Docker Swarm остаётся самым простым способом собрать кластер контейнеров на нескольких VDS: инициализировали управляющий узел, присоединили воркеры, дали сервисам overlay‑сеть — и вы уже получаете встроенный балансировщик, отказоустойчивый планировщик, безопасные секреты и управляемые rolling update. Для многих веб‑и API‑нагрузок этого достаточно, чтобы жить без простоя и избегать ручной рутины при деплое.
Когда выбирать Swarm на VDS
Если нужен минималистичный кластер без тяжёлой экосистемы, Swarm на нескольких VDS даёт быстрый старт и предсказуемое поведение. Классические сценарии: фронтенд+бэкенд+БД (с учётом грамотной работы с состоянием), микросервисы с умеренной связностью, сервисы без жёстких сетевых политик. Встроенные возможности пригодятся сразу: overlay и ingress, балансировка по VIP/DNSRR, Raft, secrets/configs, управляемые обновления.
Сетевые основы: overlay, ingress, VIP и DNSRR
Swarm строит межконтейнерную связность через overlay (VXLAN). Overlay создаётся один раз и может использоваться несколькими сервисами. Ingress — специальная сеть для публикации портов и routing mesh: любой узел кластера может принять внешний запрос к сервису, даже если задача работает на другом узле. Сервисная балансировка по VIP (дефолт) даёт стабильный виртуальный IP, а DNSRR — round‑robin по IP задач.
Типовые грабли — MTU и фаервол. Overlay использует UDP 4789 (VXLAN), служебный обмен — TCP/UDP 7946, управление — TCP 2377. При заниженном MTU (доп. инкапсуляция у провайдера) проверьте MTU end‑to‑end и протестируйте большие пакеты. Блокировка портов ведёт к флапу overlay и потерям трафика.

