Оркестрация контейнеров с Docker Swarm на Ubuntu 24.04

Оркестрация контейнеров с Docker Swarm на Ubuntu 24.04

Swarm Mode — встроенный инструмент Docker для оркестрации контейнеров. С его помощью можно объединять несколько серверов в единый кластер и управлять ими как одной системой. В статье мы разберём, как настроить Swarm на Ubuntu 24.04, развернуть веб-сервисы, а также работать с конфигурациями и секретами.

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

Введение

Контейнеризация с Docker решила проблему переносимости приложений, но управление десятками контейнеров вручную быстро превращается в хаос: масштабирование под нагрузкой требует скриптов, сбой на ноде останавливает сервисы, а обновления грозят простоем. Оркестрация автоматизирует эти процессы, и Docker Swarm Mode — логичный выбор для тех, кто уже работает с Docker. Будучи встроенным в Docker Engine (с версии 1.12), Swarm не требует установки сложных внешних компонентов — всё управляется знакомыми командами docker service.

Swarm предпочтительнее Kubernetes для малых и средних кластеров (до 50 нод), где доминируют stateless-приложения (веб-серверы, API, фоновые обработчики), если нужно быстро запустить оркестрацию или нет ресурсов на поддержку тяжёлой инфраструктуры. Когда вы столкнётесь с необходимостью Canary-развёртываний, сложных сетевых политик или кластеров размером более 100 нод — тогда стоит задуматься о Kubernetes. Но для старта Swarm остаётся лучшим по эффективности.

В этой статье мы рассказываем, как создать Swarm-кластер на Ubuntu 24.04 на примере веб-приложения.

Аренда VPS/VDS — от ₽219/месяц

Почему выбирают VPS от AdminVPS:

✓ Дешевле физического сервера

✓ Более гибкий и мощный, чем обычный хостинг

✓ Бесплатная защита от DDoS и техподдержка 24/7

✓ Масштабируется под любые задачи

Виртуальный сервер VPS/VDS — ваш личный сервер для сайтов, магазинов, ботов и других проектов.

popup12

Подготовка инфраструктуры

В Docker Swarm ноды разделяются на две роли:

  • Менеджеры (managers) — управляют состоянием кластера, хранят данные Raft Consensus, обрабатывают API-запросы. Для отказоустойчивости требуется минимум 3 менеджера.
  • Воркеры (workers) — это ноды, на которых выполняются задачи (контейнеры). Они не участвуют в управлении кластером, а только получают инструкции от менеджеров.

Хосты могут выполнять роль менеджера и воркера одновременно — менеджеры настроены так по умолчанию, но их можно переключить на работу только в режиме управления.

Требования к сети:

  • 2377/tcp — порт для коммуникации с менеджерами и между ними.
  • 7946/tcp,udp — для обнаружения узлов overlay-сети.
  • 4789/udp — VXLAN-туннели для трафика overlay-сетей.

Убедитесь, что файрвол разрешает этот трафик между всеми нодами.

Перейдём к подготовке серверов Ubuntu 24.04. Выполните на каждой будущей ноде кластера обновление индекса пакетов и установку обновлений:

sudo apt update && sudo apt upgrade -y

Установите Docker Engine из репозитория Ubuntu:

sudo apt install -y docker.io

docker.io — официальный пакет Docker в репозиториях Ubuntu (версия 26.1.3+ на момент релиза 24.04).

Разрешите автозапуск Docker при загрузке и запустите службу:

sudo systemctl enable --now docker

Запустите тестовый контейнер для проверки установки:

sudo docker run --rm hello-world

--rm удалит контейнер сразу после завершения работы.

Вы должны увидеть сообщение от Docker:

Hello from Docker!

This message shows that your installation appears to be working correctly.

Рекомендации для продакшена:

  • Аппаратные требования — минимум 2 ядра CPU, 2 ГБ RAM на ноду. Для менеджеров добавьте ещё по 1 ГБ RAM.
  • Сеть — статические IP-адреса для всех нод, отключённый swap (команда sudo swapoff -a).
  • Безопасность — настройте туннелирование или ограничьте доступ к портам 2377/7946 только доверенным IP.

Все ноды должны:

  • иметь одинаковую версию Docker (проверка: sudo docker version);
  • разрешать коммуникацию по ключевым портам;
  • иметь синхронизированное время (NTP).

Создание Swarm-кластера

Docker Swarm использует архитектуру «менеджер-воркер», где управляющие ноды координируют работу через Raft Consensus — алгоритм распределённого консенсуса. Это обеспечивает отказоустойчивость: кластер сохраняет работоспособность при потере до 50 % менеджеров (например, 1 из 3, 2 из 5). Все коммуникации между нодами защищены TLS-шифрованием «из коробки», включая аутентификацию воркеров.

