Отказоустойчивость в Docker: стратегии рестарта и оркестрация с Docker Swarm | AdminWiki

Отказоустойчивость в Docker: стратегии рестарта и оркестрация с Docker Swarm

21 августа 2026 9 мин. чтения

Введение: зачем нужна отказоустойчивость Docker

Контейнер падает, узел перезагружается, приложение теряет доступность. Это рабочие сценарии, а не исключения. Docker предлагает два уровня защиты: локальные политики перезапуска (restart policy) для одного хоста и встроенную оркестрацию Docker Swarm для кластеров из нескольких узлов. Первый вариант решает проблему упавшего процесса, второй — проблему упавшего сервера.

В этой статье разберем все политики перезапуска с командами и YAML-конфигурациями, затем пошагово соберем отказоустойчивый кластер Swarm с репликами, балансировкой нагрузки и автоматическим восстановлением после сбоев. Материал рассчитан на DevOps-инженеров и системных администраторов, которым нужно быстро поднять высокую доступность без внедрения Kubernetes.

Короткий выбор: restart policy Docker или Docker Swarm

Короткий вывод. Если контейнер падает, но хост доступен, начните с restart policy Docker. Если узел недоступен и нужен failover без Kubernetes, используйте Docker Swarm с несколькими узлами и репликами.

СценарийЧто использоватьЧто произойдет при сбоеОграничение
Один хостrestart policyКонтейнер перезапустится после сбоя процесса.Отказ хоста или Docker Engine остановит сервис до восстановления.
КластерDocker Swarm: service с replicasЗадачи можно перенести на доступные узлы; routing mesh принимает трафик.Нужны несколько узлов, кворум manager и отдельная стратегия для stateful-данных.

Если нужен более широкий обзор оркестрации контейнеров, используйте практический гайд по Docker Swarm 2026. Там разобраны overlay-сети, секреты и rolling updates с нуля.

restart policy Docker: локальная отказоустойчивость

Restart policy определяет, что Docker делает с контейнером после завершения его основного процесса. Политика задается на уровне контейнера и работает только на том хосте, где контейнер запущен. Это первая линия защиты от сбоев приложения.

Обзор политик: no, on-failure, always, unless-stopped

Docker поддерживает четыре политики перезапуска. Выбор зависит от того, как должен вести себя контейнер после остановки или ошибки.

ПолитикаПоведениеКогда использовать
noКонтейнер не перезапускается автоматически. Это значение по умолчанию.Разовые задачи, отладка, контейнеры с внешним управлением жизненным циклом.
on-failure[:max-retries]Перезапуск только при завершении с ненулевым кодом ошибки. Можно ограничить количество попыток.Приложения, которые должны завершаться чисто, но иногда падают по ошибке.
alwaysПерезапуск всегда, включая случай ручной остановки. При старте Docker демон также поднимет контейнер.Критичные сервисы, которые должны работать непрерывно.
unless-stoppedПерезапуск всегда, кроме случая, когда контейнер остановлен вручную. После перезагрузки демона контейнер поднимется, если не был остановлен явно.Продакшен-сервисы, где нужен контроль над ручной остановкой.

Разница между always и unless-stopped проявляется при ручной остановке. Команда docker stop с политикой always не остановит контейнер навсегда: Docker перезапустит его при следующем старте демона. Политика unless-stopped запоминает, что контейнер остановлен вручную, и не трогает его до явного запуска.

Ошибка выбора политики имеет практическое последствие: при no упавший контейнер останется остановленным; выбор always для разовой задачи приведет к повторным запускам даже после успешного завершения. А on-failure без max-retries для приложения с постоянной ошибкой конфигурации может создать бесконечный цикл перезапусков и лишнюю нагрузку на хост.

Пример запуска с политикой on-failure и лимитом в пять попыток:

docker run -d --name app --restart=on-failure:5 nginx

Если контейнер пять раз завершится с ошибкой, Docker прекратит попытки перезапуска. Это защищает хост от бесконечного цикла падений.

Настройка restart policy Docker через Docker CLI и Docker Compose

Политика задается при запуске контейнера флагом --restart. Для уже работающего контейнера ее можно изменить без пересоздания:

docker update --restart=unless-stopped app

Команда docker update применяет новую политику мгновенно. Проверить текущую настройку можно через docker inspect:

docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' app

В Docker Compose политика указывается параметром restart в описании сервиса. Пример docker-compose.yml:

services:
  web:
    image: nginx:1.27
    restart: unless-stopped
    ports:
      - "80:80"
  worker:
    image: my-worker:latest
    restart: on-failure:3

После изменения файла примените конфигурацию командой docker compose up -d. Compose пересоздаст только те контейнеры, чьи параметры изменились.

Когда restart policy Docker недостаточно

Restart policy закрывает только сбой процесса внутри контейнера. Если падает сам хост, Docker демон не работает, и перезапускать контейнеры некому. После восстановления хоста контейнеры с политикой always или unless-stopped поднимутся автоматически, но время простоя будет равно времени восстановления сервера.

