1. Архитектура кластера: роли менеджеров, воркеров и механизмы консенсуса
Архитектура кластера: роли менеджеров, воркеров и механизмы консенсуса
Представьте ситуацию: в три часа ночи на одном из серверов в дата-центре выходит из строя блок питания. Если ваше приложение запущено в обычном Docker-контейнере на этой машине, сервис мгновенно становится недоступным. В мире высоконагруженных систем такая ситуация недопустима. Docker Swarm решает эту проблему, превращая группу изолированных хостов в единый виртуальный вычислительный ресурс. Однако за внешней простотой команды docker swarm init скрывается сложная распределенная система, работающая на базе алгоритмов консенсуса и четкого разделения обязанностей между узлами.
Двухуровневая иерархия: Менеджеры и Воркеры
Кластер Docker Swarm строится на взаимодействии узлов (nodes), каждый из которых выполняет одну из двух ролей. Важно понимать, что роль узла — это не приговор, а текущий статус в рамках кластера, который можно менять «на лету» без остановки системы.
Узлы-менеджеры (Managers)
Менеджеры являются «мозгом» кластера. Их основная задача — поддержание желаемого состояния системы. Если вы сообщаете Swarm, что в кластере должно быть запущено пять экземпляров веб-сервера Nginx, именно менеджеры будут следить за тем, чтобы это число оставалось неизменным.
Функции менеджеров включают:
Узлы-воркеры (Workers)
Воркеры — это «мускулы» кластера. Их единственная задача — выполнять контейнеры, которые им поручили менеджеры. Воркер не принимает решений о том, где запустить задачу, и не знает о глобальном состоянии кластера. Он лишь сообщает менеджеру о статусе запущенных на нем процессов.
Интересной особенностью архитектуры является то, что по умолчанию каждый менеджер также является воркером. Это означает, что на управляющем узле могут запускаться пользовательские нагрузки. В небольших тестовых средах это удобно, но в промышленной эксплуатации (production) часто практикуется «дрессировка» менеджеров: их переводят в режим Drain, чтобы они занимались только управлением и не тратили ресурсы CPU и RAM на выполнение прикладных контейнеров.
Механизм консенсуса и алгоритм Raft
Когда у вас один менеджер, всё просто: он единоличный правитель. Но одиночный менеджер — это единая точка отказа (Single Point of Failure). Если он выйдет из строя, кластер станет неуправляемым. Для обеспечения отказоустойчивости в Swarm добавляют несколько менеджеров. Здесь возникает фундаментальная проблема распределенных систем: как заставить несколько независимых серверов договориться о едином состоянии данных?
Для решения этой задачи Docker Swarm использует алгоритм консенсуса Raft.
Как работает Raft в контексте Swarm
Raft гарантирует, что если в кластере произошло изменение (например, вы обновили образ сервиса), это изменение будет либо записано на всех менеджерах, либо не записано вовсе. В каждый момент времени среди менеджеров выбирается один Лидер (Leader). Все остальные менеджеры становятся Последователями (Followers).
Процесс записи данных выглядит так:
Понятие кворума и расчет количества узлов
Кворум — это минимальное количество менеджеров, которые должны быть доступны, чтобы кластер мог принимать решения. Формула кворума выглядит так:
Где — общее количество менеджеров в кластере, а — необходимый кворум.
Рассмотрим практические сценарии: * Если у вас 3 менеджера, кворум составляет . Это означает, что кластер выдержит отказ одного менеджера. * Если у вас 5 менеджеров, кворум составляет . Кластер выдержит отказ двух менеджеров.
> Важный нюанс: Использование четного количества менеджеров (например, 2 или 4) не имеет смысла с точки зрения отказоустойчивости. Кластер из 4 менеджеров требует кворум в 3 узла. Это значит, что он может пережить потерю только одного узла — точно так же, как и кластер из 3 менеджеров. Однако вероятность выхода из строя одного из четырех узлов выше, чем одного из трех. Поэтому золотое правило Swarm: всегда используйте нечетное количество менеджеров (3, 5 или 7).
Жизненный цикл задачи: от команды до контейнера
В Docker Swarm мы не оперируем понятием «контейнер» в привычном смысле. Мы управляем сервисами (Services). Сервис — это декларативное описание того, как должен выглядеть ваш аппликейшн.
Когда вы создаете сервис, менеджер разбивает его на задачи (Tasks). Задача — это атомарная единица планирования. Если вы создали сервис с тремя репликами, Swarm создаст три задачи. Каждая задача в конечном итоге превращается в запущенный контейнер на конкретном воркере.
Процесс развертывания выглядит следующим образом:
Внутренняя топология сети и Service Discovery
Одной из самых мощных функций архитектуры Swarm является встроенная система маршрутизации — Routing Mesh.
Когда вы публикуете порт сервиса (например, порт 80), Swarm открывает этот порт на всех узлах кластера, включая те, на которых физически не запущен ни один контейнер этого сервиса. Это работает благодаря комбинации IPVS (IP Virtual Server) в ядре Linux и внутренней сети ingress.
Представьте кластер из 10 узлов. Веб-сервис запущен только на узлах А и Б. Если запрос придет на узел В (где нет контейнера), внутренний балансировщик Swarm перенаправит трафик через overlay-сеть на узел А или Б. Для внешнего пользователя кластер выглядит как единый гигантский сервер.
Внутри кластера сервисы общаются друг с другом через виртуальные имена. Docker Swarm включает в себя встроенный DNS-сервер. Если сервис app хочет обратиться к базе данных db, он просто делает запрос по имени db. Swarm автоматически разрешит это имя в виртуальный IP-адрес (VIP) сервиса базы данных и сбалансирует нагрузку между всеми его репликами.
Безопасность «из коробки»: TLS и шифрование
В отличие от многих других систем оркестрации, Docker Swarm по умолчанию защищен. В момент инициализации кластера (swarm init) создается корневой удостоверяющий центр (Root CA).
Все коммуникации между узлами (менеджер-менеджер и менеджер-воркер) шифруются с помощью взаимной аутентификации TLS (mTLS). Когда новый узел присоединяется к кластеру, он получает сертификат с коротким сроком жизни. Swarm автоматически занимается ротацией этих сертификатов, что избавляет администратора от ручного управления ключами.
Для присоединения нового узла используются токены присоединения (Join Tokens). Существуют отдельные токены для воркеров и менеджеров. Токен — это по сути секретный ключ, который подтверждает право узла войти в состав кластера. Если токен скомпрометирован, его можно отозвать и сгенерировать новый без остановки работы существующих узлов.
Граничные случаи и поддержание здоровья кластера
Архитектура Swarm спроектирована так, чтобы минимизировать последствия «разрезания сети» (Network Partition). Если группа воркеров теряет связь с менеджерами, они продолжают выполнять уже запущенные контейнеры, но не могут принимать новые задачи. Если же связь теряет менеджер, и он оказывается в меньшинстве (не может собрать кворум), он немедленно прекращает выполнять функции управления, чтобы не допустить рассинхронизации данных (состояние Split-brain).
Особое внимание стоит уделить хранению данных. Swarm отлично справляется с оркестрацией процессов (Stateless), но управление состоянием (Stateful) требует внешних решений, таких как сетевые хранилища (NFS, Ceph, облачные диски). Поскольку задача может мигрировать с узла на узел, данные должны следовать за ней.
В завершение стоит отметить, что понимание ролей и механизмов консенсуса — это фундамент. Именно знание того, как Raft обеспечивает целостность, а менеджеры распределяют задачи, позволяет строить системы, способные пережить не только выход из строя отдельного сервера, но и масштабные сбои в сетевой инфраструктуре дата-центра. Docker Swarm предоставляет инструменты, но стратегия их использования зависит от понимания этих базовых архитектурных принципов.