Проблема запуска реплик в Docker Swarm: диагностика и решения

в 7:15, , рубрики: container, devops, docker, docker swarm, linux, problem solving, underweighting
Проблема запуска реплик в Docker Swarm: диагностика и решения - 1

Введение

Введение

При работе с 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 "понижает вес" ноды:

  1. Ошибка или сбой на узле – например, нехватка ресурсов, проблемы с сетью, падение агента Swarm.

  2. Предыдущие неудачные попытки запуска контейнера – если на этой ноде несколько раз подряд не удалось запустить контейнер, Swarm временно исключает её из списка кандидатов.

  3. Ограничения по ресурсам – если контейнеру требуются ресурсы (CPU, память, диск), которых нет на узле, Swarm не сможет туда его запланировать.

  4. Тайм-ауты в сети – если нода не отвечает или связь с ней нестабильная, Swarm может игнорировать её при планировании.

  5. Аппаратные сбои или проблемы с Docker Daemon – если на ноде происходят сбои оборудования или сам докер-демон работает нестабильно, это может приводить к отказам выполнения задач.

  6. Недостаточно нод-воркеров для запуска требуемого количества реплик – если кластер недостаточно велик, Swarm не сможет запустить вторую и последующие реплики сервиса.

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

  8. Ошибки внутри самого сервиса – если контейнер завершает работу с ошибкой или не проходит проверку работоспособности (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>

Проблема запуска реплик в Docker Swarm: диагностика и решения - 2

2. Уменьшить количество реплик для сервиса в конфигурационном файле .yml

Чтобы снизить нагрузку на кластер и убрать ошибку о неудачных попытках запуска реплик, можно уменьшить количество реплик для сервиса в конфигурационном файле .yml. Это поможет избежать переполнения истории завершенных задач.

Пример уменьшения реплик:

deploy:
  replicas: 2  # Уменьшите количество реплик

Второстепенные решения

Если вышеописанные шаги не решат проблему, можно использовать следующие подходы:

3. Нехватка ресурсов

  • Освободите место на диске:

    docker system prune -a
  • Перенастройте сервис с меньшими требованиями:

    docker service update --limit-cpu 0.5 --limit-memory 512M 86jgkc35ctasmu8ubpnilsrqo
Проблема запуска реплик в Docker Swarm: диагностика и решения - 3

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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js