问题很可能出在docker0桥接层的转发行为上,需检查bridge设备状态、br_netfilter模块、stp设置、iptables桥接调用、veth挂载及fdb学习等底层转发机制。

当 Docker 容器间通信突然中断、ping 同网段容器 IP 失败,但各自网络配置看似正常时,问题很可能出在虚拟交换机(即 docker0 或自定义 bridge)的转发行为上。这类故障不表现为“设备 down”,而是数据包静默丢弃——传统 ping 或 ip addr 往往查不出端倪,必须聚焦桥接层的运行状态与转发逻辑。
确认 bridge 设备是否真正启用并参与转发
Linux 网桥不是“up 就等于能转发”。它依赖内核模块 br_netfilter 和 sysctl 开关协同工作:
- 运行
ip link show docker0,确认状态为UP(而非NO-CARRIER或DOWN) - 检查
cat /sys/class/net/docker0/bridge/stp_state:值为1表示 STP 启用且可能阻塞端口;生产环境建议设为0(关闭 STP) - 执行
cat /proc/sys/net/bridge/bridge-nf-call-iptables:必须为1,否则 iptables 规则无法作用于桥接流量 - 验证
lsmod | grep br_netfilter是否有输出;若无,需sudo modprobe br_netfilter并写入/etc/modules
检查 veth pair 是否正确挂载到 bridge
每个容器对应一对 veth 设备,其中宿主机侧必须绑定到 bridge 才能参与二层转发:
- 用
brctl show docker0或ip link show master docker0列出所有接入端口 - 找到形如
vethxxxx的接口,确认其master字段指向docker0 - 若缺失,说明容器启动时桥接失败(常见于 Docker daemon 异常重启后未重建连接)
- 可手动测试:
sudo ip link set vethabcd master docker0(仅调试用,非持久化)
验证桥接表(FDB)是否学习到容器 MAC 地址
网桥靠 FDB(Forwarding Database)做 MAC 学习和转发决策。若表项为空或老化,会导致单向/双向不通:
- 运行
sudo bridge fdb show | grep -v "self"查看当前学习到的 MAC 条目 - 正常应看到类似
00:11:22:33:44:55 dev vethabcd master docker0 self permanent的记录 - 若某容器 MAC 缺失,可能是该容器未发送过任何二层帧(如刚启动未发 ARP),或网桥未收到响应
抓包定位转发卡点位置
在 bridge 入口和出口分别抓包,比对流量走向:
- 在
docker0上抓包:sudo tcpdump -i docker0 -nn icmp,观察容器发出的 ping 请求是否到达网桥 - 在对应 veth 宿主机端抓包:
sudo tcpdump -i vethabcd -nn icmp,确认请求是否被转发进容器 - 若
docker0有请求但vethabcd没有,说明桥接转发被阻断(检查 bridge 设置或 netfilter 链) - 若
vethabcd有请求但容器内收不到,可能是命名空间路由或容器内防火墙拦截
快速验证桥接功能是否完好
绕过容器,直接用两个临时 network namespace 模拟:
# 创建两个命名空间和一对 veth ip netns add ns1 && ip netns add ns2 ip link add veth1 type veth peer name veth2 ip link set veth1 master docker0 && ip link set veth1 up ip link set veth2 netns ns2 && ip netns exec ns2 ip link set veth2 up ip netns exec ns2 ip addr add 172.17.0.100/16 dev veth2 ip netns exec ns2 ip link set lo up # 在 ns1 中 ping ns2 的 IP ip netns exec ns1 ping -c 3 172.17.0.100
若此测试失败,基本可锁定为 docker0 桥接层异常;若成功,则问题在容器自身配置或网络命名空间内。
不复杂但容易忽略











