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

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

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

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

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

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

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

Политики перезапуска 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 запоминает, что контейнер остановлен вручную, и не трогает его до явного запуска.

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

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

Если контейнер пять раз завершится с ошибкой, 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 и когда их недостаточно

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

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

Сравнение Swarm и Kubernetes с практическими аргументами для перехода в 2026 году разобрано в отдельном материале.

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

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 используйте пошаговое руководство по эволюции оркестрации.

Балансировка нагрузки и автоматическое восстановление в Swarm

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

Routing mesh: как работает балансировка

Когда вы публикуете порт сервиса через --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-приложений отказоустойчивость достигается простым увеличением количества реплик. Создайте сервис 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=unless-stopped \
  postgres:16

Параметр --constraint гарантирует, что контейнер всегда запускается на node1, где находится volume с данными. Политика unless-stopped перезапустит контейнер при сбое процесса. Если узел node1 падает, база данных станет недоступной до восстановления узла.

Для настоящей высокой доступности базы данных нужны репликация и автоматический 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. Определите проверку состояния внутри контейнера. Swarm будет перезапускать контейнеры, которые не проходят проверку, даже если процесс формально жив. Для сервисов Swarm healthcheck задается в образе или через параметры --health-cmd при создании сервиса.

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

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

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

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

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

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

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

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

Заключение

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

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

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