Зачем вообще IPVS в Docker Swarm
В Docker Swarm есть два ключевых обещания, которые выглядят магией, пока не начнёшь дебажить: сервис доступен по одному адресу (VIP), и запросы автоматически распределяются по таскам (репликам) даже если клиент попал на «не тот» узел.
Эту магию в режиме по умолчанию (endpoint-mode vip) делает связка ingress routing mesh + IPVS (L4-балансировщик ядра Linux). На каждом узле Swarm появляется виртуальный сервисный IP (VIP) для каждого сервиса, а IPVS держит таблицу «виртуальный сервис → реальные эндпоинты (IP тасков)».
Важно: Swarm не строит L7-балансировку. IPVS работает на L4 (TCP/UDP), и это определяет поведение таймаутов, «прилипания» соединений и диагностики: вы смотрите не на заголовки HTTP, а на сокеты, conntrack и маршрутизацию.
Архитектура: что такое VIP, ingress и overlay в одном абзаце
У Swarm есть overlay-сети для контейнеров и специальная сеть ingress для routing mesh (когда вы публикуете порт сервиса). Пакеты между узлами обычно инкапсулируются (VXLAN), а для доступа снаружи используется опубликованный порт на каждом узле. Дальше локальные правила netfilter перенаправляют трафик на VIP, а IPVS выбирает конкретный таск (контейнер) и отправляет туда.
Практический вывод: если «сервис не открывается», проверять нужно не только контейнер и порт внутри него, но и цепочку host firewall → iptables/nft → IPVS → overlay → conntrack.
Если вы хотите глубже разобраться, как Docker взаимодействует с фильтрацией, полезно держать под рукой разбор про iptables-nftables и docker-цепочки: это часто ускоряет поиск «кто именно дропает пакет».