Raft‑кворум менеджеров: почему нечётное число и что будет при сбое
Конфигурация Swarm хранится в Raft‑журнале. Нужен кворум менеджеров (большинство) для любых изменений. Один менеджер годится только для разработки, прод — 3 менеджера в разных зонах/узлах. Данные Raft шифруются на диске; опция autolock защищает ключи, но потребует разблокирования после рестартов демона.
# Инициализация кластера на первом менеджере
docker swarm init --advertise-addr <MANAGER_IP>
# Выдача токенов
docker swarm join-token manager
docker swarm join-token worker
# Присоединение узлов (пример)
docker swarm join --token <MANAGER_TOKEN> <MANAGER_IP>:2377
# Включить автолок и получить ключ разблокировки
docker swarm update --autolock=true
docker swarm unlock-key
# Ротация CA и join-токенов (по регламенту)
docker swarm ca --rotate
docker swarm join-token --rotate worker
docker swarm join-token --rotate manager
Порты и фаервол на VDS
Откройте между всеми узлами: TCP 2377 (управление), TCP/UDP 7946 (служебная шина), UDP 4789 (VXLAN). Не забудьте пользовательские порты сервисов. Следите за conntrack: под нагрузкой переполнение nf_conntrack вызывает обрывы.
# Быстрый пример для UFW
sudo ufw allow 2377/tcp
sudo ufw allow 7946/tcp
sudo ufw allow 7946/udp
sudo ufw allow 4789/udp
# Рекомендуемые sysctl (пример: /etc/sysctl.d/99-swarm.conf)
net.netfilter.nf_conntrack_max=262144
net.netfilter.nf_conntrack_buckets=65536
net.core.somaxconn=1024
net.ipv4.ip_local_port_range=1024 65000
# Применить
sudo sysctl --system
# Проверка MTU (Linux iputils), ищем максимальный размер без фрагментации
ping -M do -s 1472 <PEER_IP>
Если узлы распределены по разным сетям/ДЦ, удобно проложить peer‑to‑peer туннель и зафиксировать MTU. Для устойчивого туннеля c roaming и keepalive рассмотрите WireGuard с roam/keepalive.
VIP против DNSRR и влияние на балансировку
VIP удобен и стабилен (одно имя — один IP). DNSRR полезен, когда клиент сам управляет пулом соединений и отслеживает живость целей. Для долгих WebSocket‑сессий используйте DNSRR и публикацию в mode=host, чтобы не терять привязку к конкретной задаче.
Ingress и публикация портов: routing mesh и mode=host
Есть два варианта публикации портов: через ingress (routing mesh) или mode=host. Mesh прост и отказоустойчив, подходит большинству HTTP‑нагрузок. mode=host даёт предсказуемость и отсутствие лишнего хопа — полезно для stateful и L4‑трафика. Для L4‑балансировки вместе с mode=host можно применить NGINX Stream; см. пример конфигурации NGINX для TCP/UDP.
# Пример overlay-сети (attachable — удобно для отладки)
docker network create --driver overlay --attachable app-net
# Фрагмент stack.yml: ingress-публикация и обновления
version: "3.9"
services:
api:
image: registry.example.com/team/api@sha256:111122223333...
networks: [app-net]
deploy:
replicas: 3
update_config:
parallelism: 2
delay: 10s
order: start-first
monitor: 30s
failure_action: rollback
rollback_config:
parallelism: 2
monitor: 30s
placement:
constraints:
- node.labels.role == backend
ports:
- target: 8080
published: 80
protocol: tcp
mode: ingress
networks:
app-net:
external: true
Для mode=host во фронтенде можно отдавать несколько A‑записей и балансировать на уровне DNS. Если домены ещё не заняты — сразу оформите регистрацию доменов и настройте многозаписный A‑RR. Не забудьте про TLS: для публичных входов заранее подготовьте SSL-сертификаты и регулярную ротацию.
Secrets и configs: хранение чувствительных данных
Секреты шифруются в Raft и доставляются только на узлы с нужными задачами как файловые дескрипторы. Не храните пароли в переменных окружения без необходимости — используйте secrets. Configs подходят для нечувствительных настроек (конфиг Nginx и т.п.).
# Создание секрета из файла
printf "s3cr3tP@ss" | docker secret create db_password -
# Фрагмент stack.yml: подключение секрета
services:
api:
secrets:
- source: db_password
target: /run/secrets/db_password
secrets:
db_password:
external: true
Рекомендуется регулярно ротировать CA и сертификаты узлов, ограничивать распространение join‑токенов и минимизировать набор секретов для каждой задачи.

