多网卡下Docker容器路由选错源于宿主机多默认网关或子网重叠,需清理冲突路由、避免docker0与业务网段冲突、配置SNAT及启用IP转发,并优先使用自定义bridge网络。

多网卡环境下Docker容器路由选错,本质是宿主机存在多个默认网关或子网重叠,导致流量被错误导向docker0或非业务网卡。核心不在容器本身,而在宿主机路由表与Docker网络配置的协同关系。
确认宿主机是否存在多默认路由
执行 ip route,重点检查是否出现多条 default via xxx dev xxx。Docker启动后若宿主机已有默认路由,它可能不会自动适配,反而新增一条冲突的默认路径(如同时存在 default via 192.168.5.1 dev ens33 和 default via 172.17.0.1 dev docker0)。这种重复默认路由会破坏出向流量走向。
- 临时清理:用
sudo ip route del default via 172.17.0.1删除由Docker误加的默认路由 - 永久规避:在Docker启动前确保宿主机仅保留一条业务网卡的默认路由
- 验证:清理后再次
ip route,应只剩一条default via [业务网关] dev [业务网卡]
避免docker0与业务网段地址冲突
Docker默认使用 172.17.0.0/16,若宿主机业务网段为 172.17.10.0/24 或 172.16.0.0/12,就会触发内核路由模糊匹配,优先走docker0而非物理网卡。
- 修改
/etc/docker/daemon.json,指定不重叠的网段,例如:{"bip": "192.168.200.1/24"} - 停服务:
sudo systemctl stop docker containerd - 删旧网桥:
sudo ip link delete docker0 - 重启:
sudo systemctl start docker - 验证:
ip addr show docker0应显示新IP,且ip route中对应子网已更新
强制容器流量走指定网卡出口
当宿主机有 eth0(内网)、eth1(公网)等多张业务网卡时,需确保容器出站流量经由正确接口。仅靠默认路由不够,需配合策略路由或iptables SNAT。
- 确认容器所在网桥的宿主机侧IP(如
192.168.200.1),该IP必须属于你希望出口的网卡子网或能被其网关转发 - 若需强制走 eth1(假设其IP为
203.0.113.10),可添加SNAT规则:sudo iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -o eth1 -j SNAT --to-source 203.0.113.10 - 确保内核开启转发:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward,并写入/etc/sysctl.conf
检查容器网络模式与路由继承逻辑
不同网络模式下,容器对宿主机路由的依赖程度不同:
- bridge 模式:容器通过 docker0 网桥 + NAT 访问外网,完全依赖宿主机的默认路由和 iptables 规则
-
host 模式:容器直接复用宿主机网络栈,此时容器内
ip route与宿主机一致,多网卡路由问题会原样暴露 - 自定义 bridge 网络:仍走 NAT,但网桥 IP 可独立配置;务必避免其 subnet 与任一物理网段重叠
建议生产环境优先使用自定义 bridge 网络,并显式指定 --subnet 和 --gateway,不依赖默认行为。