Инициализация кластера

На сервере, который будет главным менеджером, выполните:

sudo docker swarm init --advertise-addr <MANAGER_IP>

--advertise-addr указывает IP-адрес, который будут использовать другие ноды для подключения; замените <MANAGER_IP> на реальный IP сервера. Если сервер имеет несколько интерфейсов, явное указание IP предотвращает ошибки.

Команда автоматически генерирует токен для присоединения воркеров.

Пример вывода:

Swarm initialized: current node (d4n5g...) is now a manager.
To add a worker to this swarm, run the following command:
    docker swarm join --token SWMTKN-1-59fl8... 192.168.1.100:2377

Присоединение воркеров

На каждом сервере-воркере выполните команду из вывода выше:

sudo docker swarm join --token SWMTKN-1-59fl8... 192.168.1.100:2377

Токен (SWMTKN-1...) обеспечивает аутентификацию и авторизацию и гарантирует, что к кластеру присоединяются только доверенные ноды. Если токен утерян, просмотреть его можно на менеджере, выполнив:

sudo docker swarm join-token worker

Проверка кластера

На менеджере выполните:

sudo docker node ls

Ожидаемый вывод:

ID  HOSTNAMESTATUSAVAILABILITYMANAGER STATUSENGINE VERSION
d4n5g... * manager1ReadyActiveLeader26.1.3
x8qk2... worker1ReadyActive26.1.3
p3mz7... worker2ReadyActive26.1.3
Таблица. Статус узлов Docker Swarm

Что означают статусы:

  • * — текущая нода, где выполняется команда;
  • MANAGER STATUS: Leader — нода принимает решения;
  • Reachable — резервный менеджер (если их несколько);
  • Availability: Active/Drain — может ли нода получать задачи.

Добавление менеджеров

Чтобы добавить дополнительный менеджер, выполните на менеджере-лидере:

sudo docker swarm join-token manager

Эта команда выведет токен и команду для присоединения ноды в качестве менеджера. Если добавить опцию -q (--quiet), то будет выведен только токен.

Затем выполните на новой ноде-менеджере, указав токен, IP-адрес лидера и порт:

sudo docker swarm join --token SWMTKN-1-... 192.168.1.100:2377

Ротация токенов

Проводите ротацию токенов, если токены или узлы кластера были скомпрометированы:

sudo docker swarm join-token --rotate worker  # или manager

После этого новые ноды не смогут присоединиться к кластеру со старым токеном.

Если при присоединении появляется ошибка «Timeout» — проверьте файрвол (порты 2377, 7946, 4789) и доступность <MANAGER_IP>.

Развёртывание сервисов

Основная единица развёртывания в Docker Swarm — сервис (service), который описывает желаемое состояние контейнера (образ, количество реплик, сеть). Каждая реплика сервиса — это задача (task), запущенная на одной из нод кластера. Для связи сервисов используются overlay-сети, работающие поверх физической сети, а внешний доступ к сервисам обеспечивается через опубликованные порты.

Запуск Nginx с балансировкой нагрузки

Создадим сервис веб-сервера с 3 репликами, доступный извне кластера:

sudo docker service create --name web \
  --replicas 3 \
  -p 80:80 \
  --network ingress \
  nginx:alpine

Пояснение параметров:

  • --name web — имя сервиса для управления;
  • --replicas 3 — количество идентичных контейнеров (Swarm распределит их по нодам);
  • -p 80:80 — публикация порта: внешний порт 80 → порт 80 в контейнере;
  • --network ingress — подключение к встроенной сети для входящего трафика;
  • nginx:alpine — официальный образ (alpine имеет меньший размер).

Проверка:

sudo docker service ps web # статус задач
curl http://localhost     # запрос к Nginx (на любой ноде кластера)

Создание overlay-сети для внутреннего трафика

Для защищённого взаимодействия сервисов создадим изолированную сеть:

sudo docker network create -d overlay \
  --subnet 10.13.0.0/24 \
  --attachable \
  my-net

Здесь:

  • -d overlay — драйвер для сетей между нодами;
  • --subnet — CIDR задаёт фиксированный диапазон IP в подсети;
  • --attachable — разрешает ручной запуск контейнеров в сети.

Запуск Python-API

Развернём сервис с Flask-приложением в сети my-net:

sudo docker service create --name api \
  --replicas 2 \
  --network my-net \
  python:3.11-slim \
  sh -c "pip install --no-cache-dir flask && echo 'from flask import Flask; app=Flask(__name__); @app.route(\"/\") def home(): return \"Hello Swarm!\"' > app.py && python -u app.py"

