ADG Оставить заявку
Блог DevOps 5 мин чтения

Docker Swarm 0.3: трёхнодовый кластер без внешних зависимостей

Собираем трёхнодовый Docker Swarm 0.3/0.4, запускаем сервисы через стандартный Docker CLI. Оцениваем зрелость для stateless-задач и сравниваем с Mesos.

Контекст момента

Docker Swarm 0.3/0.4 развивается как нативная кластеризация Docker без внешних зависимостей - управление кластером через стандартный Docker CLI

На прошлой неделе выкроили время и собрали нормальный Swarm-кластер - не наспех на тестовой коробке, а три реальных ноды, реальная нагрузка, реальный разбор полётов. Поводом стал запрос от интеграционного проекта: клиент хочет запускать stateless-сервисы в контейнерах и спрашивает, есть ли что попроще Mesos. Docker Swarm выглядел как очевидный кандидат для ответа.

Что такое Swarm в версии 0.3

Swarm - это нативная кластеризация Docker. Идея простая: несколько Docker-демонов объединяются в один виртуальный хост, которым управляешь через обычный docker CLI. Никакого нового синтаксиса, никаких дополнительных абстракций - docker run на Swarm-мастере раскидывает контейнеры по нодам по стратегии планировщика.

В отличие от Mesos, Swarm не требует ZooKeeper, отдельного планировщика Marathon, Java-стека и команды специалистов для первоначального поднятия. Это его главный аргумент на сегодня.

Как собирали кластер

Три CentOS 7 сервера, Docker 1.6, Swarm 0.3. Открытие master на 2375 порту с TLS - обязательно, иначе любой в сети дёрнет ваш Docker API.

Базовая схема такая:

# На каждой ноде - регистрация в Consul (использовали как discovery backend)
docker run -d swarm join --addr=<NODE_IP>:2375 consul://<CONSUL_IP>:8500/swarm

# На мастере - Swarm manager
docker run -d -p 4000:4000 swarm manage \
  --strategy spread \
  consul://<CONSUL_IP>:8500/swarm

После этого docker -H tcp://<MASTER_IP>:4000 info показывает все три ноды и суммарные ресурсы. docker run автоматически выбирает ноду по стратегии.

Вместо Consul можно использовать встроенный token-based discovery через Docker Hub - но это облачная зависимость, для изолированного окружения не годится. Consul уже стоял у нас в инфраструктуре, поэтому его и взяли.

Стратегии планировщика

Swarm 0.3 даёт три стратегии размещения:

  • spread - раскидывает контейнеры по нодам равномерно, стараясь занять каждую хотя бы по одному контейнеру. Для нашего сценария оптимально.
  • binpack - набивает одну ноду до отказа, потом переходит к следующей. Логика экономии ресурсов.
  • random - случайный выбор. Для тестов удобно, для продакшна нет смысла.

Кроме стратегий есть constraints - метки на ноды и фильтры при запуске. Например:

docker run -e constraint:storage==ssd nginx

Пометили одну ноду storage=ssd, и контейнеры с таким constraint пойдут только на неё. Это закрывает базовые кейсы с разными типами железа.

Что работает нормально

Стандартный CLI. Главный плюс - ты не переучиваешься. Тот же docker ps, docker logs, docker exec. Контейнер запущен на удалённой ноде, но команды выглядят одинаково. Для команды, которая уже умеет Docker, порог входа в Swarm минимальный.

Docker Compose поверх Swarm. Взяли существующий docker-compose.yml от одного проекта, подняли через docker-compose -H tcp://<MASTER>:4000 up -d - заработало без изменений. Контейнеры разъехались по нодам по стратегии spread. Это приятно - переиспользуешь то, что уже написано для локальной разработки.

Автоматическая публикация портов. Swarm при запуске контейнера с -p публикует порт именно на той ноде, куда поместил контейнер. docker port показывает правильный адрес.

Где трещит по швам

Нет балансировки на уровне Swarm. Если запустил три реплики nginx - каждая сидит на своей ноде со своим портом. Клиент должен сам знать, куда ходить, или нужен внешний балансировщик. Mesos + Marathon умеют service discovery через HAProxy из коробки; здесь это ваша забота.

Планировщик примитивный. Spread раскидывает контейнеры по количеству, не по реальной нагрузке CPU/RAM. Можно получить ситуацию когда на одной ноде три тяжёлых контейнера, а рядом три лёгких - и Swarm доволен, у него по три штуки везде.

Нет health checks на уровне Swarm. Контейнер упал - Swarm его не перезапустит и не перенесёт на другую ноду. Максимум что есть - Docker restart policy на самом контейнере. Если нода недоступна, Swarm перестаёт отправлять туда контейнеры, но уже запущенные не мигрируют. Mesos + Marathon здесь выигрывает принципиально.

Состояние в discovery backend. При использовании Consul (или etcd) Swarm хранит там список нод. Это дополнительная зависимость, которую нужно мониторить и бэкапить. С token-based discovery зависимость уходит, но появляется требование наличия внешней сети.

Swarm vs Mesos: честное сравнение

На сегодняшний день это не совсем конкуренты - разный уровень зрелости и разный масштаб задач.

Mesos сложнее в развёртывании и требует отдельной экспертизы. Зато он умеет нормальный scheduling по ресурсам, health checks, rolling updates через Marathon, work с произвольными задачами - не только контейнерами. Если у вас десятки сервисов и требование отказоустойчивости - это разговор про Mesos.

Swarm закрывает другой сценарий: небольшой кластер (три-пять нод), stateless сервисы без сложных требований по планированию, команда уже в Docker и не хочет тратить неделю на онбординг в новый оркестратор. Для тестовых сред или небольших проектов аргумент про «просто docker run» реально работает.

Для нашего клиентского кейса Swarm оказался достаточным: несколько stateless API-сервисов, балансировщик снаружи уже есть (HAProxy), требования по HA минимальные. Mesos здесь был бы избыточен по операционной стоимости.

Итог

Swarm 0.3 работает. Для простых stateless-сценариев без жёстких требований к планированию ресурсов и автовосстановлению - вполне. Главный его козырь - нулевой порог входа для тех, кто уже использует Docker.

Принципиальные ограничения - отсутствие нормального scheduling по загрузке и отсутствие встроенного health check с перезапуском - это архитектурные решения, которых в Swarm нет. Для сложных production-сценариев это не замена Mesos.

Мы планируем погонять кластер ещё пару недель под реальной нагрузкой клиентского проекта - посмотрим, что всплывёт.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.