Политики перезапуска контейнеров Docker

Быстрые ссылки
- Доступные политики
- Применение политики перезапуска
- Циклы перезапуска
- Ограничение числа попыток
- Расследование причин остановки контейнеров
- Дополнительно: чек-листы и runbook
- Резюме
Зачем нужны политики перезапуска
Docker по умолчанию не перезапускает контейнеры после их завершения. Политики перезапуска позволяют взять под контроль жизненный цикл отдельного контейнера: автоматически восстанавливать сервисы после сбоев или запускать контейнеры при загрузке хоста. Это важно для фоновых сервисов, сервисов с высокой доступностью и для автоматизации операций после перезагрузки системы.
Ключевая идея: политика перезапуска применяется, когда контейнер останавливается, и при старте демона Docker. Политики помогают восстановить сервис без ручного вмешательства, но требуют продуманного выбора для корректной работы и отладки.
Доступные политики
Существует четыре основных политики перезапуска:
no— контейнер никогда автоматически не стартует. Политика по умолчанию для контейнера, созданного черезdocker run.always— Docker гарантирует, что контейнер всегда будет запущен. Если контейнер остановлен, он будет немедленно перезапущен. Вы всё ещё можете вручную остановить контейнер с помощьюdocker stop, но Docker вновь поднимет его при следующем перезапуске демона.on-failure— контейнер будет перезапущен только если остановка произошла из-за ошибки (код выхода ≠ 0). Docker не поднимет контейнер при рестарте демона, если он остановлен нормально.unless-stopped— аналогичноalways, но Docker не будет автоматически перезапускать контейнер, если вы остановили его вручную.
Когда использовать какие политики:
always— подходит для сервисов, которые должны быть постоянно доступны, но учитывайте поведение при рестарте демона.unless-stopped— если хотите, чтобыdocker stopоставлял контейнер в окончательно остановленном состоянии до ручного запуска.on-failure— для задач, где повторные автоматические попытки полезны, но нужно ограничить бесконечные перезапуски.no— локальная разработка, одноразовые утилиты или задачи, которые должны завершаться и не рестартоваться.
Docker интерпретирует коды выхода в Unix-стиле: 0 — успех, любое значение 1 или выше — ошибка.
Важно: перезапуск фактически выполняет новое docker run, то есть выполняется ENTRYPOINT и возможные скрипты инициализации. Скрипты инициализации должны быть идемпотентны и устойчивы к многократным вызовам.
Применение политики перезапуска
Для указания политики при запуске контейнера используйте флаг --restart:
docker run --name httpd --restart always httpd:latestВ Docker Compose добавьте поле restart в docker-compose.yml:
services:
httpd:
image: httpd:latest
restart: alwaysИзменить политику у существующего контейнера можно через docker update. Сначала найдите имя контейнера docker ps -a, затем выполните:
docker update --restart-policy unless-stopped httpddocker update можно вызвать для запущенных и остановленных контейнеров.
Защита от циклов перезапуска
Docker применяет несколько механизмов защиты от бесконечных циклов перезапуска:
- Минимальное время работы перед началом учёта рестартов — контейнер должен проработать хотя бы 10 секунд. Это предотвращает быстрые циклы рестарта при ошибочном старте.
- Команда
docker stopвсегда уважается: Docker не будет немедленно перезапускать контейнер послеdocker stop. Если нужно инициировать перезапуск принудительно, используйтеdocker restart.
Эти механизмы помогают отличить ожидаемые остановки и ручное вмешательство от автоматических сбоев.
Ограничение числа попыток перезапуска
Политика on-failure позволяет указать максимальное число попыток рестарта:
docker run httpd:latest --restart on-failure:5В этом примере Docker попытается перезапустить контейнер не более 5 раз при аварийном завершении (код выхода ≠ 0). Если пятая попытка также завершится с ошибкой, Docker перестанет пробовать. Это удобно для сценариев, где постоянный автоматический перезапуск малополезен и требует вмешательства оператора.
Совет: комбинируйте on-failure с системой мониторинга и алертами — при достижении лимита должна срабатывать нотификация для инженера.
Как выяснить, почему контейнер остановился
- Просмотрите список всех контейнеров:
docker ps -aВ колонке “Status” для остановленных контейнеров указывается код выхода в скобках. Код больше 0 означает ошибку.
- Получите логи контейнера:
docker logs my-containerЛоги собирают stdout и stderr процесса внутри контейнера. Часто последние строки лога содержат причину падения.
- Если нужен интерактивный доступ, запустите контейнер аналогично рабочему образу и выполните отладку:
docker run -it --entrypoint /bin/sh image:tagили используйте docker cp для извлечения файлов конфигурации и анализа.
- Обратите внимание на поведение
ENTRYPOINTи скриптов инициализации — они должны корректно обрабатывать повторные запуска и проверять предварительные условия (например, доступ к базе данных, переменные окружения, монтируемые тома).
Для интерпретации кодов выхода обратитесь к документации приложения, запущенного в контейнере. Многие приложения документируют значения кодов завершения.
Дополнительные материалы для эксплуатации и принятия решений
Быстрая методология выбора политики
- Определите тип сервиса: кратковременная задача, долгоживущий сервис, или системный демонизированный процесс.
- Для долгоживущих сервисов выберите
alwaysилиunless-stopped. - Если важно не продолжать попытки при постоянной ошибке —
on-failure:N. - Для разработки и одноразовых задач —
no.
Модель зрелости (пример)
- Уровень 0 — локальная разработка:
no. - Уровень 1 — тестовые стенды:
on-failure:3+ мониторинг. - Уровень 2 — продакшн сервисы:
unless-stoppedилиalways+ healthchecks + SLO. - Уровень 3 — критичные сервисы:
unless-stopped+ кластерная оркестрация (Kubernetes) + автоматическое масштабирование.
Когда политики могут не сработать (примеры)
- Сбой гипервизора или проблемы с файловой системой хоста: Docker может не восстановить контейнеры до решения проблемы на хосте.
- Идемпотентность инициализации нарушена — скрипт ENTRYPOINT ломает окружение при повторных запусках.
- Приложение уходит в циклическое падение быстрее 10 секунд: Docker начнёт защиту и может отложить мониторинг.
Таблица сравнения политик
| Политика | Перезапуск при ошибке | Перезапуск после рестарта демона | Ручной stop останавливает навсегда |
|---|---|---|---|
| no | нет | нет | да |
| always | да | да | нет (будет поднят при рестарте демона) |
| on-failure[:N] | да (при коде ≠0) | нет | да |
| unless-stopped | да | да (если не был остановлен вручную) | да (оставит остановленным) |
Ролевые чек-листы
Developer:
- Локально тестировать поведение ENTRYPOINT при повторных запусках.
- Покрыть сценарии инициализации тестами.
- Документировать значения кодов выхода приложения.
SRE / Ops:
- Выбрать политику в соответствии с SLA.
- Настроить мониторинг и алерты на частые рестарты и достижение лимитов
on-failure. - Проверить, что тома и сетевые зависимости корректно монтируются при перезапусках.
QA:
- Проверить, что контейнер корректно восстанавливается после имитации сбоев.
- Тестировать сценарии
docker stop,docker restart, рестарт демона.
Пример runbook при повторяющихся рестартах
- Получить список проблемных контейнеров:
docker ps -a --filter "status=exited"- Посмотреть последний код выхода и логи:
docker inspect --format='{{.State.ExitCode}}' my-container
docker logs --tail 200 my-container- Если ошибка очевидна — применить исправление (конфиг, секреты, зависимости). Если нет — запустить интерактивную отладку:
docker run --rm -it --entrypoint /bin/sh image:tagПри повторении ошибки более N раз и использовании
on-failure:N— оповестить on-call и поднять инцидент.После исправления назначить тестовый запуск и мониторить.
Диаграмма решения (Mermaid)
flowchart TD
A[Контейнер остановлен] --> B{Код выхода = 0?}
B -- Да --> C[Не считать ошибкой]
B -- Нет --> D{Политика}
D -->|no| E[Остановлен: не перезапускать]
D -->|on-failure| F[Перезапускить до N раз]
D -->|always| G[Немедленный перезапуск]
D -->|unless-stopped| H[Перезапустить, кроме ручной остановки]
F --> I{Достигается лимит?}
I -- Да --> J[Оставить остановленным и оповестить]
I -- Нет --> GКритерии приёмки
- Контейнеры, критичные для сервиса, автоматически возвращаются в рабочее состояние после одиночных сбоев.
- Скрипты инициализации работают идемпотентно при многократных запусках.
- Набор алертов оповещает инженера при достижении лимитов
on-failureи при частых рестартах. - Документация содержит выбранную политику и причины выбора для каждого сервиса.
Краткий словарь (одной строкой)
- Политика перезапуска — правило, задающее, будет ли Docker автоматически стартовать контейнер после его остановки или рестарта демона.
Расследование — примеры команд и тест-кейсы
- Проверка статуса контейнера:
docker ps -a --filter "name=my-app"- Инспекция состояния контейнера:
docker inspect --format '{{json .State}}' my-app | jq- Просмотр последних 500 строк логов:
docker logs --tail 500 my-appТест-кейсы:
- Остановить контейнер
docker stopи проверить, останется ли он остановленным при политикеunless-stopped. - Принудительно завершить процесс внутри контейнера и убедиться в поведении политики
on-failure. - Перезапустить демон Docker и проверить, какие контейнеры были подняты автоматически.
Примеры типичных ошибок и рекомендации по их устранению
- Симптом: контейнер падает с кодом 137 (OOM). Рекомендация: проверить ограничения памяти и корректно настроить лимиты ресурсов (
--memory,--memory-swap). - Симптом: контейнер быстро стартует и сразу падает (менее 10 сек). Рекомендация: добавить паузу в инициализации, логирование на старте и healthcheck, чтобы отличать временные ошибки от системных.
- Симптом: контейнер не стартует после рестарта демона, хотя раньше запускался. Рекомендация: проверить монтирования томов, сетевые зависимости и порядок запуска сервисов.
Резюме
Политики перезапуска — простой и мощный инструмент для повышения устойчивости контейнеризированных приложений. Для продакшна чаще всего используются always или unless-stopped, а on-failure ценен в ситуациях, когда нужны ограниченные автоматические попытки. Настраивайте мониторинг, тестируйте инициализацию на идемпотентность и документируйте выбранную политику для каждого сервиса.
Важно: политика перезапуска не заменяет корректную архитектуру отказоустойчивости и систему оркестрации для критичных сервисов.
Полезные действия: проверить entrypoint на идемпотентность, настроить алерты при достижении лимитов on-failure, и прогнать сценарии остановки и рестарта в тестовой среде.