使用host网络的容器A与bridge网络的容器B能否直接通信?
问题
请问在不借助外部路由应用的情况下,使用host网络模式(--net host)的Container_A内部端口,能否被使用bridge网络模式(--network=secure-network)的Container_B访问?
容器配置
- 容器A:采用host网络模式
ExecStart=/usr/bin/docker run --name=agent-a \ --detach \ --net host \ --pid host \ -v /run:/run:ro \ -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ --mount type=bind,source=/mnt/agent_a.py,target=/agent_a.py \ local/agent-a:local \ python3 /agent_a.py
agent_a.py绑定0.0.0.0的5678端口(Web服务)
- 容器B:采用bridge网络
secure-network
ExecStart=/usr/bin/docker run \ --init \ --restart always \ --cap-add SYS_ADMIN \ --cap-add SYS_PTRACE \ --ip=192.168.10.10 \ --network=secure-network \ --name=agent-b \ us-docker.pkg.dev/agents/gcr.io/agent-b:local
测试情况
在宿主机上:
- 宿主机IP 10.128.0.70可正常访问
- 通过curl能访问宿主机IP 10.128.0.70的Web服务
- 容器B可ping通宿主机IP 10.128.0.70:
ping 10.128.0.70 PING 10.128.0.70 (10.128.0.70) 56(84) bytes of data. 64 bytes from 10.128.0.70: icmp_seq=1 ttl=64 time=0.051 ms 64 bytes from 10.128.0.70: icmp_seq=2 ttl=64 time=0.064 ms ^C --- 10.128.0.70 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1014ms rtt min/avg/max/mdev = 0.051/0.057/0.064/0.006 ms
- 容器B无法通过curl访问宿主机IP 10.128.0.70的5678端口:
curl -vv http://10.128.0.70:5678/health * Trying 10.128.0.70:5678...
网络配置
已创建网络列表
sudo docker network ls NETWORK ID NAME DRIVER SCOPE 4eab8870c1cc bridge bridge local a7c6e199d01a secure-network bridge local 32fb6d1f566c host host local 53190c781054 none null local
secure-network 详情
sudo docker network inspect secure-network [ { "Name": "secure-network", "Id": "a7c6e199d01a51daa43a18d04c07a03f0e590cd9ff4ed971d671657cf5e3f32a", "Created": "2023-07-02T07:47:36.147584427Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.10.0/24", "Gateway": "192.168.10.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "c44594d803226d41a588c6a23375d60052c9144020bd51ac450e1ece0d7a067d": { "Name": "agent-b", "EndpointID": "68963552203a1dbc3d718bc4455e050bf4c6172c7b6d638e05fcb3511a490902", "MacAddress": "02:42:c0:a8:0a:0a", "IPv4Address": "192.168.10.10/24", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
排查信息
- 容器A的服务监听状态:
sudo netstat -anp | grep 5678 tcp 0 0 0.0.0.0:5678 0.0.0.0:* LISTEN 10207/python3
- 尝试将agent A绑定到宿主机IP 10.128.0.70:5678,问题依旧
- 容器A无法路由到192.168.x.x网段
解答
结论:可以实现访问,核心是调整宿主机防火墙规则
使用host网络模式的容器A,服务直接绑定在宿主机网络栈上,理论上bridge网络的容器B只要能访问宿主机IP,就应该能访问该端口。当前无法访问的原因是宿主机防火墙拦截了来自bridge子网(192.168.10.0/24)的流量访问5678端口。
解决步骤
- 允许bridge子网访问宿主机5678端口
如果使用iptables:
sudo iptables -A INPUT -s 192.168.10.0/24 -p tcp --dport 5678 -j ACCEPT
如果使用firewalld:
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.10.0/24" port port="5678" protocol="tcp" accept' --permanent sudo firewall-cmd --reload
- 验证规则生效
在容器B中再次执行curl命令:
curl http://10.128.0.70:5678/health
此时应该能正常访问服务。
补充方案
如果不想修改防火墙,也可以将容器A加入secure-network bridge网络(需权衡host模式特性的影响):
docker network connect secure-network agent-a
之后容器B可以直接通过agent-a:5678访问服务,但容器A会同时拥有host和bridge两个网络栈,可能影响原本的host模式功能。
内容的提问来源于Stack Exchange,提问作者Nuria
相关产品推荐
相关产品推荐

