В этом руководстве рассмотрим способы обеспечения непрерывной работы контейнеров Docker.
По умолчанию контейнеры работают только до тех пор, пока выполняется их команда по умолчанию, но общий вариант использования – запускать их на неопределенный срок для целей отладки и устранения неполадок.
Основы запуска Docker
Рассмотрим некоторые основы команды запуска docker и способы передачи команд контейнеру при его запуске.
Указание команды для запуска
При создании Dockerfile есть два способа указать команду для запуска.
- Директива ENTRYPOINT указывает команду для контейнера. Это полезно для команд, которые всегда хотим запускать, если пользователь явно не переопределяет их).
- Можно указать команды с помощью директивы CMD. Она используется для определения команды или аргументов по умолчанию, которые будут переданы в контейнер. Любые аргументы, которые пользователь включает после имени образа, заменяют всю директиву CMD.
Переопределение команд по умолчанию
Чтобы переопределить директиву CMD, можно добавить еще одну команду после docker run [image_name]. Например:
docker run ubuntu echo "Hello World"
Чтобы переопределить директиву ENTRYPOINT, необходимо добавить флаг –entrypoint и нужную команду перед именем образа и любыми аргументами после имени образа.
docker run --entrypoint echo ubuntu "Hello World"
Оба примера будут запускать команду echo “Hello World” при запуске контейнера.
Запуск Docker с помощью команды
Поведение по умолчанию команды запуска Docker можно обобщить следующим образом:
- контейнер по умолчанию работает на переднем плане, если только он не был явно отключен с помощью флага -d;
- контейнер работает до тех пор, пока выполняется указанная команда, а затем останавливается.
Посмотрим на небольшой пример:
docker run ubuntu bash
Приведенная выше команда запустит команду bash в образе Ubuntu. Команда bash запустит оболочку в контейнере.
Команда выполняется, но контейнер останавливается после завершения команды, то есть почти сразу. Можно проверить это с помощью команды docker ps:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c8f8f8f8f8f8 ubuntu bash 2 minutes ago Exited (0) 22/tcp mystifying_snyder
Запуск контейнеров Docker на неопределенный срок
По умолчанию контейнер может быть рассчитан или не рассчитан на неограниченный срок службы. Например, контейнер, содержащий веб-сервер, работает до тех пор, пока работает веб-сервер. Однако контейнер, содержащий одноразовое задание, такое как задание cron, выполняется только в течение короткого периода времени.
Рассмотрим некоторые способы запуска контейнеров на неограниченный срок.
Бесконечные команды
Самый простой способ сохранить контейнер в рабочем состоянии – передать команду, которая никогда не заканчивается.
Вот несколько примеров:
Можем использовать команду tail -f для чтения файла /dev/null. Команда продолжает искать новые изменения в файле для отображения. Таким образом, это никогда не заканчивается, пока файл существует. Посмотрим на команду:
docker run ubuntu tail -f /dev/null
Можно использовать приведенную ниже команду для запуска бесконечного цикла, который ничего не делает:
docker run ubuntu while true; do sleep 1; done
Следующая команда удерживает контейнер в режиме ожидания и ничего не делает:
docker run ubuntu sleep infinity
Можно использовать бесконечные команды любым из следующих способов:
- ENTRYPOINT или CMD в Dockerfil;
- переопределение ENTRYPOINT или CMD в команде docker run.
Более того, не имеет смысла запускать бесконечную команду на переднем плане и получать зависший терминал. В этом случае можно использовать флаг -d для запуска контейнера в фоновом режиме.
Запуск псевдо-TTY
Бесконечные команды были хаком давным-давно, когда не было других вариантов. Однако в последних версиях Docker можно поддерживать работу контейнеров, запуская с ними сеанс терминала как на переднем плане, так и в фоновом режиме.
Псевдо-TTY используются для запуска команд внутри контейнера. Чтобы начать сеанс псевдо-TTY с контейнером, можно использовать флаг -t. Контейнер не выйдет, пока сеанс не завершится.
Если хотим взаимодействовать с контейнером, можно соединить это с флагом -i. Это позволит запускать команды в контейнере с помощью терминала. Вот пример команды:
docker run -it ubuntu bash
В качестве альтернативы, если наша цель – запустить контейнер на неопределенный срок, можно использовать флаг -d:
docker run -d -t ubuntu
Заключение
В этом руководстве рассмотрели несколько способов бесконечного запуска контейнеров Docker. Мы посмотрели, как команды передаются в контейнер, а затем изменили эти команды, чтобы решить проблему. Мы также изучили современное решение, использующее сеансы псевдо-TTY для поддержания работы контейнеров.