Назад | Перейти на главную страницу

Время ожидания сетки маршрутизации роя докеров истекло

У меня есть две машины, работающие на Ubuntu 18.04 с установленной на них Docker версии 18.09.9. Я установил ройный кластер, в котором узел-менеджер объявляет свой общедоступный IP-адрес, а рабочий узел - свой частный IP-адрес:

// On manager
docker swarm init --advertise-addr INSTANCE_PUBLIC_IP

// On worker
docker swarm join --advertise-addr INSTANCE_PRIVATE_IP --token XXXXXX MANAGER_PUBLIC_IP:2377

Две машины работают в одной частной сети, и менеджер может подключаться к частному IP-адресу рабочего. Рой в основном работает, я могу развертывать службы, видеть входящую сеть на обоих узлах и т.д., но когда я развертываю службу, контейнер которой находится на рабочем узле, я не могу связаться с ней через узел диспетчера. Время ожидания соединения истекло. От рабочего узла соединение установлено успешно.

Однако если я заставлю рабочий узел рекламировать свой общедоступный IP-адрес, все будет работать хорошо. Узлы размещены в Digitalocean, вы знаете, откуда взялась эта проблема?

Относится к Истекло время ожидания соединений с сеткой маршрутизации Docker Swarm.

Я наконец-то понял ! Проблема заключалась не в закрытых портах или неправильной настройке, а во внутреннем устройстве Digitalocean с точки зрения сети.

Они устанавливают NAT между общедоступным и частным IP-адресами экземпляров. Оказывается, подключение p2p через NAT не очень хорошо сочетается. Как указано в этом комментарии (https://github.com/docker/swarmkit/issues/1429#issuecomment-361924332):

Ключ в том, чтобы иметь прямое соединение (без NAT на пути) от рабочего узла к управляющему узлу и наоборот.

На этой странице также упоминаются потенциальные проблемы и ограничения NAT: https://en.wikipedia.org/wiki/Network_address_translation#Issues_and_limitations

В нем говорится: «Если маршрутизатор NAT не приложит особых усилий для поддержки таких протоколов, входящие пакеты не смогут достичь места назначения».

Так что, даже если вы можете в конечном итоге полностью использовать рой через систему NAT, я бы не рекомендовал этого делать.

Обычно это результат того, что брандмауэр блокирует оверлейные сетевые порты vxlan между хостом. Вы хотите открыть следующее:

  • 2377 / tcp: связь с менеджером роя
  • 7946 / tcp + udp: оверлейный порт управления сетью
  • 4789 / udp: оверлейный сетевой порт данных
  • протокол 50: требуется, только если вы включили безопасность в оверлейной сети.

При использовании iptables на каждом узле кластера роя вам потребуется следующее:

iptables -A INPUT -p tcp -m tcp --dport 2377 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 7946 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 7946 -j ACCEPT
iptables -A INPUT -p tcp -m udp --dport 4789 -j ACCEPT
iptables -A INPUT -p 50 -j ACCEPT

Обратите внимание, что некоторые инструменты, в частности VMWare NSX, блокируют порты vxlan.