Второе ограничение — отсутствие распределения нагрузки. Restart policy не умеет запускать копии приложения на других узлах. Для multi-host сценариев нужна оркестрация: Docker Swarm или Kubernetes. Swarm встроен в Docker, настраивается за минуты и покрывает базовые требования к высокой доступности.

Docker Swarm high availability: оркестрация для отказоустойчивого кластера

Docker Swarm — встроенный режим оркестрации, который объединяет несколько Docker-хостов в единый кластер. В отличие от Kubernetes, Swarm не требует установки дополнительных компонентов: все уже есть в Docker Engine. Для высокой доступности управляющей части кластера нужно минимум три manager-узла и один или несколько worker-узлов.

Manager-узлы управляют состоянием кластера и распределяют задачи. Worker-узлы только запускают контейнеры. Для сохранения консенсуса при сбое части manager-узлов используется алгоритм Raft. Кластер продолжает работать, пока доступно большинство manager-узлов. Поэтому рекомендуется нечетное их количество: три или пять.

Инициализация кластера и добавление узлов

На первом узле выполните инициализацию:

docker swarm init --advertise-addr 10.0.0.1

IP-адрес 10.0.0.1 — адрес интерфейса, по которому узлы будут общаться между собой. После инициализации Docker выведет команду для добавления worker-узлов. Получить токен можно в любой момент:

docker swarm join-token worker

На втором и третьем узлах выполните команду из вывода:

docker swarm join --token SWMTKN-1-xxxxx 10.0.0.1:2377

Для добавления дополнительного manager-узла получите отдельный токен:

docker swarm join-token manager

Проверьте состояние кластера:

docker node ls

Вывод покажет все узлы, их статус и роль. Узел-лидер отмечен звездочкой в колонке MANAGER STATUS.

Развертывание сервисов с репликами

В Swarm контейнеры запускаются как сервисы. Сервис описывает желаемое состояние: образ, количество реплик, порты, сети. Swarm поддерживает это состояние автоматически.

Запустите веб-сервис с тремя репликами:

docker service create --name web --replicas 3 -p 80:80 nginx:1.27

Swarm распределит три реплики по доступным узлам. Реплики дают отказоустойчивость только при размещении на разных узлах: три реплики на одном хосте не переживут отказ этого хоста.

Проверить распределение:

docker service ls
docker service ps web

В выводе docker service ps web видно, на каком узле работает каждая реплика и ее текущее состояние. Если один узел выйдет из строя, Swarm перезапустит его реплики на оставшихся.

Для более глубокого погружения в оркестрацию от Docker Compose до Swarm используйте пошаговое руководство по эволюции оркестрации.

Docker Swarm: routing mesh и self-healing при сбоях

Swarm обеспечивает высокую доступность двумя механизмами: routing mesh для балансировки входящего трафика и self-healing для поддержания желаемого количества реплик.

routing mesh в Docker Swarm: как работает балансировка

Когда вы публикуете порт сервиса через --publish, Swarm настраивает этот порт на всех узлах кластера, независимо от того, где фактически работают реплики. Запрос на любой узел по опубликованному порту автоматически перенаправляется на доступную реплику.

Внутренний балансировщик Swarm распределяет запросы между всеми репликами сервиса. Вам не нужен внешний балансировщик для базовой отказоустойчивости: любой узел кластера принимает трафик и отправляет его на здоровую реплику.

Проверить это можно простым curl на IP любого узла кластера по опубликованному порту. Ответ придет независимо от того, на каком узле работает конкретная реплика.

self-healing: автоматическое восстановление после сбоев

Swarm постоянно сравнивает фактическое состояние кластера с желаемым. Если реплика падает, Swarm запускает новую на доступном узле. Если узел становится недоступным, его задачи переносятся на другие узлы.

Для manager-узлов работает Raft consensus. Если лидер падает, оставшиеся manager-узлы выбирают нового лидера, и управление кластером продолжается. Кластер сохраняет работоспособность, пока доступно большинство manager-узлов: два из трех или три из пяти.

Симулировать сбой можно командой drain, которая мягко выводит узел из обслуживания:

docker node update --availability drain node2

Swarm перенесет все задачи с node2 на другие узлы. Команда docker service ps web покажет новые расположения реплик.

Практические сценарии: stateless и stateful — веб-сервис и база данных

Разберем два типовых сценария: stateless веб-сервер и stateful база данных. Подходы к отказоустойчивости у них разные.

Тип сервисаБазовая схемаЧто важно при сбое
statelessНесколько replicas на разных узлах и routing mesh для входящего трафика.Реплику можно заменить без потери уникального состояния контейнера.
statefulОдна реплика с volume или репликация средствами СУБД.Swarm не синхронизирует данные; нужны отдельные backup и failover.

Веб-сервер с несколькими репликами

Для stateless-приложений отказоустойчивость достигается простым увеличением количества реплик. Создайте сервис Nginx с тремя репликами и опубликованным портом:

docker service create \
  --name web \
  --replicas 3 \
  --publish published=80,target=80 \
  nginx:1.27

