Docker предоставляет параметр политики перезапуска, позволяющий автоматически перезапускать контейнеры в случае определенных событий или сбоев.
Это чрезвычайно полезно в сценариях, когда вам необходимо перезапустить хост Docker (ваш сервер Linux) или если служба, работающая в контейнере, не работает.
Политики перезапуска Docker применяются для каждого контейнера. Есть два способа назначить контейнеру политику перезапуска. Вы можете установить его в файле YAML, если собираетесь использовать Docker Compose, Swarm или Kubernetes.
Вы также можете установить политику перезапуска прямо в командной строке при запуске контейнера:
docker container run --restart <policy>
Давайте поговорим о том, какую политику перезапуска вы можете использовать.
Существуют следующие политики перезапуска контейнеров Docker:
Как мы уже упоминали, если вы явно не добавите политику перезапуска, она будет иметь значение «no», что означает, что контейнеры не будут перезапущены автоматически.
Позвольте нам показать эти политики в действии, чтобы вы могли их реально визуализировать. Это особенно полезно для понимания разницы между политикой always и unless-stopped.
Начнем с политики перезапуска always. Если эта политика установлена, контейнер всегда будет перезапускаться, если он не был остановлен явно.
Мы собираемся запустить контейнер Alpine Linux с политикой перезапуска always. Мы называем это всегда политикой.
У контейнера одна задача. Он запускает команду sleep в bash в течение 10 секунд, а затем завершает работу.
docker container run --name always-policy --restart always alpine sleep 10
Без политики перезапуска always контейнер остановился бы через 10 секунд. Но здесь он автоматически перезапустится и запустит команду сна еще 10 секунд, и так будет продолжаться.
destroyer@andreyex:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1171dcfb7e06 alpine "sleep 10" 25 seconds ago Up 4 seconds always-policy
В приведенной выше команде вы можете видеть, что, хотя контейнер был создан 25 секунд назад, он работал всего 4 секунды. Учтите, что тот же контейнер перезапускается, новый не создается.
Вы можете использовать команду docker inspect, чтобы узнать, сколько раз контейнер был перезапущен на данный момент.
destroyer@andreyex:~$ docker inspect always-policy | grep -i restartcount "RestartCount": 4,
Если вы остановите контейнер с помощью команды остановки, он не перезапустится автоматически после этого. В приведенном ниже примере вы можете увидеть, что контейнер теперь имеет статус «Exited», а не «Up».
destroyer@andreyex:~$ docker stop always-policy always-policy destroyer@andreyex:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1171dcfb7e06 alpine "sleep 10" 58 seconds ago Exited (0) 6 seconds ago always-policy
Мы использовали вариант -it запуска контейнера с интерактивным терминалом на скриншоте выше. Это было по привычке и здесь не нужно.
unless-stopped похоже на политику перезагрузки always. Оба перезапускают контейнеры автоматически, и если вы остановите контейнеры явно, они не перезапустятся.
Но основное различие между ними заключается в том, что если вы остановите контейнеры с помощью команды docker stop, а затем перезапустите демон docker, контейнер с политикой перезапуска always запустит контейнер автоматически, но контейнер с политикой unless-stopped не будет перезапущен.
Покажу это на примерах. У меня уже есть остановленный контейнер с политикой постоянного перезапуска. Позвольте мне создать новый контейнер с именем except-stop-policy с политикой unless-stopped.
docker container run --name unless-stopped-policy --restart always alpine sleep 10
Остановите контейнер:
docker stop unless-stopped-policy
Теперь у нас есть два контейнера, которые явно остановлены:
destroyer@andreyex:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d244b6e08899 alpine "sleep 10" 2 minutes ago Exited (0) About a minute ago unless-stopped-policy 1171dcfb7e06 alpine "sleep 10" 22 minutes ago Exited (0) 21 minutes ago always-policy
Перезапустите демон Docker:
sudo systemctl restart docker
Теперь, если вы проверите запущенные контейнеры, вы увидите, что контейнер с именем always-policy работает, потому что он был установлен с политикой перезапуска always.
destroyer@andreyex:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1171dcfb7e06 alpine "sleep 10" 30 minutes ago Up 8 seconds always-policy
Политика перезапуска on-failure перезапускает контейнер, если он был завершен с ненулевым кодом выхода (указывающим на ошибку/сбой). Он также перезапускает контейнеры, если перезапускается демон docker, включая те, которые ранее находились в остановленном состоянии.
Если вы вручную остановите контейнер с помощью команды docker stop, он будет существовать с нулевым кодом, указывающим, что все было нормально.
К настоящему времени у вас есть довольно хорошее представление о запуске контейнера с политикой перезапуска.
Если вы используете что-то вроде Docker Compose для развертывания контейнеров, вы можете упомянуть политику перезапуска для объекта службы в файле YAML.
Вот пример:
version: "3.3" services: NginxProxy: image: "jwilder/nginx-proxy:latest" restart: "on-failure" networks: ["net"] ports: - "80:80" - "443:443"
Честно говоря, однозначного ответа на этот вопрос нет. Это зависит от вашего варианта использования и того, что вы хотите.
Надеюсь, эта статья была полезна для понимания политики перезапуска Docker. Если у вас есть какие-либо вопросы или предложения, дайте мне знать в разделе комментариев.