Если у меня есть Docker Swarm с несколькими узлами, подключенный к определенной пользователем оверлейной сети, и служба A пытается связаться со службой B, где служба B имеет несколько реплик, какая реплика получит сообщение? Я понимаю, что сетка маршрутизации - это входящий поток, но что-то подобное должно произойти и в этом случае, верно?
Проходит ли межсервисное взаимодействие Docker Swarm через сетку маршрутизации?
Ответы (2)
По умолчанию docker настраивает каждую службу с виртуальным IP-адресом (VIP), который реализуется с помощью ipvs в ядре. Это выполняет циклическую балансировку нагрузки между каждой репликой службы для каждого отдельного сетевого подключения (постоянные сетевые подключения будут оставаться подключенными к одной и той же реплике в течение всего срока службы этого TCP-подключения).
Когда перенаправляемый IP-адрес находится на другом узле, он использует оверлейную сеть, реализованную vxlan в ядре, для отправки этих пакетов другим узлам. Если что-то в сети блокирует оверлейные сетевые порты, вы увидите проблемы с их работой. В документации Docker есть необходимые порты:
- TCP-порт 2377 для обмена данными по управлению кластером
- TCP и UDP порт 7946 для связи между узлами
- UDP-порт 4789 для оверлейного сетевого трафика
Я часто отлаживаю проблемы с подключением, используя tcpdump на каждом узле, чтобы увидеть, получены ли пакеты, отправленные с одного узла, в пункт назначения. И при необходимости порт оверлея можно изменить с помощью флага docker swarm init --data-path-port
при инициализации кластера роя.
Я предпочитаю использовать оверлейную сеть по умолчанию в большинстве сценариев, поскольку она устраняет целый класс проблем с кэшированием DNS. Если вы используете циклический перебор DNS, каждый контейнер в кластере Swarm может кэшировать результаты DNS для реплик вашей службы и взаимодействовать со старыми IP-адресами, используемыми этой службой, до тех пор, пока кэшированный результат DNS сохраняется в приложении этого контейнера. Это может привести к значительному простою во время непрерывного обновления, пока вы ждете, пока приложение обновит свои результаты DNS для выбранного контейнера. Хотя я сталкивался с проблемами с ipvs в прошлом, я не встречал их в последних версиях docker с новым ядром, и тот же модуль ядра сейчас используется многими поставщиками сетевых ресурсов Kubernetes, что приводит к гораздо большему тестированию и стабильности.
Если вы хотите получить отдельные IP-адреса для реплик службы или использовать DNS RR, вы можете сделать это на разовой основе, не отключая VIP-адрес службы. Вместо этого, если бы вы запросили web
виртуальный IP-адрес веб-службы, вы могли бы запросить tasks.web
DNS RR всех реплик этой службы (заменив web
именем вашей службы). Я делал это только тогда, когда у меня есть приложения, которым нужно запускать команду для каждой реплики, и я вижу, как это может быть полезно для липких сеансов.
Что касается того, как это относится к входящей сети и сервисной сети, входящая сеть настроена для маршрутизации определенного порта к этому виртуальному IP-адресу входящей сети на каждом узле в кластере. Вы увидите VIP для каждой оверлейной сети, к которой подключена служба, включая входящую сеть, если у вас есть опубликованные порты, когда вы запустите docker network inspect -v ...
в своей сети.
Единственный раз, когда я рассматриваю возможность отключения входящей сети, - это если у меня есть глобальная служба, кластер с одним узлом или служба, работающая в предсказуемом списке узлов, и я хочу избежать дополнительных сетевых переходов, добавляемых сеткой служб. В этих сценариях я публикую порт в режиме "хоста" (см. длинный синтаксис для публикации портов). Это предотвратит запуск более одной реплики на узле, но в большинстве моих случаев использования это для приложения с отслеживанием состояния, где несколько реплик не имеют смысла.
По сути, существует 2 режима конечной точки:
dnsrr
=> IP-адреса контейнера разрешения DNS службыdefault
=> служба разрешения DNS роутера входящего трафика
Маршрутизатор Swarm - чистый *****, у него много сетевых проблем (тайм-аут, нет маршрута к хосту, зомби).
dnsrr
предоставит IP-адреса всех контейнеров, это круто, но это может вызвать проблемы с кешем DNS (logstash, клиент Php AMQP ...):
"Служба A имеет DNS-кеш на X секунд, она может взаимодействовать с контейнером B.1. Сбой контейнера B.1, повторное создание с другим IP ==> служба A все еще отправляет на прежний IP"
Также будьте осторожны в случае контейнера с несколькими сетями.