
Введение
Введение
При работе с Docker Swarm вы можете столкнуться с ситуацией, когда кластер не может разместить новую реплику сервиса на одной из нод, либо вообще запустить сервис. Это проявляется в логах на одной из менеджер-нод следующим предупреждением:
Mar 03 07:46:32 swarm3 dockerd[875]: time="2025-03-03T07:46:32.123554337Z" level=warning msg="underweighting node nt98wn9he8my6tsuasgkhrrjp for service 86jgkc35ctasmu8ubpnilsrqo because it experienced 5 failures or rejections within 5m0s" module=scheduler node.id=gaip86ri06jyrdwxcogl9j2p5
Эта ошибка означает, что Swarm снижает приоритет использования данной воркер-ноды при размещении задач сервиса, так как на ней зафиксировано 5 отказов или ошибок за последние 5 минут. В этой статье разберем причины возникновения проблемы, способы диагностики и методы решения.
Причины ошибки
Основные причины, по которым Swarm "понижает вес" ноды:
-
Ошибка или сбой на узле – например, нехватка ресурсов, проблемы с сетью, падение агента Swarm.
-
Предыдущие неудачные попытки запуска контейнера – если на этой ноде несколько раз подряд не удалось запустить контейнер, Swarm временно исключает её из списка кандидатов.
-
Ограничения по ресурсам – если контейнеру требуются ресурсы (CPU, память, диск), которых нет на узле, Swarm не сможет туда его запланировать.
-
Тайм-ауты в сети – если нода не отвечает или связь с ней нестабильная, Swarm может игнорировать её при планировании.
-
Аппаратные сбои или проблемы с Docker Daemon – если на ноде происходят сбои оборудования или сам докер-демон работает нестабильно, это может приводить к отказам выполнения задач.
-
Недостаточно нод-воркеров для запуска требуемого количества реплик – если кластер недостаточно велик, Swarm не сможет запустить вторую и последующие реплики сервиса.
-
Недостаточно нод-воркеров с заранее навешанным на неё лейблом, который соответствует лейблам запускаемого сервиса, хотя при этом количество воркеров может быть достаточным для запуска.
-
Ошибки внутри самого сервиса – если контейнер завершает работу с ошибкой или не проходит проверку работоспособности (health check), Swarm будет пытаться перезапустить его, что может привести к серии отказов.
Диагностика проблемы
Для выявления узла, который не принимает реплику, и сервиса, к которому она относится, выполняем следующие шаги:
1. Проверка статуса нод
Сначала смотрим, какие ноды участвуют в кластере и в каком они состоянии:
docker node ls
Если одна из нод в статусе Down или Unreachable, скорее всего, она и является проблемной. Смотрим, к какой ноде относится проблема по ID из ошибки:
docker node ls | grep nt98wn9he8my6tsuasgkhrrjp
2. Проверка статуса задач
Для диагностики того, к какому сервису относится проблема, можно выполнить команду с фильтрацией по первым 12 символам ID сервиса, взятых из ошибки:
docker service ls | grep 86jgkc35ctas
Теперь посмотрим, какие задачи (tasks) не могут запуститься:
docker service ps 86jgkc35ctasmu8ubpnilsrqo
Здесь можно увидеть, на какой ноде не удалось запустить задачу и возможную причину (Rejected, Shutdown, No suitable node).
Также стоит проверить, использует ли сервис определённые лейблы для размещения на нодах. Если у сервиса в .yml-файле задано ограничение на запуск только на нодах с определённым лейблом, но таких нод недостаточно для запуска всех реплик, это также может привести к невозможности запуска этих реплик, даже если общее количество воркер-нод достаточно.
Проверить используемые лейблы можно так:
docker service inspect 86jgkc35ctasmu8ubpnilsrqo --format '{{json .Spec.TaskTemplate.Placement}}' | jq .
А затем посмотреть, какие ноды имеют нужный лейбл:
docker node ls --filter label=<LABEL_KEY>=<LABEL_VALUE>
Пример:
docker node ls --filter "label=cli=1"
3. Проверка доступных ресурсов на проблемной ноде
Если мы определили ноду, попробуем посмотреть её состояние:
docker node inspect nt98wn9he8my6tsuasgkhrrjp --format '{{json .Description.Resources}}' | jq .
Пример ответа:
{
"NanoCPUs": 16000000000,
"MemoryBytes": 16771465216
}
А также загрузку ресурсов:
top -o %CPU # нагрузка по CPU
free -m # доступная память
df -h # свободное дисковое пространство
4. Проверка логов Swarm
Лог событий Swarm может помочь выявить корневую причину:
journalctl -f -u docker --since "10m ago"
5. Проверка сетевого соединения
Если подозреваем сетевые проблемы, попробуем проверить соединение с менеджер-ноды:
ping <IP_проблемной_ноды>
telnet <IP_проблемной_ноды> 2377
Решение проблемы
Для решения проблемы переполнения истории завершенных задач Docker Swarm, основными шагами будут следующие:
1. Добавить лейблы на воркер-ноды
Если на некоторых нодах отсутствуют необходимые лейблы, добавьте их в соответствии с количеством реплик (например, лейбл cli=1). Это поможет улучшить планирование задач и предотвратить переполнение истории задач на ненужных нодах.
Пример добавления лейбла:
docker node update --label-add cli=1 <NODE_ID>

2. Уменьшить количество реплик для сервиса в конфигурационном файле .yml
Чтобы снизить нагрузку на кластер и убрать ошибку о неудачных попытках запуска реплик, можно уменьшить количество реплик для сервиса в конфигурационном файле .yml. Это поможет избежать переполнения истории завершенных задач.
Пример уменьшения реплик:
deploy:
replicas: 2 # Уменьшите количество реплик
Второстепенные решения
Если вышеописанные шаги не решат проблему, можно использовать следующие подходы:
3. Нехватка ресурсов
-
Освободите место на диске:
docker system prune -a
-
Перенастройте сервис с меньшими требованиями:
docker service update --limit-cpu 0.5 --limit-memory 512M 86jgkc35ctasmu8ubpnilsrqo

4. Перезапуск Docker-агента на проблемной ноде
systemctl restart docker
Или перезагрузка всей ноды:
reboot
5. Выключение проблемной ноды (временное решение)
docker node update --availability drain nt98wn9he8my6tsuasgkhrrjp
Это исключит её из планирования задач, пока проблема не решена.
6. Переподключение ноды к кластеру
Если проблема не решается, можно попробовать удалить ноду и добавить её заново (выполняется на manager-ноде):
docker swarm leave --force
docker swarm join --token <TOKEN> <MANAGER_IP>:2377
7. Обновление Docker (если используется старая версия)
apt update && apt upgrade -y docker-ce
Заключение
Ошибка underweighting node for service в Docker Swarm обычно вызвана проблемами с ресурсами, сетью, предыдущими сбоями контейнеров, а также нехваткой нод-воркеров или ошибками внутри самого сервиса. Мы разобрали основные шаги диагностики и способы исправления ошибки. Если проблема сохраняется, рекомендуется проверить логи, обновить Docker и, при необходимости, исключить проблемную ноду из кластера.
Автор: dtiumentsev