我的目标是在不同的网络上运行两个 Docker 容器,并让我的主机 (Ubuntu 22.04) 执行 NAT,以便第一个网络可以到达第二个网络。
我的设置:
docker network create network1
docker network create network2
docker run --rm -it --network network1 ubuntu:22.04 bash
# In other terminal
docker run --rm -it --network network2 ubuntu:22.04 bash
第一个容器的地址为 172.19.0.2,第二个容器的地址为 172.20.0.2。
在我的主机上运行ip addr
,我看到接口分别是br-deadbeef
和br-feedbeef
。
然后我跑
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A FORWARD -i br-deadbeef -o br-feedbeef -j ACCEPT
iptables -A FORWARD -i br-feedbeef -o br-deadbeef -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -o br-feedbeef -j MASQUERADE
以 root 身份在主机上。
然而,ping 172.20.0.2
从第一个容器开始并没有成功。在主机上运行 Wireshark 显示br-deadbeef
网络上有从 172.19.0.2 到 172.20.0.2 的 ICMP 数据包,但没有回复。
我缺少什么?
答案1
问题在于以下iptables
规则:
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
...
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE2 all -- anywhere anywhere
...
Chain DOCKER-ISOLATION-STAGE-2 (3 references)
target prot opt source destination
DROP all -- anywhere anywhere
...
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
如果您iptables
使用详细选项 ( -v
) 运行,您将看到DROP
下面的目标DOCKER-ISOLATION-STAGE-2
引用接口(在它的正下方br-deadbeef
有一个规则)。DROP
br-feedbeef
由于您使用 添加了规则-A
,因此它们被附加到链的底部,这意味着跳转到DOCKER-ISOLATION-STAGE-1
并因此DOCKER-ISOLATION-STAGE-2
跳转到 优先。
一个简单的解决方法是添加您的规则-I
。这会将它们插入链的顶部。