在 Linux 中,bridge 是虚拟的二层网络设备。不同于 eth 或 ens 等真实的网络设备,bridge 能够让同一 Linux 系统内的其他网络设备连接起来;比如 docker 默认的网络模型就是利用 bridge 将各个实例的网络打通,如图:

linux bridge

brctl 强制泛洪

在 brctl 的 manual 中有一段描述:

1
2
3
4
       brctl setageing <brname> <time> sets the ethernet (MAC) address
       ageing time, in seconds. After <time> seconds of not having seen
       a frame coming from a certain address, the bridge will time out
       (delete) that address from the Forwarding DataBase (fdb).

bridge 会维持一张 mac 地址表,叫 fdb。Linux 内核会为该 bridge 维持一个 gc 定时器,该定时器会定时去清理失效的 fdb 记录;该定时器默认的间隔为 300s;可以通过命令 brctl showstp docker0 看到:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# brctl showstp docker0
docker0
 bridge id		8000.0242d4005155
 designated root	8000.0242d4005155
 ...
 ageing time		 300.00
 ...

veth4f17ef9 (1)
 ...

或者查看相应的 sysctl 文件 cat /sys/class/net/docker0/bridge/ageing_time

当这个 ageing time 设置为 0,会发生什么呢?

强制泛洪效果

当一个网络包经过 bridge 而 bridge 在其 fdb 中找不到对应记录,即 bridge 不确定该网络包该通过那个网口发出去时,bridge 会将该网络包通过除收包网口外的其他所有网口发出去,俗称泛洪。 当将 ageing time 设置为 0 时, 意即 bridge 无需维持 fdb ,每当收到一个网络包,都将这个网络包泛洪出去。

img

如图,就是从 CoreDNS 发出来的网络包,会以泛洪的方式发给 Nginx 和 MySQL。

总结

在正常的生产环境中,是不希望发生 bridge 泛洪这种事情的。

而在特定的场景中,强制泛洪却是不可多得的技巧