![使用 Linux Bridge 的转发和路由问题](https://linux22.com/image/730246/%E4%BD%BF%E7%94%A8%20Linux%20Bridge%20%E7%9A%84%E8%BD%AC%E5%8F%91%E5%92%8C%E8%B7%AF%E7%94%B1%E9%97%AE%E9%A2%98.png)
我在虚拟机 (Ubuntu 18.04) 中运行两个容器 (A 和 B)。为了进行网络模拟,我将数据包从 A 路由到 B (此部分有效)。我想要做的是允许 A 和 B 与外界通信。因此,我会:
A ---- B ---- Host VM --- Host --- Internet
到目前为止我已经这样做了:
ip link add name br_routing type bridge
ip link set dev br_routing up
然后添加另一个虚拟接口,以便容器 B 有一个接口可以到达主机虚拟机网络:
ip link add vm_side_iface type veth peer name containerb_side_iface
将接口添加到桥接器
ip link set dev vm_side_iface master br_routing
设置容器内的网桥和接口的 IP
ip addr add 192.168.10.1/24 dev br_routing
ip addr add 192.168.10.2/24 dev vm_side_iface
激活虚拟机端接口
ip link set vm_side_iface up
ip link set containerb_side_iface netns $container_pid
然后在容器 B 网络命名空间内:
ip addr add 192.168.10.2/24 broadcast 192.168.10.255 dev containerb_side_iface
ip route add default via 192.168.10.1 dev containerb_side_iface
此时,我可以从主机虚拟机 ping A 和 B
但是我无法从 A 或 B ping 通网桥。错误似乎来自路由,因此它是这样的:B 路由表:
10.11.1.0/24 dev eth0 proto kernel scope link src 10.11.1.2
10.22.0.0/16 via 10.11.1.1 dev eth0
192.168.10.0/24 dev containerb_side_iface proto kernel scope link src 192.168.10.2
主机虚拟机路由表:
default via 10.0.2.2 dev enp0s3 proto dhcp metric 100
10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.15 metric 100 #Irrelevant here
10.11.0.0/16 via 192.168.10.2 dev br_routing #Route to reach B
10.22.0.0/16 via 192.168.10.2 dev br_routing #Route to reach A
192.168.10.0/24 dev br_routing proto kernel scope link src 192.168.10.1 #This seems odd
192.168.10.0/24 dev router_0 proto kernel scope link src 192.168.10.2 #This seems odd
我的第二个猜测是我的路由表,这是我尝试过的:
iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
iptables -A FORWARD -i enp0s3 -o vm_side_iface, -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i vm_side_iface, -o enp0s3 -j ACCEPT
iptables -A FORWARD -i enp0s3 -o vm_side_iface, -j ACCEPT
我也尝试更换虚拟机侧接口经过br_routing但无论如何都行不通。此外,规则未被使用(0 个接受的数据包,0 个丢弃的数据包)。这些是 VM 中配置的唯一规则。无论如何,从主机 VM 到 A/B 的 ping 在没有这些规则的情况下也能正常工作。
最后,modprobe br_netfilter并且刷新 /etc/sys/net/bridge 里面的文件不会改变任何东西。
无效的方法:
ping from A or B to HOST VM
ping from A or B to vm_side_iface
ping from A or B to br_routing
有效的方法:
ping from HOST VM to A or B
我注意到消息到达了网桥(tcpdump -i br_routing)但没有转发到 enp0s3 接口。
有什么猜测吗?
答案1
我设法通过使用在启动没有网络参数的docker容器时默认创建的docker0网桥来使其工作
docker run -itd image_name
这座桥和我正在建造的那座桥是一样的,但不知何故,这座桥却能正常运作。