我有 (2) 个 Docker-Compose 配置在相同主机上运行,但不同 Docker 桥接器上运行。每个都位于不同的子网上,因此必须路由它们的流量。一个 Docker-Compose 配置用于容器化网站,而另一个 Docker-Compose 配置用于 Zabbix Agent 来监控网站 Docker-Compose 配置。
虽然它们所在的 Docker 主机在网关路由器中都有到两个子网的路由,但 Linux Docker 主机本身也配置为路由器,因此应该在其托管的子网之间路由流量。
为什么流量无法在SAME Docker 主机上的不同网桥之间传递?!?!?
最佳答案
简介:
在实现容器化监控之前,我事先没有要求在同一主机上的 Docker 网桥之间传递流量。我是一名 Linux 和网络工程师,这浪费了我一生的一个小时来试图了解事情是如何发生的,所以我想如果你不是网络工程师,你会浪费更多的时间时间或完全失败。因此觉得值得花点时间来记录。
简短回答:
通过在 DOCKER-ISOLATION-STAGE-1 中自动插入 iptables
规则,Docker 再次“提供了帮助” - 再次 &2 FORWARD 表中的链破坏了连接。删除这些规则,现在可以实现分配给同一主机上不同子网的不同网桥上引发的容器之间的连接。
带有证明的较长答案:
诊断:
我重新剪切了 Zabbix Agent 的镜像,包括一些诊断工具 - traceroute、inetutils-ping> & iproute2 - 使用 docker exec -u root -it <container ID> bash
登录容器后,我发现代理的容器无法 ping 通另一个网桥上的容器,尽管 ip route list
证明存在正确的路由从代理的容器中出来。
对 Docker 主机的防火墙规则的审查显示,在 Docker 网桥之间传递的流量是禁止设计的:
iptables -nvx -L --line-numbers
<SNIP>
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
num pkts bytes target prot opt in out source destination
1 530374 174564169 DOCKER-ISOLATION-STAGE-2 all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0
2 3559 5117334 DOCKER-ISOLATION-STAGE-2 all -- br-2dfcb90fe695 !br-2dfcb90fe695 0.0.0.0/0 0.0.0.0/0
3 1229457 499057258 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Chain DOCKER-ISOLATION-STAGE-2 (2 references)
num pkts bytes target prot opt in out source destination
1 0 0 DROP all -- * docker0 0.0.0.0/0 0.0.0.0/0
2 16 960 DROP all -- * br-2dfcb90fe695 0.0.0.0/0 0.0.0.0/0
3 533917 179680543 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
<SNIP>
如果 DOCKER-ISOLATION-STAGE-1 中 Docker 桥的流量来源和目的地不相同,则它与通过的链规则 2 匹配它到链DOCKER-ISOLATION-STAGE-2,它匹配这里的规则2并丢弃流量。
我们知道该规则正在生效,因为我们可以看到数据包为此增加;流量确实在下降。因此,如果违规者,则使用链 DOCKER-ISOLATION-STAGE-2 中的规则 2。
解决方案:
打印规则,以便我们可以确定破坏我们连接的 iptables
的规则编号:
sudo iptables -nvx -L --line-numbers
然后按各自的编号删除有问题的规则。请注意,每个 iptables
命令末尾的最后一个数字“2”是您要删除的规则编号。我们将删除目标和引荐规则:
sudo iptables -D DOCKER-ISOLATION-STAGE-1 2
sudo iptables -D DOCKER-ISOLATION-STAGE-2 2
警告:虽然重新启动容器不会导致重新创建已删除的 iptables
规则,但执行 docker-compose down
后跟 up
会。
希望这可以节省其他人在解决容器网络连接中断问题上浪费的时间...
关于同一主机上的 Docker 容器但不同网桥无法连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71894601/