Rolling update без простоя: параметры, порядок, откаты
Обновления контролируются update_config/rollback_config: параллелизм, задержка, порядок start-first или stop-first, таймаут мониторинга и политика при сбоях. Включайте healthcheck в образах.
# Обновление сервиса с откатом при ошибке
docker service update --image registry.example.com/team/api@sha256:111122223333... --update-parallelism 2 --update-delay 10s --update-order start-first --update-monitor 30s --update-failure-action rollback api
Для очередей и воркеров иногда безопаснее режим
stop-first, чтобы избежать двойной обработки.
Планирование, метки, ограничения размещения
Задавайте роли узлам и закрепляйте сервисы constraints. Stateful‑нагрузки привязывайте к узлам с данными. Для обслуживания узла используйте режим drain.
# Маркируем узел и ограничиваем размещение
docker node update --label-add role=backend vds-2
# Выводим узел на обслуживание (без простоя)
docker node update --availability drain vds-2
Хранение данных: bind‑mounts, volume‑плагины и согласованность
Swarm не решает устойчивое хранение «из коробки». Варианты: локальный bind‑mount с привязкой к узлу (просто, но SPOF), сетевые volume‑драйверы к блочному хранилищу (переносимость, но внимательнее к задержкам), репликация на уровне приложения (реплики БД, шардинг).
# Пример фрагмента для stateful сервиса (bind-mount + привязка)
services:
db:
image: postgres:16
volumes:
- type: bind
source: /srv/db-data
target: /var/lib/postgresql/data
deploy:
placement:
constraints:
- node.hostname == vds-1
Производительность и стабилизация сети overlay
Overlay добавляет инкапсуляцию и немного задержки. На типичных VDS это терпимо для HTTP, но важно для RPC и трейдинга. Подберите MTU, следите за nf_conntrack, учитывайте CPU‑стоимость шифрования overlay и включайте его только там, где действительно нужно.
Мониторинг и диагностика: что смотреть в продакшене
Минимум: кворум и лидер менеджеров, лаги Raft, желаемые/реальные реплики, причины рестартов, healthcheck, метрики сети (ошибки, дропы, UDP 4789), системные метрики CPU/IO/диск и давление памяти.
# Полезные команды дежурному
docker node ls
docker service ls
docker service ps --no-trunc api
docker service logs -f api
docker events --since 1h
Практические паттерны балансировки
Встроенный балансировщик хорош для большинства случаев, но без липкости сессий. Для sticky‑cookie используйте L7‑прокси. Долгие соединения (WebSocket, streaming) лучше публиковать в mode=host и балансировать внешним L4/L7. Применяйте readiness‑пробу и плавный drain перед обновлением, чтобы избежать обрывов.
Безопасность кластера
Помимо secrets, уделите внимание жизненному циклу доверия: регулярная ротация CA и сертификатов, ограничение доступа к TCP 2377, autolock ключей на диске, принцип наименьших привилегий (не запускайте контейнеры с лишними capabilities).
# Примеры ротации
docker swarm ca --rotate
docker swarm join-token --rotate worker
docker swarm join-token --rotate manager
CI/CD: предсказуемые деплои образов
Собирайте образ в CI, пушьте в реестр и деплойте по digest, чтобы исключить «плавающие» теги. Прогрейте кэш, выполните миграции и smoke‑тесты на staging в том же Swarm, затем обновляйте прод с включённым rollback и небольшим параллелизмом.
# Деплой стека из Compose-файла
docker stack deploy -c stack.yml app
# Пример канареечного сервиса (ограниченный трафик через внешний прокси)
docker service create --name api-canary --label canary=true --replicas 1 registry.example.com/team/api@sha256:canary...
Чек‑лист развёртывания Swarm на нескольких VDS
- 3 менеджера (нечётное число) + воркеры под нагрузку, разные зоны отказа.
- NTP, стабильные DNS и маршруты.
- Открыты 2377/tcp, 7946/tcp+udp, 4789/udp между узлами.
- Проверен MTU, нет скрытой фрагментации.
- Созданы overlay‑сети; ingress настроен.
- Определены labels, constraints, preferences.
- Secrets/configs заведены; токены и CA ротируются по регламенту.
- У каждого сервиса есть healthcheck, update_config и rollback_config.
- Логи и метрики собираются централизованно.
Типичные проблемы и как их избежать
Разрывы в overlay: чаще всего MTU и conntrack. Подберите MTU, увеличьте лимиты nf_conntrack, проверьте таймауты и правила фаервола (ESTABLISHED/RELATED, NAT для VXLAN).
Потеря кворума: держите нечётное число менеджеров и разводите их по зонам; следите за диском — Raft чувствителен к fsync и нехватке места.
«Успешный» деплой с деградацией: без healthcheck и monitor Swarm может завершить апдейт слишком рано. Задавайте явные критерии готовности.
Долгие соединения и routing mesh: используйте mode=host и внешний балансировщик или готовьте приложение к переустановлению каналов при drain/обновлении.
Итоги
Docker Swarm на VDS — быстрый путь к устойчивому кластерному деплою с понятной overlay‑сетью, встроенной балансировкой и прозрачными rolling update. Соблюдайте базовые принципы: нечётный кворум менеджеров, аккуратный фаервол и MTU, secrets вместо переменных, healthcheck и rollback — и получите надёжную платформу для большинства веб‑нагрузок без избыточной сложности.
Когда требований становится больше — специализированные балансировщики на входе, mode=host для критичных потоков, планирование по меткам и аккуратная работа с состоянием. При необходимости выбора конфигурации фронта для L4 см. также руководство по NGINX Stream, а для межузловых связей — наш материал про WireGuard с keepalive.