Разберём параметры:

  • --network my-net — подключение к созданной overlay-сети;
  • python:3.11-slim — оптимизированный образ Python.

Команда установки Flask и запуска приложения:

  • --no-cache-dir — отключение кеширования пакетов для экономии места;
  • -u в python -u — небуферизованный вывод (для корректных логов);
  • порт Flask по умолчанию (5000) доступен только внутри my-net.

Проверка связи между сервисами

Запустим временный контейнер в сети my-net:

sudo docker run -it --rm \
  --network my-net \
  alpine sh

Протестируем API изнутри сети:

wget -O- api:5000

Ожидаемый вывод: Hello Swarm!

В результате:

  • Сервис web доступен по порту 80 любой ноды кластера.
  • Сервис api доступен только через сеть my-net по DNS-имени api.
  • Swarm DNS автоматически резолвит api во все IP его задач.

Обратите внимание, что ingress-сеть использует L4-балансировку (TCP/UDP). Для HTTP/HTTPS балансировки потребуется Nginx или Traefik внутри кластера.

Управление конфигурацией и секретами

В Docker Swarm данные конфигурации и секреты управляются централизованно, что обеспечивает безопасность и согласованность развёртываний. При этом секреты — это критичная информация (пароли, ключи): они хранятся в зашифрованном виде в Raft-логе менеджеров и передаются только на ноды, где запущены связанные задачи.

Создание конфига для Nginx

Сгенерируем конфигурацию для оптимизации worker-процессов:

echo "worker_processes auto;" | sudo docker config create nginx-conf -

Здесь:

  • docker config create создаёт объект конфигурации в Swarm;
  • nginx-conf — имя конфига;
  • - — указывает, что данные передаются через STDIN (можно указать файл nginx.conf).

Команда выполняется только на менеджере. Конфигурация будет храниться в распределённом хранилище и автоматически реплицироваться на все менеджеры. Это позволяет хранить конфиги отдельно от образов и менять их без пересборки, а также гарантирует одинаковую конфигурацию для всех реплик сервиса.

Добавление секрета (пароля базы данных)

Создадим защищённый секрет (также на менеджере):

echo "qwerty123" | sudo docker secret create db_password -

Секрет шифруется с помощью AES-256-GCM и сохраняется в Raft. При запуске задачи секрет монтируется в контейнер как файл в tmpfs, то есть он никогда не сохраняется на диске воркеров. Также секреты не видны в логах и docker inspect — там отображается только ID, но не содержимое.

Обновление сервиса

Добавим конфиг и секрет к сервису web:

sudo docker service update \
  --config-add source=nginx-conf,target=/etc/nginx/nginx.conf \
  --secret-add source=db_password,target=/run/secrets/db_pass \
  web

Параметры:

  • --config-add source=... ,target=... — монтирует конфиг как файл по указанному пути;
  • --secret-add source=... ,target=... — аналогичное действие для секрета (права 0400);

Swarm выполнит последовательное обновление сервиса с нулевым даунтаймом.

Проверка внутри контейнера

Проверка выполняется на любой ноде, где есть задачи сервиса web (можно на менеджере или воркере). Цель — убедиться, что конфиг действительно смонтирован и имеет правильные права (только для чтения), а секрет доступен в контейнере и содержит корректное значение. Найдите запущенный контейнер сервиса:

sudo docker ps --filter name=web -q

Просмотрите файловую систему:

sudo docker exec <CONTAINER_ID> ls -l /etc/nginx/nginx.conf
sudo docker exec <CONTAINER_ID> cat /run/secrets/db_pass

Ожидаемый результат:

-r--r--r-- 1 root root 20 May 15 10:00 /etc/nginx/nginx.conf  # конфиг
qwerty123                                                     # секрет

Преимущества такого обновления:

  • Безопасность секретов — даже при компрометации ноды злоумышленник не получит данные.
  • Централизованное управление — изменение конфига/секрета через docker config|secret update автоматически обновит все сервисы.
  • Версионирование — каждое изменение создаёт новую версию, что позволяет откатиться к предыдущей.

Не используйте секреты для данных более 500 КБ — это нагрузка на Raft-лог. Для больших объёмов (например, TLS-ключи) монтируйте внешние тома.

Читайте в блоге:

Loading spinner
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

Нужен VPS сервер?

Арендуйте мощный VPS сервер для ваших проектов! Быстрая настройка, высокая производительность и надежная поддержка 24/7. Начните прямо сейчас!

Что будем искать? Например,VPS-сервер

Мы в социальных сетях