January 17, 2023

О чем молчат докер-контейнеры, или 4 способа узнать entrypoint

Часто бывает, что документация по запуску того или иного контейнера либо отсутствует, либо ее качество оставляет желать лучшего. На своей практике я наблюдал множество случаев, когда docker run приводил к многозначительному молчанию консоли, после чего процесс завершался без какого-либо видимого эффекта:

«Молчаливый» Alpine

Давайте рассмотрим несколько  техник, которые помогут вам разобраться с запуском любого контейнера.

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 завершается сразу после старта.

Подпишись на телеграм «чевопса»

https://t.me/chevops

Девопс глазами программиста 👨‍💻

Практические примеры работы с Docker 🐳, Kubernetes ☸️ и облаками ☁️

Доступно, по делу, с юмором 🤡