Перейти к основному содержимому

Состояния контейнера Docker

· 7 мин. чтения

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.