Проверьте состояние:

docker service ps web

Отправьте запрос на любой узел кластера:

curl http://10.0.0.1

Ответ придет от одной из трех реплик. Остановите один worker-узел и повторите запрос: сервис продолжит отвечать, Swarm перераспределит реплики автоматически.

База данных: особенности обеспечения отказоустойчивости

База данных хранит состояние, поэтому простое увеличение реплик не решает проблему: каждая реплика будет работать со своим локальным хранилищем, данные разойдутся. Для stateful-сервисов нужен другой подход.

Базовый вариант — одна реплика с volume и привязкой к конкретному узлу:

docker service create \
  --name db \
  --replicas 1 \
  --constraint node.hostname==node1 \
  --mount type=volume,source=dbdata,target=/var/lib/postgresql/data \
  --restart-condition=on-failure \
  --restart-max-attempts 5 \
  postgres:16

Параметр --constraint гарантирует, что контейнер всегда запускается на node1, где находится volume с данными. В Swarm для service используются параметры restart-condition и restart-max-attempts; локальная политика unless-stopped из docker run в этом синтаксисе недоступна. В приведенном примере задача перезапускается при ошибке до пяти попыток.

Если узел node1 падает, база данных станет недоступной до восстановления узла: ограничение node.hostname не позволит Swarm перенести задачу на другой хост без доступного хранилища и соответствующей конфигурации.

Если просто заменить --replicas 1 на --replicas 2 без репликации на уровне СУБД, Swarm запустит два независимых экземпляра PostgreSQL. При размещении на разных узлах у них будут разные локальные volume, поэтому данные могут разойтись, а запросы — обращаться к разным состояниям. Swarm не превращает базу данных в отказоустойчивый кластер.

Для настоящей высокой доступности базы данных нужны репликация и автоматический failover. Это отдельная тема, выходящая за рамки статьи. Swarm обеспечивает инфраструктурную основу, но логику репликации данных настраивает сама СУБД.

Мониторинг и проверка отказоустойчивости

Регулярная проверка состояния кластера помогает обнаружить проблемы до того, как они повлияют на пользователей. Основные команды:

  • docker node ls — состояние всех узлов, их доступность и роль.
  • docker service ls — список сервисов и количество реплик.
  • docker service ps <service> — распределение задач по узлам и их статус.
  • docker service inspect <service> — детальная конфигурация сервиса.

Для проверки отказоустойчивости регулярно проводите учения: выводите узлы из обслуживания командой docker node update --availability drain и наблюдайте за переносом задач. Это покажет, как кластер ведет себя при реальном сбое.

Настройку мониторинга Prometheus и логирования Loki для Docker в production разбирает полное руководство по безопасному деплою.

Лучшие практики для повышения отказоустойчивости

Базовые механизмы Swarm и restart policy — это фундамент. Следующие практики повышают надежность системы.

Healthcheck. Определите проверку состояния внутри контейнера. Healthcheck показывает, отвечает ли приложение, но сам по себе не заменяет restart policy и не гарантирует перезапуск при статусе unhealthy. Для self-healing проверяйте не только процесс, но и реакцию сервиса на реальный сбой.

Ограничение ресурсов. Задайте лимиты CPU и памяти для каждого сервиса:

docker service create --name api --limit-cpu 0.5 --limit-memory 512M my-api:latest

Это предотвращает ситуацию, когда один контейнер потребляет все ресурсы узла и деградирует соседние сервисы.

Rolling updates. Обновляйте сервисы постепенно, чтобы избежать одновременного простоя всех реплик:

docker service update --image nginx:1.28 --update-parallelism 1 --update-delay 10s web

Swarm обновит реплики по одной с паузой 10 секунд между ними. Если новая версия падает, обновление можно откатить.

Резервное копирование. Для stateful-сервисов настройте регулярные бэкапы volume. Отказоустойчивость не заменяет резервное копирование: при повреждении данных на всех репликах восстановить систему можно только из бэкапа.

Для размещения отказоустойчивого кластера нужна надежная облачная инфраструктура. Timeweb Cloud предоставляет VDS/VPS и Kubernetes с гибким масштабированием ресурсов.

Заключение

Отказоустойчивость Docker строится на двух уровнях. Restart policy в Docker защищает от сбоев процесса на одном хосте: политики on-failure, always и unless-stopped покрывают большинство локальных сценариев. Docker Swarm решает задачу на уровне кластера: реплики распределяются по узлам, routing mesh балансирует трафик, self-healing восстанавливает сервисы после отказа узлов.

Выбор между restart policy и Swarm зависит от масштаба. Для одного хоста достаточно политик перезапуска. Если узел может стать недоступным, используйте Docker Swarm с минимум тремя manager-узлами и репликацией stateless-сервисов. Для stateful-сервисов отдельно спроектируйте репликацию данных, failover и резервное копирование. Начните с пошагового руководства по настройке отказоустойчивого кластера Swarm — там готовые команды для production-среды.

Поделиться:
Сохранить гайд? В закладки браузера