Docker Swarm на сервере: частые ошибки и решения
Кластер Docker Swarm собрали, а он капризничает: нода не присоединяется, сервис бесконечно висит в состоянии pending, реплики на разных нодах не видят друг друга, а после падения менеджера кластер отказывается что-либо делать. Эти ошибки Docker Swarm на сервере почти всегда сводятся к сети, портам и кворуму. Разберём их по схеме «симптом — причина — решение».
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →С чего начинать диагностику кластера
Диагностика Swarm начинается с общей картины: состояние нод и сервисов. На ноде-менеджере посмотрите, кто в кластере и в каком статусе:
docker node ls
docker service ls
Если нода в статусе Down или отсутствует — проблема на уровне присоединения или сети. Если сервис показывает меньше запущенных реплик, чем задано, — задачи не размещаются, и нужно смотреть, почему. Детали по конкретному сервису показывают, где именно застряли его задачи и с какой ошибкой:
docker service ps --no-trunc web
Флаг --no-trunc разворачивает полный текст ошибки задачи — часто именно там прямым текстом написана причина, будь то нехватка ресурсов, недоступный образ или ограничение размещения. Держа перед глазами список нод, список сервисов и детальный статус задач, вы локализуете проблему за минуту. Дальше — разбор частых симптомов.
Нода не присоединяется к кластеру
Частый симптом: на воркере выполнили docker swarm join, а он висит или падает по таймауту, и нода не появляется в docker node ls на менеджере. В подавляющем большинстве случаев виноваты закрытые порты между серверами. Swarm использует несколько портов, и все они должны быть открыты в сети между нодами.
Проверьте и откройте нужные порты на всех нодах:
ufw allow 2377/tcp
ufw allow 7946/tcp
ufw allow 7946/udp
ufw allow 4789/udp
Порт 2377 нужен для управления кластером, 7946 (TCP и UDP) — для обмена между нодами, 4789 (UDP) — для overlay-сетей. Забытый порт 7946 или 4789 — типичная причина, по которой нода вроде присоединяется, но потом сеть между репликами не работает. Вторая причина — неверный адрес менеджера в команде join: он должен быть тем приватным IP, который указан в --advertise-addr при инициализации. Третья — протухший или неправильный токен: посмотрите актуальный токен на менеджере командой docker swarm join-token worker и используйте свежую команду присоединения.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPSСервис висит в состоянии pending
Симптом: сервис создан, но реплики не запускаются и остаются в pending или постоянно перезапускаются. Это значит, что Swarm не может разместить задачу ни на одной ноде. Разверните причину детальным статусом:
docker service ps --no-trunc web
Самая частая причина — ограничения размещения (constraints), которым не удовлетворяет ни одна нода. Например, сервис требует ноду с определённой меткой или роли, а таких нод нет. Проверьте, нет ли лишних ограничений в описании сервиса. Вторая причина — образ недоступен: если он лежит в приватном реестре, а ноды не авторизованы, задача не стартует. Для стеков образ должен быть доступен всем нодам, поэтому его либо кладут в общий реестр, либо передают учётные данные при деплое флагом --with-registry-auth.
Третья причина — нехватка ресурсов: если у сервиса заданы резервирования памяти или процессора (reservations), которых нет на нодах, задача не разместится. Либо снизьте требования, либо добавьте ноды. Именно --no-trunc обычно прямо называет, что мешает: «no suitable node», «image not found» или «insufficient resources» — и дальше вы чините конкретную причину.
Overlay-сеть не связывает сервисы
Коварная ошибка: сервисы запущены, реплики Running, но они не видят друг друга по именам, запросы между сервисами не проходят. Проблема почти всегда в overlay-сети и её порте. Overlay-трафик идёт по UDP 4789, и если этот порт закрыт между нодами, реплики на разных нодах оказываются в сетевой изоляции, хотя формально сеть создана.
Убедитесь, что порт открыт, и проверьте саму сеть:
ufw allow 4789/udp
docker network ls
docker network inspect my-overlay
В инспекции overlay-сети должны быть перечислены подключённые к ней контейнеры с разных нод. Если реплики одной ноды общаются, а разных — нет, это почти наверняка блокировка UDP 4789 или конфликт с фаерволом облачного провайдера поверх системного. Вторая тонкость — сервисы должны быть подключены к одной overlay-сети, чтобы находить друг друга по именам; проверьте, что в описании стека все они используют общую сеть. Overlay-сеть, охватывающая ноды, — основа связности в Swarm, и её порт нельзя забывать при настройке фаервола.
Потеря кворума менеджеров
Опасная ситуация: одна из нод-менеджеров упала, и кластер перестал управляться — команды docker service не проходят или зависают. Причина в потере кворума. Менеджеры Swarm принимают решения голосованием, и для кворума нужно большинство. Если менеджеров было два и один упал, большинства нет — кластер замирает в целях безопасности данных.
Отсюда главное правило: всегда держите нечётное число менеджеров — один, три или пять. Три менеджера переживают падение одного, пять — двух. Два менеджера, вопреки интуиции, менее надёжны, чем один, потому что теряют кворум при любом падении. Проверьте состояние менеджеров:
docker node ls
Если кворум потерян и восстановить упавшие менеджеры нельзя, есть аварийная процедура принудительного восстановления кластера с одной оставшейся ноды:
docker swarm init --force-new-cluster
Эта команда пересоздаёт кластер из текущего состояния на живой ноде, после чего можно добавить менеджеры заново до нечётного числа. Применяйте её только как аварийную меру. Правильная профилактика — изначально закладывать три менеджера, и тогда падение одной ноды не выводит кластер из строя.
Профилактика и когда нужен запас
Большинство ошибок Swarm предотвращается на этапе сборки кластера. Откройте все нужные порты между нодами сразу: 2377/tcp, 7946/tcp+udp, 4789/udp — и не забывайте про облачный фаервол провайдера поверх системного. Держите нечётное число менеджеров для устойчивости кворума. Кладите образы в реестр, доступный всем нодам, и деплойте стеки с --with-registry-auth. Проверяйте overlay-связность между разными нодами, а не только внутри одной.
Отдельно про ресурсы и сеть. Swarm чувствителен к задержкам между нодами, поэтому держите их в одной локации — разнесённый по разным дата-центрам кластер работает нестабильно из-за пинга в управлении. И следите за нагрузкой: когда реплик и сервисов становится много, нодам нужен запас по памяти и процессору, иначе задачи начнут вытесняться и висеть в pending. Расширение кластера новыми нодами и апгрейд существующих решают это. У MAATRIX дополнительные VPS в одной локации доступны с оплатой из России картой или криптой, что позволяет наращивать кластер горизонтально без трансграничных задержек и смены провайдера.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPSОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Почему нода не присоединяется к Docker Swarm?
Чаще всего закрыты порты между нодами (2377/tcp, 7946, 4789/udp) или неверный адрес и токен менеджера; откройте порты и используйте свежую команду join.
Из-за чего сервис висит в pending?
Swarm не может разместить задачу: мешают ограничения размещения, недоступный образ или нехватка ресурсов; разверните причину через docker service ps --no-trunc.
Почему сервисы на разных нодах не видят друг друга?
Обычно закрыт UDP 4789 для overlay-трафика или сервисы в разных сетях; откройте порт и подключите их к общей overlay-сети.
Что делать при потере кворума менеджеров?
Держите нечётное число менеджеров (три и более); в аварии восстановите кластер командой docker swarm init --force-new-cluster на живой ноде.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.