docker 群容器连接到主机端口

docker swarm container connect to host port

我有一个 swarm 集群,我在集群中的所有 docker 主机上为 运行 创建了一个全局服务。

目标是让此服务的每个容器实例连接到侦听 docker 主机的端口。

有关更多信息,我正在按照此 Docker Daemon Metrics 指南在所有主机上公开新的 docker 指标 API,然后将该主机端口代理到覆盖网络中,以便 Prometheus可以从所有 swarm 主机上抓取指标。

我读了好几期dockergithub期#8395#32101# 32277 #1143 - 由此我的理解与Docker Daemon Metrics中概述的相同。为了从 swarm 容器内连接到主机,我应该使用默认为 172.18.0.1.

的 docker-gwbridge 网络

我群中的每个容器都有一个用于 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

此外,swarm 中的每个容器都有一个默认路由,即通过 172.0.0.1:

/prometheus # ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print  }' 
172.18.0.1
/prometheus # netstat -nr | grep '^0\.0\.0\.0' | awk '{print }'
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

在主机上,我可以访问 172.18.0.1 上的 docker 指标 API。我可以 ping 通并且可以发出成功的 HTTP 请求。

  1. 任何人都可以阐明为什么这在容器内不起作用,如 Docker Daemon Metrics 指南中所述?
  2. 如果容器在 172.18.0.1 网络上有一个网络接口并且为 172.18.0.1 配置了路由,为什么从容器内 ping 到 172.18.0.1 失败?
  3. 如果这不是从 swarm 容器内访问主机端口的有效方法,那么如何实现这一点?

编辑: 才发现原来我没有给出所有的信息post。 我在 CentOS 7.2 主机上 运行ning docker swarm,docker 版本 17.04.0-ce,内部版本 4845c56。我的内核是 4.9.11 版本,启用了 vxlan 和 ipvs 模块。

经过进一步挖掘,我注意到这似乎是一个防火墙问题。我发现我不仅无法从容器内 ping 172.18.0.1 - 而且我根本无法 ping 我的主机!我尝试了我的域名、服务器的 FQDN 甚至它的 public IP 地址,但容器无法 ping 主机(有网络访问,我可以 ping google/etc)。

我在主机上禁用了 firewalld,然后重新启动了 docker 守护进程。在此之后,我能够从容器内 ping 我的主机(域名和 172.18.0.1)。不幸的是,这不是我的解决方案。我需要确定我需要设置哪些防火墙规则以允许容器-> 主机通信而不需要禁用 firewalld。

首先,我非常感谢你。在阅读您的 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 您可能还需要重新启动 docker。