Как проходит пакет: путь запроса через routing mesh
Сценарий 1: опубликованный порт (ingress routing mesh)
Вы сделали публикацию порта сервиса, например:
docker service create --name web --publish published=80,target=80 nginx:alpine
Теперь порт 80 слушается на каждом узле Swarm (даже там, где нет таска). Типовой путь TCP-пакета такой:
- Пакет приходит на интерфейс узла (например, публичный).
- Правила в netfilter (часто через
iptables-nftна современных дистрибутивах) перенаправляют трафик на внутренний VIP сервиса. - IPVS выбирает реальный эндпоинт (IP таска в overlay-сети) и делает DNAT на этот адрес/порт.
- Дальше пакет уходит либо в локальный контейнер, либо через VXLAN на другой узел, где живёт нужный таск.
- Обратный трафик проходит обратно, используя состояние в
conntrack.
Если вы понимаете, на каком шаге «обрывается» цепочка, вы почти всегда быстро находите причину.
Сценарий 2: сервис внутри overlay без published-портов
Если порт не опубликован, ingress-сеть не участвует. Сервис доступен только внутри overlay через VIP (или через DNSRR). Клиентский контейнер обращается к имени сервиса, Docker DNS возвращает VIP, и IPVS на узле клиента раскидывает трафик по эндпоинтам.
Это важный момент: IPVS работает не только для «внешнего» ingress. Он участвует и в межсервисном взаимодействии внутри кластера, если выбран vip.
VIP vs DNSRR: что выбрать и почему
В Swarm у сервиса есть режим endpoint (endpoint-mode):
- VIP (по умолчанию) — имя сервиса резолвится в один виртуальный IP, балансировка на L4 делает IPVS.
- DNSRR — имя сервиса резолвится в список IP тасков, балансировка происходит на стороне клиента (кто как умеет).
Когда VIP удобнее
- Нужна предсказуемость: один адрес на сервис, не важно сколько тасков.
- Клиенты «простые»: не умеют балансировать список A-записей или делают это плохо.
- Нужно, чтобы запрос мог прийти на любой узел (routing mesh) и всё равно нашёл таск.
Когда лучше DNSRR
- Нужен контроль балансировки на уровне приложения/клиента (например, gRPC/HTTP-клиенты с собственной стратегией).
- Есть проблемы с
conntrack/IPVS на высоких нагрузках и вы хотите упростить dataplane. - Нужно избежать «лишнего хопа» через mesh и ходить напрямую к таскам (часто вместе с внешним L7/L4 балансировщиком).
Подводные камни VIP
- Состояние соединений живёт в
conntrack: при переполнении таблиц начинаются «странные» таймауты и сбросы. - Диагностика сложнее: DNS резолвит VIP, но трафик не доходит из-за фильтрации или проблем overlay.
IPVS на практике: что смотреть через ipvsadm
Для диагностики полезно видеть таблицу IPVS. Обычно достаточно пакета ipvsadm на узле:
sudo ipvsadm -Ln
Вы увидите виртуальные сервисы (VIP:port) и реальные серверы (IP тасков:port), а также счётчики соединений/пакетов. Это один из самых быстрых способов понять: Swarm вообще «видит» эндпоинты или балансирует «в пустоту».
Полезные варианты:
sudo ipvsadm -Ln --stats
sudo ipvsadm -Ln --rate
Если VIP есть, но реальных серверов нет, причины обычно такие: таски не прикрепились к сети, сервис не в нужной overlay, на конкретном узле отвалился агент Docker (или есть проблемы с обменом состоянием между нодами).
conntrack: почему он важен для ingress и overlay
conntrack — подсистема отслеживания состояний соединений в netfilter. Swarm с VIP/ingress активно использует NAT-подобную механику (DNAT для выбора конкретного endpoint), а значит, состояние соединения в таблице conntrack становится критичным ресурсом.
Типовые симптомы проблем conntrack:
- случайные
timeoutпри подключении к сервису при общей «здоровости» контейнеров; - часть узлов «не пробрасывает» трафик, часть — пробрасывает;
- после всплеска нагрузки всё «чинится» только перезапуском docker/ноды (потому что очищается состояние).
Быстрая проверка состояния conntrack
sudo sysctl net.netfilter.nf_conntrack_count
sudo sysctl net.netfilter.nf_conntrack_max
Если nf_conntrack_count близок к nf_conntrack_max, вы в зоне риска. В логах ядра при этом часто появляются сообщения о переполнении.
Чтобы посмотреть статистику (нужен пакет conntrack-tools):
sudo conntrack -S
sudo conntrack -L | head
Лечить тут лучше не «очисткой таблицы», а причинами: лимиты, таймауты, лишний mesh/NAT, агрессивные клиенты, шторма переподключений.
iptables-nft и Swarm: почему правила выглядят непривычно
На новых системах iptables часто является совместимым фронтендом к nftables (режим iptables-nft). Docker/Swarm добавляют много правил в таблицы NAT/FILTER: это нормально, но усложняет понимание, кто именно «съел» пакет.
Для первичного аудита правил:
sudo iptables -t nat -S
sudo iptables -S
Если у вас nftables как основной firewall, полезно смотреть реальную nft-конфигурацию:
sudo nft list ruleset
Частая ошибка — политика DROP на FORWARD без разрешений для docker-интерфейсов, из-за чего VXLAN или форвардинг трафика ломаются «наполовину».
Overlay network troubleshooting: чеклист, который экономит часы
1) Проверить состояние нод и задач
docker node ls
docker service ls
docker service ps <service>
Сначала убедитесь, что таски реально запущены и не в перманентном рестарте.
2) Проверить сети и привязки
docker network ls
docker network inspect ingress
docker service inspect <service>
В инспекте сервиса смотрите EndpointSpec, Ports, Mode, VirtualIPs.
3) Проверить IPVS-таблицу на проблемной ноде
sudo ipvsadm -Ln
sudo ipvsadm -Ln --stats
Сравните ноды: если на одной ноде VIP «пустой», а на другой заполнен, ищите расхождение в состоянии агента Docker, проблемы с обменом в кластере или фильтрацию.
4) Проверить MTU и VXLAN-путь
Overlay часто ломается из-за MTU: если подложка (провайдерская сеть, туннель, VLAN) режет MTU, VXLAN-пакеты начинают фрагментироваться или теряться. Симптомы: DNS работает, SYN уходит, ответы не возвращаются, или «зависают» большие ответы.
ip link show
ip -d link show | grep -i vxlan -n
Если есть подозрения, тестируйте размер пакета и DF аккуратно и в рамках вашей сети (особенно на проде).
5) Смотреть счётчики и дропы
sudo ip -s link
sudo ss -s
sudo nstat -az | head
Дальше уже точечно: tcpdump на интерфейсах, проверка nft/iptables счётчиков, поиск, где теряется трафик.

