我遇到了奇怪的虚拟(docker bridges)网络状况
我有两个 docker 通过 docker-compose 连接到同一个网桥。一个 docker 是“probe”,另一个是“injector”。Injector 使用 tcpreplay 重放捕获,而“probe”应该通过 tcpdump 接收它。不用说,重放的捕获与连接到网桥的 NICS 的 IP 或 mac 没有任何关系。主机之间的 ping 工作正常。
现在,docker 自动向主机公开了第三个 NIC。
+--->NIC1 ["injector" docker / uses tcpreplay to inject ]
bridge +--->NIC2 ["probe" docker / uses tcpdump to listen]
|
+--- NIC3 host [used for testing sometimes as injector and sometimes as listener]
现在实际发生的情况是,当从 HOST 运行 tcpreplay(通过 NIC3 注入捕获)时,一切都运行正常,并且“探测”上的 tcpdump 显示重放的流量。但是,当在注入器上使用 tcpreplay 并通过 NIC1 注入捕获时,在“探测”上只能看到捕获的前两个数据包,然后“探测”上的所有流量都会停止(从主机注入也将停止工作)。如果在 NIC3 上运行 tcpdump,它会正常接收来自注入器的所有捕获流量。
- “探测”上的 ifconfig 没有显示任何丢弃的数据包
- 主机上的 iptables 不会增加丢弃数据包的计数器(希望我做得正确“sudo iptables -L -v -n | grep -i drop”)
- tcpdump 在探测时自动启用混杂模式
有人能解释这种不对称行为吗?知道如何调试吗?
注入器和主机 - AlmaLinux:8,探测 -Centos:7 tcpreplay 版本 4.4.1
答案1
桥接器未传递帧的原因在于 mac 学习机制。假设我们想在注入器容器中将流量从 MAC1 注入到 NIC1 上的 MAC1->MAC2,桥接器过滤器将传递(泛洪到探测器)来自 MAC1 --> MAC2 的流量并获悉 MAC1 位于 NIC1 上,但随后它将拒绝泛洪来自同一端口上的 MAC2-->MAC1 的所有内容,因为它认为 MAC1 位于流量来自的同一端口上。再次说明,注入的流量记录在其他地方,与实际桥接器拓扑没有任何联系。
按照说明禁用网桥上的 mac 学习机制这里解决了该问题,从注入器注入的所有帧都将被淹没到探测器。
当流量从主机注入时,行为不对称的原因尚不清楚。但我发现,当流量从 NIC3 注入时,网桥并没有真正激活其学习机制,例如,出于某种原因,注入流量的 mac 从一开始就没有出现在学习的 mac 列表中。