При развертывании Portainer в кластере Docker Swarm на виртуальных машинах VMware мы столкнулись с неочевидной проблемой. Portainer сообщал о недоступности агентов, хотя ICMP-запросы проходили без проблем. Оверлей-сеть работала со сбоями — сервис публиковал порт на всех нодах, но реально отвечал только на той, где находился контейнер. При этом в логах не было ничего, кроме сообщений о недоступности агентов. Разбираемся, в чем дело и как это исправить.
Симптомы: всё работает, но не так, как надо
Проблема воспроизводилась в разных окружениях:
- RedOS на VMware
- Ubuntu 24.04 на vSphere
- Ubuntu 22 + Docker-CE (из официального репозитория Docker) на VMware
При этом в конфигурации Ubuntu 22 + Docker.io (из репозитория Ubuntu) проблема не проявлялась. Это важно — различия в сборках Docker могут влиять на поведение сетевого стека.
Классические признаки неисправности оверлейной сети:
- Агенты Portainer недоступны, хотя пинг до них проходит.
- Routing mesh работает некорректно — запросы на опубликованный порт достигают цели, только если контейнер находится на той же ноде.
- Логи не дают никаких подсказок — даже на дебаг-уровне.
Погуглили:
- https://docs.portainer.io/sts/faqs/known-issues/known-issues-with-vmware
- https://forums.docker.com/t/unable-to-access-swarm-services-from-other-node-ip-via-routing-mesh/146676/3
- https://stackoverflow.com/questions/43933143/docker-swarm-overlay-network-is-not-working-for-containers-in-different-hosts?rq=1#1
- https://github.com/coreos/fedora-coreos-tracker/issues/1372
Анализ проблемы и обсуждения в сообществе указывают на две основные причины, связанные с особенностями работы VMware.
1. Конфликт портов с VMware NSX
Docker Swarm по умолчанию использует UDP-порт 4789 для передачи данных оверлейной сети (VXLAN) . Этот же порт используется VMware NSX для своих нужд. В результате трафик, направленный на порт 4789, может молча отбрасываться .
Если вы используете NSX в среде VMware, вы, вероятно, столкнетесь с проблемами оверлейной сети Docker. В частности, оверлейная сеть по умолчанию использует UDP-порт 4789, который конфликтует с портом VXLAN VMware NSX.
Эта проблема возникает даже без NSX — ESXi может сбрасывать исходящие пакеты от виртуальных машин на порт, совпадающий с портом VTEP.
2. Проблемы с контрольными суммами (checksum offloading)
Вторая, еще более коварная причина — неправильный расчет контрольных сумм при аппаратном ускорении.
При работе Docker Swarm под VMware могут возникать проблемы с маршрутизацией через mesh. Мы выяснили, что это связано с отбрасыванием UDP-пакетов на исходной ноде. Отключение checksum offloading решает проблему.
В документации Portainer прямо указывается, что это наблюдается на RedHat-подобных системах, включая CentOS и Photon OS, а также иногда на Ubuntu .
Broadcom в своем знании подтверждает: проблема возникает с VMXNET3, но не с E1000. Двойная инкапсуляция (VXLAN от Docker + Geneve от NSX) приводит к тому, что контрольные суммы внутренних TCP-заголовков не пересчитываются корректно, и пакеты отбрасываются.
Как мы решили проблему
Смена data-path-port
Наиболее простое решение, которое сработало для RedOS — использование нестандартного порта для данных оверлейной сети. Вместо 4789 мы указали, например, 36564.
docker swarm init --data-path-port=36564Этот подход рекомендован и в документации Portainer, и в обсуждениях на Stack Overflow. Нам помогло.
Важно: Если кластер уже инициализирован, его придется пересоздать.
Отключение checksum offloading
Если смена порта не дает результата (как в некоторых случаях на Ubuntu с Docker-CE), помогает отключение checksum offloading.
На всех нодах кластера выполните:
ethtool -K [имя_интерфейса] tx-checksum-ip-generic offНапример, для интерфейса ens160:
ethtool -K ens160 tx-checksum-ip-generic offВ некоторых случаях также рекомендуют отключать tx-udp_tnl-segmentation и tx-udp_tnl-csum-segmentation:
ethtool -K eth0 tx-udp_tnl-segmentation off tx-udp_tnl-csum-segmentation offПосле изменения настроек может потребоваться перезапуск сервисов, использующих оверлейную сеть .
Важно: Изменения, внесенные через ethtool, действуют только до перезагрузки сервера. Для постоянного применения добавьте команду в скрипты автозагрузки сети.
Почему Docker.io работал, а Docker-CE — нет?
Гипотеза: различия в сборках Docker.
Docker-CE из официального репозитория может использовать более агрессивные оптимизации сетевого стека или иметь иные настройки по умолчанию, которые вступают в конфликт с особенностями VMXNET3. Docker.io из репозитория Ubuntu собран с другими параметрами, которые «дружелюбнее» к виртуальной среде VMware.
Выводы и рекомендации
Проблемы с оверлейными сетями Docker Swarm на VMware — известный, но не всегда очевидный кейс. Основные причины:
- Конфликт портов с VMware NSX или ограничениями ESXi на использование порта 4789.
- Ошибки контрольных сумм из-за взаимодействия VMXNET3 и аппаратной оптимизации.
Практические шаги для устранения:
- Попробуйте сменить --data-path-port при инициализации Swarm. Это просто и часто решает проблему.
- Если не помогает — отключите checksum offloading через ethtool на всех нодах.
- Помните, что изменения через ethtool временны — добавьте их в автозагрузку.
Если вы сталкивались с похожей проблемой или знаете другие способы решения — делитесь в комментариях. Возможно, ваш опыт поможет другим избежать долгих часов дебага.
