контейнер docker swarm подключается к порту хоста

У меня есть ройный кластер, в котором я создал глобальную службу для запуска на всех хостах докеров в кластере.

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

Для получения дополнительной информации я следую Docker Daemon Metrics руководство по предоставлению нового API метрик докеров на всех хостах и ​​последующему проксированию порта хоста в оверлейную сеть, чтобы Prometheus мог собирать метрики со всех хостов роя.

Я прочитал несколько проблем с докером на github # 8395 # 32101 # 32277 # 1143 - исходя из этого, я понимаю, что изложено в Docker Daemon Metrics. Чтобы подключиться к хосту из контейнера роя, я должен использовать сеть docker-gwbridge, которая по умолчанию 172.18.0.1.

Каждый контейнер в моем рое имеет сетевой интерфейс для сети docker-gwbridge:

326: eth0@if327: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue
    link/ether 02:42:0a:ff:00:06 brd ff:ff:ff:ff:ff:ff
    inet 10.255.0.6/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.255.0.5/32 scope global eth0
       valid_lft forever preferred_lft forever 
333: eth1@if334: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:12:00:04 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.4/16 scope global eth1
       valid_lft forever preferred_lft forever

Кроме того, каждый контейнер в рое имеет маршрут по умолчанию через 172.0.0.1:

/prometheus # ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }' 
172.18.0.1
/prometheus # netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'
172.18.0.1
/prometheus # ip route
default via 172.18.0.1 dev eth1
10.0.1.0/24 dev eth2  src 10.0.1.9
10.255.0.0/16 dev eth0  src 10.255.0.6
172.18.0.0/16 dev eth1  src 172.18.0.4

Несмотря на это, я не могу связаться с 172.18.0.1 из контейнера:

/ # wget -O- 172.18.0.1:4999
Connecting to 172.18.0.1:4999 (172.18.0.1:4999)
wget: can't connect to remote host (172.18.0.1): No route to host

На хосте я могу получить доступ к API метрик докеров на 172.18.0.1. Я могу пинговать и могу выполнить успешный HTTP-запрос.

  1. Может ли кто-нибудь пролить свет на то, почему это не работает изнутри контейнера, как указано в Docker Daemon Metrics?
  2. Если у контейнера есть сетевой интерфейс в сети 172.18.0.1 и маршруты, настроенные для 172.18.0.1, почему эхо-запросы не проходят до 172.18.0.1 изнутри контейнера?
  3. Если это недопустимый подход для доступа к порту хоста из контейнера роя, то как можно этого добиться?

РЕДАКТИРОВАТЬ: только что понял, что я не дал всю информацию в исходном сообщении. Я запускаю docker swarm на хосте CentOS 7.2 с версией docker 17.04.0-ce, сборка 4845c56. Мое ядро ​​- это сборка 4.9.11 с включенными модулями vxlan и ipvs.

После некоторых дополнительных поисков я заметил, что это проблема с брандмауэром. Я обнаружил, что я не только не смог проверить связь с 172.18.0.1 из контейнеров, но и вообще не смог проверить связь с моей хост-машиной! Я попробовал свое доменное имя, полное доменное имя для сервера и даже его общедоступный IP-адрес, но контейнер не смог проверить связь с хостом (есть доступ к сети, поскольку я могу проверить связь с google и т. Д.).

Я отключил firewalld на своем хосте, а затем перезапустил демон докеров. После этого я смог проверить связь с моим хостом из контейнеров (как доменное имя, так и 172.18.0.1). К сожалению, это не решение для меня. Мне нужно определить, какие правила брандмауэра мне нужно установить, чтобы разрешить связь между контейнером и хостом без отключения брандмауэра.


person Andrew Butler    schedule 09.04.2017    source источник


Ответы (1)


Во-первых, я должен вам огромное СПАСИБО. Прежде чем я прочитал вашу часть EDIT, я потратил буквально день и ночь, чтобы решить подобную проблему, и никогда не осознавал, что дьявол - это брандмауэр.

Не отключая брандмауэр, я решил свою проблему на Ubunt 16.04, используя sudo ufw allow in on docker_gwbridge sudo ufw allow out on docker_gwbridge sudo ufw enable

Я не очень хорошо знаком с CentOS, но считаю, что следующее должно вам помочь или, по крайней мере, служить подсказкой sudo firewall-cmd --permanent --zone=trusted --change-interface=docker_gwbridge sudo systemctl restart firewalld Возможно, вам также придется перезапустить докер.

person Aragorn Yang    schedule 12.12.2017