О чем молчат докер-контейнеры, или 4 способа узнать entrypoint
Часто бывает, что документация по запуску того или иного контейнера либо отсутствует, либо ее качество оставляет желать лучшего. На своей практике я наблюдал множество случаев, когда docker run приводил к многозначительному молчанию консоли, после чего процесс завершался без какого-либо видимого эффекта:
Давайте рассмотрим несколько техник, которые помогут вам разобраться с запуском любого контейнера.
1. Найдите Dockerfile
Dockerfile представляет собой набор инструкций для сборки образа и последующего запуска контейнера. Лучшим рецептом исследования проблемы «молчаливого» старта является изучение непосредственно самого docker-файла. При запуске контейнера выполняется команда, указанная в инструкции ENTRYPOINT:
Dockerfile в исходном виде не является частью собранного образа, поэтому проще всего отыскать оригинал. Если автор образа — не вы, то попробуйте найти репозиторий исходного кода, откуда образ был собран. Как правило, помогает гугление запросов из разряда «some-image docker github». Используйте поиск по гитхаб-репозиторию, чтобы найти искомый Dockerfile.
Если в docker-файле отсутствует инструкция ENTRYPOINT, найдите самую последнюю инструкцию FROM, и далее изучите родительский образ аналогичным способом.
Если вам не удалось найти ENTRYPOINT, или у вас нет уверенности, что найденный Dockerfile соответствует искомому контейнеру, переходите к следующим техникам.
2. Зачитайте Entrypoint из конфигурации образа
$ docker inspect some-image -f "{{.Config.Entrypoint}}"
Эта команда дешево и сердито выведет искомый ENTRYPOINT. Зачем же тогда искать Docker-файл, если есть такая простая и понятная команда? Дело в том, что Dockerfile является наиболее полным представлением о содержимом образа, в то время как docker inspect просто выдает параметры конфигурации, одним из которых, в том числе, является ENTRYPOINT:
$ docker inspect nginx -f "{{.Config.Entrypoint}}" [/docker-entrypoint.sh]
Образ Nginx выполняет команду /docker-entrypoint.sh при запуске контейнера.
3. Скопируйте Entrypoint-скрипт из контейнера на вашу машину
$ docker run \ -v /path/on/host:/mount-dir \ --entypoint cp \ some-image /path/in/container /mount-dir
Скопирует /path/in/container из образа some-image на хост в директорию /path/on/host (на Windows вместо обратного слеша «\» использовать «^» — здесь и далее).
$ docker run \ -v $PWD:/mount --entypoint cp \ nginx /docker-entrypoint.sh /mount
Теперь в вашей рабочей директории есть файл /docker-entrypoint.sh из образа Nginx (на Windows вместо $PWD использовать %cmd%)
Кстати, я использую эту команду для копирования любого файла из образа. Разберем подробнее, как она работает:
-v /path/on/host:/mount-dir
замаунтить директорию хоста /path/on/host в контейнер на путь /mount-dir--entypoint cp
при старте контейра использовать команду cp (сокращение от copy, то есть скопировать)/path/in/container /mount-dir
параметры запуска контейнера, в данном случае - параметры команды cp - скопировать откуда и скопировать куда
Как итог, файл /path/in/container копируется в директорию /path/on/host.
Работает гораздо быстрее чем docker save и не требует запущенного контейнера, как docker copy.
4. Запустите контейнер в режиме линукс-терминала
$ docker run -it --entrypoint=sh some-image
В большинство docker-образов предуставновлен Bourne shell (/bin/sh), что позволяет вам использовать его в качестве терминала (не забудьте флаги -it, которые инициируют интерактивную консоль контейнера):
Запускаем контейнер nginx, используя sh в качестве entrypoint:
$ docker run -it --entrypoint=sh nginx
Изучаем оригинальный entrypoint, выявленный предыдущими методами:
$ less /docker-entrypoint.sh
Используем другие возможности линукса, находясь внутри контейнера:
$ bash $ ls -la /etc/nginx/conf.d
Домашнее задание
Объясните, почему $ docker run alpine
завершается сразу после старта.
Подпишись на телеграм «чевопса»
Девопс глазами программиста 👨💻
Практические примеры работы с Docker 🐳, Kubernetes ☸️ и облаками ☁️