同一主机上的 Docker 容器但不同网桥无法连接

标签 docker docker-compose routes iptables zabbix

我有 (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 的镜像,包括一些诊断工具 - tracerouteinetutils-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/

相关文章:

Tomcat 7 在 Debian 中启动时失败,但继续在后台工作

docker-compose 不加载 yaml 文件中定义的附加环境文件

asp.net-mvc - ASP.Net MVC 支持嵌套资源吗?

ruby-on-rails - 铁路路线问题

ruby-on-rails - 传递与 id 不同的参数以返回 JSON 用户对象的正确 Rails 路由是什么?提供 Controller 方法

bash - 使用与父用户相同的 UID/GID 运行 docker 或 docker-compose 的简单方法?

windows - 运行 postgres 容器时出错 "Error response from daemon: invalid mode:/var/lib/postgresql/data."

docker - 如何使用 docker env 创建文件

python - Docker - 无法访问 Django 服务器

mysql -/usr/bin/docker-当前 : Error parsing reference . 。引用格式无效