我有一个Swarm集群,在其中创建了一个全局服务,以在集群中的所有Docker主机上运行。
目标是使此服务的每个容器实例连接到侦听Docker主机端口的端口。
为了获取更多信息,我正在遵循这个“Docker Daemon Metrics”指南,在所有主机上公开新的Docker度量API,然后将该主机端口代理到覆盖网络中,以便Prometheus可以从所有Swarm主机抓取度量数据。
我已经阅读了几个Docker GitHub问题#8395、#32101、#32277、#1143——从中我的理解与“Docker Daemon Metrics”中概述的相同。为了从Swarm容器内部连接到主机,我应该使用docker-gwbridge网络,其默认为172.18.0.1。
我的Swarm中的每个容器都有一个docker-gwbridge网络接口。
尽管如此,我仍无法在容器内与172.18.0.1通信:
在主机上,我可以访问172.18.0.1上的docker metrics API。我可以ping通它并成功发出HTTP请求。
问题如下:
经过进一步调查,我注意到这似乎是防火墙问题。我发现不仅容器内无法ping通172.18.0.1,而且容器内也无法ping通我的主机!我尝试了我的域名、服务器的FQDN甚至它的公共IP地址,但容器无法ping通主机(虽然网络可用,我可以ping通Google/等等)。
我在主机上禁用了firewalld,然后重启了docker守护程序。在此之后,我能够从容器内ping通我的主机(无论是域名还是172.18.0.1)。不幸的是,这对我来说并不是一个解决方案。我需要确定需要放置哪些防火墙规则以允许容器与主机通信,而无需禁用firewalld。
目标是使此服务的每个容器实例连接到侦听Docker主机端口的端口。
为了获取更多信息,我正在遵循这个“Docker Daemon Metrics”指南,在所有主机上公开新的Docker度量API,然后将该主机端口代理到覆盖网络中,以便Prometheus可以从所有Swarm主机抓取度量数据。
我已经阅读了几个Docker GitHub问题#8395、#32101、#32277、#1143——从中我的理解与“Docker Daemon Metrics”中概述的相同。为了从Swarm容器内部连接到主机,我应该使用docker-gwbridge网络,其默认为172.18.0.1。
我的Swarm中的每个容器都有一个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
在主机上,我可以访问172.18.0.1上的docker metrics API。我可以ping通它并成功发出HTTP请求。
问题如下:
- 有人能解释一下为什么按照《Docker Daemon Metrics》指南,在容器内部无法按照规定方式使用该API吗?
- 如果容器在172.18.0.1网络上有网络接口并且配置了路由,则为什么从容器内部ping 172.18.0.1会失败呢?
- 如果这不是从swarm容器内部访问主机端口的有效方法,则怎样才能实现呢?
经过进一步调查,我注意到这似乎是防火墙问题。我发现不仅容器内无法ping通172.18.0.1,而且容器内也无法ping通我的主机!我尝试了我的域名、服务器的FQDN甚至它的公共IP地址,但容器无法ping通主机(虽然网络可用,我可以ping通Google/等等)。
我在主机上禁用了firewalld,然后重启了docker守护程序。在此之后,我能够从容器内ping通我的主机(无论是域名还是172.18.0.1)。不幸的是,这对我来说并不是一个解决方案。我需要确定需要放置哪些防火墙规则以允许容器与主机通信,而无需禁用firewalld。