我有一个这样的网络拓扑:
你看,em1
(1.1.8.209)是我可以通过互联网进行通信的物理接口。我创建了两个虚拟机实例:PID 8740
和PID 8817
,都使用网络 IP 1.1.8.210/29
,并且1.1.8.211/29
,都是公共 IP 地址。
现在我可以通过互联网与em1交流。
但我有一个要求,我想直接访问两个虚拟机,所以我想将 em1 附加到br0
.
然后我执行了这个:
brctl addif br0 em1
拓扑变成这样:
但是,执行此命令后,出现错误,无法1.1.8.209
再与任何人通信。然后我删除了附件brctl delif br0 em1
,现在就可以访问了1.1.8.209
。
为什么我会遇到这个问题?不太明白,请帮忙解释一下原因。
答案1
当接口成为桥接端口时,它不再参与路由。
此博客中描述了底层细节Linux 桥的正确隔离:
将帧移交给全局或设备特定的协议处理程序(例如 IPv4、ARP、IPv6)。
对于桥接接口,内核配置了一个特定于设备的接收处理程序,
br_handle_frame()
.此功能不允许在传入接口的上下文中进行任何附加处理,STP 和 LLDP 帧或启用“路由”的情况除外。因此,协议处理程序永远不会被执行在这种情况下。
此类桥接端口的 IP 地址与传入数据包无关。将其保留在原来的位置仍然会破坏传出数据包的正确路由,因为这些数据包仍然可以直接通过桥接端口发送(当它们不应该再发送时)。
必须做的是将 IP 地址移动到另一端连接到网桥的系统(或网络命名空间,甚至是 veth 对在同一位置的另一个自由端),或者网桥的自端口,即网桥本身。在此移动过程中总会有一个小的时间窗口,其中会存在中断,因此在本地执行的更改此配置的操作不得依赖于网络访问(例如:不得依赖于使用中断的路由通过 shell 远程键入命令)。
我将仅使用下面具有较新语法的较新工具。
例如:
ip address flush dev em1
ip address add 1.1.8.209/29 dev br0
相反,另一种方法是让网桥不参与路由并使用额外的韦斯参与路由的对端(在同一网络命名空间中)可以是:
ip address flush dev em1
ip link add name em1twin type veth peer name br0portem1twin
ip link set br0portem1twin master br0 up
ip link set em1twin up
ip address add 1.1.8.209/29 dev em1twin
在这两种情况下,如果默认路由(或其他路由)依赖于该地址的存在,则还必须再次添加该路由,因为它消失了。