1. Обзор
Контейнер Docker — это экземпляр образа Docker, внутри которого выполняется некоторый процесс. Изменение состояния этого процесса также влияет на поведение контейнера. Таким образом, контейнер может находиться в разных состояниях на протяжении всего жизненного цикла.
В этом руководстве мы узнаем обо всех возможных состояниях контейнера Docker.
Давайте сначала рассмотрим, как найти состояние контейнера Docker, а затем пройдемся по различным этапам контейнера.
2. Найдите текущее состояние контейнера Docker
Прежде чем мы углубимся в различные состояния контейнера Docker, давайте сначала рассмотрим, как найти состояние любого контейнера Docker.
По умолчанию команда docker ps
отображает текущее состояние всех контейнеров Docker:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8f0b524f2d32 centos:7 "/bin/bash" 46 seconds ago Created strange_beaver
e6d798254d45 centos:7 "/bin/bash" About a minute ago Exited (0) About a minute ago wizardly_cohen
Вывод отображает все контейнеры, присутствующие на машине, с их СТАТУСОМ
(пятый столбец) и кучей других деталей.
Мы также можем использовать команду docker inspect
для получения статуса отдельного контейнера:
$ docker inspect -f '{{.State.Status}}' mycontainer
running
Здесь mycontainer
— это имя контейнера, для которого мы хотим найти текущее состояние. Мы также можем заменить его идентификатором контейнера Docker.
3. Возможные состояния контейнера Docker
В каждом конкретном случае контейнер Docker может находиться в 6 возможных состояниях. Давайте теперь углубимся в каждое из этих состояний:
3.1. Созданный
Docker присваивает состояние created
контейнерам, которые ни разу не запускались с момента их создания. Следовательно, в этом состоянии контейнеры не используют ЦП или память.
Контейнеры Docker, созданные с помощью команды docker create
, показывают статус создания:
$ docker create --name mycontainer httpd
dd109e4be16219f1a6b9fc1cbfb050c1ae035d6a2c301ea0e93eb7d5252b8d2e
$ docker inspect -f '{{.State.Status}}' mycontainer
created
Здесь мы создали контейнер Docker, mycontainer
, используя официальный образ Docker httpd
. Поскольку мы использовали команду docker create
для запуска контейнера, статус отображается как созданный.
Такие контейнеры полезны, когда нам нужно быть готовыми к каким-то большим задачам. В таких ситуациях мы создаем контейнер таким образом, чтобы он был готов к работе, когда мы его запускаем.
3.2. Бег
Когда мы запускаем контейнер, создав
состояние с помощью команды запуска docker
, он переходит в рабочее
состояние.
Это состояние означает, что процессы выполняются в изолированной среде внутри контейнера.
$ docker create --name mycontainer httpd
8d60cb560afc1397d6732672b2b4af16a08bf6289a5a0b6b5125c5635e8ee749
$ docker inspect -f '{{.State.Status}}' mycontainer
created
$ docker start mycontainer
mycontainer
$ docker inspect -f '{{.State.Status}}' mycontainer
running
В приведенном выше примере мы сначала создали контейнер Docker, используя официальный образ httpd Docker.
Затем был создан статус контейнера .
Когда мы запускаем mycontainer,
начинает работать серверный процесс httpd и все остальные соответствующие процессы .
Следовательно, статус того же контейнера теперь изменился на « Работает».
Контейнер, запущенный с помощью команды запуска docker,
также получил тот же статус:
$ docker run -itd --name mycontainer httpd
685efd4c1c4a658fd8a0d6ca66ee3cf88ab75a127b9b439026e91211d09712c7
$ docker inspect -f '{{.State.Status}}' mycontainer
running
В этом состоянии нет никаких компромиссов в потреблении ЦП и памяти контейнером.
3.3. Перезапуск
Проще говоря, это состояние означает, что контейнер находится в процессе перезапуска.
Docker поддерживает четыре типа политик перезапуска , а именно — нет
, при сбое
, всегда
, если не остановлен.
Политика перезапуска определяет поведение контейнера при его выходе.
По умолчанию для политики перезапуска установлено значение « нет»,
что означает, что контейнер не будет запускаться автоматически после выхода.
Давайте обновим политику перезапуска, чтобы всегда
и проверить состояние контейнера Docker, используя приведенный ниже пример:
$ docker run -itd --restart=always --name mycontainer centos:7 sleep 5
f7d0e8becdac1ebf7aae25be2d02409f0f211fcc191aea000041d158f89be6f6
Приведенная выше команда запустит mycontainer,
выполнит команду sleep 5
и выйдет. Но поскольку мы обновили политику перезапуска для этого контейнера, он будет автоматически перезапускать контейнер после его выхода.
Через 5 секунд состояние контейнера будет перезапущено
:
$ docker inspect -f '{{.State.Status}}' mycontainer
restarting
3.4. Вышел
Это состояние достигается, когда процесс внутри контейнера завершается. В этом состоянии контейнер не использует ЦП и память.
Причин выхода работающего контейнера может быть несколько. Давайте рассмотрим некоторые из них:
- Процесс внутри контейнера был завершен, поэтому он завершился.
- Процесс внутри контейнера обнаружил исключение во время работы.
- Контейнер намеренно останавливается с помощью команды
docker stop
. - Ни один интерактивный терминал не был настроен на контейнер с запущенным bash.
$ docker run -itd --name mycontainer centos:7 sleep 10
596a10ddb635b83ad6bb9daffb12c1e2f230280fe26be18559c53c1dca6c755f
Здесь мы запустили контейнер Centos, mycontainer,
и передали команду sleep 10.
Это приведет к выходу из контейнера через 10 секунд сна. Мы можем проверить то же самое, выполнив следующую команду через 10 секунд:
$ docker inspect -f '{{.State.Status}}' mycontainer
exited
Доступ к контейнеру в состоянии выхода с помощью команды
docker exec
невозможен . Однако мы можем запустить контейнер с помощью запуска
докера или перезапуска докера
, а затем получить к нему доступ.
$ docker start mycontainer
3.5. Приостановлено
Приостановлено
— это состояние контейнера Docker, при котором все процессы приостанавливаются на неопределенное время.
Контейнер Docker можно приостановить с помощью команды docker pause
.
$ docker run -itd --name mycontainer centos:7 sleep 1000
1a44702cea17eec42195b057588cf72825174db311a35374e250d3d1da9d70c5
В приведенном выше примере мы запустили контейнер Docker, используя образ Centos Docker, и выполнили команду sleep 1000
. Это приведет к выходу из контейнера через 1000 секунд сна.
Теперь давайте приостановим этот контейнер через несколько секунд, скажем, 100 секунд:
$ docker pause mycontainer
mycontainer
$ docker inspect -f '{{.State.Status}}' mycontainer
paused
Приостановленный контейнер потребляет ту
же память, что и во время работы контейнера, но полностью освобождает ЦП. Давайте проверим это с помощью команды docker stat
:
$ docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
1a44702cea17 mycontainer 0.00% 1.09MiB / 7.281GiB 0.01% 1.37kB / 0B 0B / 0B 1
Обратите внимание, что ЦП равен 0%, но использование памяти не равно нулю.
Мы можем использовать команду docker unpause
, чтобы возобновить работу контейнера:
$ docker unpause mycontainer
mycontainer
При снятии с паузы контейнера он возобновится с той же точки, где мы его приостановили. В нашем примере выше мы приостановили контейнер после 100 секунд сна. Поэтому, когда мы снимем паузу с контейнера, он возобновит сон со 100. Таким образом, контейнер остановится через 900 секунд спящего режима с этого момента. (общий сон был установлен на 1000).
Теперь вопрос в том, когда приостановить работу контейнера Docker? Рассмотрим ситуацию, когда контейнер Docker выполняет какую-то задачу с интенсивным использованием ЦП. В то же время мы хотим запустить другой контейнер с интенсивным использованием ЦП с высоким приоритетом. Конечно, мы можем запустить оба контейнера одновременно, но это замедлит выполнение из-за нехватки ресурсов.
В таких случаях мы можем приостановить на некоторое время один из контейнеров с низким приоритетом и позволить другому контейнеру использовать весь ЦП. Как только это будет сделано, мы можем возобновить выполнение первого контейнера.
3.6. Мертвый
Мертвое состояние контейнера Docker означает, что контейнер не работает .
Это состояние достигается, когда мы пытаемся удалить контейнер, но он не может быть удален, потому что некоторые ресурсы все еще используются внешним процессом. Таким образом, контейнер переходит в мертвое
состояние.
Контейнеры в мертвом
состоянии не могут быть перезапущены. Их можно только удалить.
Поскольку контейнер в мертвом
состоянии частично удаляется, то он не потребляет ни памяти, ни ЦП.
4. Вывод
В этом руководстве мы прошли различные этапы контейнера Docker.
Во-первых, мы рассмотрели несколько способов узнать состояние контейнера Docker. Позже мы узнали о важности каждого состояния и о том, как достичь этих состояний с помощью различных команд Docker.