Типовые поломки VIP/ingress и как их распознать
Проблема: порт опубликован, но доступность «через раз»
Чаще всего это:
- переполненный
conntrack; - асимметричная маршрутизация или фильтрация между узлами (часть VXLAN-потока режется);
- firewall режет FORWARD или UDP-трафик overlay.
Начинайте со сравнения ipvsadm и nf_conntrack_count на «хорошей» и «плохой» ноде.
Проблема: внутри кластера имя сервиса резолвится, но соединение не устанавливается
Если VIP есть, но коннект не идёт:
- проверьте, что клиент и сервис в одной overlay-сети (или есть корректная связность);
- проверьте, что таски реально слушают порт внутри контейнера;
- проверьте, что нет конфликтующих правил nft/iptables для docker-интерфейсов.
Проблема: DNSRR включили, стало хуже
DNSRR переносит балансировку на клиента. Некоторые клиенты кэшируют DNS слишком агрессивно, не умеют равномерно распределять, или «прилипают» к первому IP. В итоге часть тасков перегружена, часть простаивает. Для DNSRR почти всегда нужна осознанная стратегия на стороне клиента и понимание кэшей/TTL.
Практические рекомендации для продакшена
Выбирайте endpoint-mode осознанно
- Если вам важна простота и единая точка входа внутри кластера — оставляйте VIP.
- Если у вас сложные клиенты или свой балансировщик и вы хотите избежать mesh — рассматривайте DNSRR, но тестируйте поведение клиентов под отказами.
Следите за conntrack как за ресурсом
conntrack — это такая же ёмкость, как память или файловые дескрипторы. На высоких RPS и большом количестве коротких соединений он заканчивается внезапно. В мониторинг стоит вынести nf_conntrack_count и долю от nf_conntrack_max.
Фиксируйте firewall-модель
Либо nftables с понятной интеграцией, либо аккуратные правила вокруг Docker. Самая дорогая по времени ситуация — когда «иногда не работает», а правила менялись несколькими руками и без счётчиков/логирования.
Не усложняйте периметр без нужды
Если кластер живёт на отдельных серверах, убедитесь, что базовая сеть стабильна (MTU/маршрутизация) и что у нод предсказуемая L3-связность. Для таких задач чаще удобнее выделенные ресурсы на VDS, где вы контролируете сетевые и firewall-настройки на уровне ОС.
Мини-справочник команд для дежурного инженера
Минимум, который обычно нужен при инцидентах с VIP/ingress:
docker service ps <service>
docker service inspect <service>
docker network inspect ingress
sudo ipvsadm -Ln
sudo ipvsadm -Ln --stats
sudo sysctl net.netfilter.nf_conntrack_count
sudo sysctl net.netfilter.nf_conntrack_max
sudo conntrack -S
sudo iptables -t nat -S
sudo nft list ruleset
ip route
ip link show
sudo ss -lntup
Итоги
Swarm ingress network и VIP-режим — это не просто «публикация порта», а полноценный dataplane на базе netfilter и IPVS. Пока всё работает, это удобно. Когда начинаются проблемы, почти всегда виноваты три класса причин: overlay-связность (часто MTU/UDP/форвардинг), firewall (iptables-nft/nftables) и ресурс conntrack.
Если выстроить привычку смотреть ipvsadm, состояние conntrack и правила фильтрации на проблемной ноде, то большинство инцидентов с swarm VIP/ingress диагностируются за 10–20 минут, а не «перезапуском всего наугад».


