1. Обзор
В этом руководстве мы рассмотрим способы обеспечения непрерывной работы контейнеров Docker.
По умолчанию контейнеры работают только до тех пор, пока выполняется их команда по умолчанию, но общий вариант использования — запускать их на неопределенный срок для целей отладки и устранения неполадок.
2. Основы запуска Docker
Давайте рассмотрим некоторые основы команды запуска docker
и способы передачи команд контейнеру при его запуске.
2.1. Указание команды для запуска
При создании Dockerfile есть два способа указать команду для запуска.
- Директива
ENTRYPOINT
указывает команду для контейнера . Это полезно для команд, которые мы всегда хотим запускать, если пользователь явно не переопределяет их. - Мы также можем указать команды с помощью директивы
CMD
. Это используется для определения команды или аргументов по умолчанию, которые будут переданы в контейнер. Любые аргументы, которые пользователь включает после имени изображения, заменяют всю директивуCMD .
2.2. Переопределение команд по умолчанию
Чтобы переопределить директиву CMD, мы можем просто добавить еще одну команду после запуска docker [image_name]
. Например:
docker run ubuntu echo "Hello World"
Чтобы переопределить директиву ENTRYPOINT, нам нужно добавить флаг –entrypoint
и нужную команду перед именем изображения и любыми аргументами после имени изображения. Например:
docker run --entrypoint echo ubuntu "Hello World"
Оба примера будут запускать команду echo «Hello World»
при запуске контейнера.
2.3. 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
3. Запуск контейнеров Docker на неопределенный срок
По умолчанию контейнер может быть рассчитан или не рассчитан на неограниченный срок службы. Например, контейнер, содержащий веб-сервер, работает до тех пор, пока работает веб-сервер. Однако контейнер, содержащий одноразовое задание, такое как задание cron, выполняется только в течение короткого периода времени.
Давайте рассмотрим некоторые способы бесконечного запуска контейнеров.
3.1. Бесконечные команды
Самый простой способ поддерживать контейнер в рабочем состоянии — передать команду, которая никогда не заканчивается.
Вот несколько примеров:
Мы можем использовать команду 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 в Dockerfile.
- Переопределение ENTRYPOINT или CMD в команде запуска докера.
Более того, не имеет смысла запускать бесконечную команду на переднем плане и получать зависший терминал. В этом случае мы можем использовать флаг -d
для запуска контейнера в фоновом режиме .
3.2. Запуск псевдо-TTY
Бесконечные команды были хаком давным-давно, когда не было других вариантов. Однако в последних версиях Docker можно поддерживать работу контейнеров, запустив с ними сеанс терминала как на переднем плане, так и в фоновом режиме.
Псевдо-TTY используются для запуска команд внутри контейнера. Чтобы начать сеанс псевдо-TTY с контейнером, мы можем использовать флаг -t .
Контейнер не выйдет, пока сеанс не завершится.
Если мы хотим взаимодействовать с контейнером, мы можем соединить это с флагом -i .
Это позволит нам запускать команды в контейнере с помощью нашего терминала. Вот пример команды:
docker run -it ubuntu bash
В качестве альтернативы, если наша цель — просто запустить контейнер на неопределенный срок, мы можем использовать флаг -d :
docker run -d -t ubuntu
4. Вывод
В этом руководстве мы рассмотрели несколько способов бесконечного запуска контейнеров Docker. Мы посмотрели, как команды передаются в контейнер, а затем изменили эти команды, чтобы решить нашу проблему. Мы также изучили современное решение, использующее сеансы псевдо-TTY для поддержания работы контейнеров.