核心问题是宿主机存在多条默认路由,Docker启动时错误添加default via 172.17.0.1 dev docker0,导致出向流量被导向虚拟网桥而非业务网卡;需立即删除冲突路由、禁用NetworkManager接管docker0、修改daemon.json中bip为不重叠网段(如192.168.200.1/24)、重启Docker并配置SNAT确保容器流量经指定网卡发出。

核心问题是宿主机存在多条默认路由,Docker启动时额外添加了一条指向docker0的default via 172.17.0.1,导致出向流量被错误导向虚拟网桥而非业务网卡。这不是容器配置问题,而是宿主机路由表混乱引发的“脱网”。
立即恢复网络连通性
先临时清除冲突路由,让业务流量回归正轨:
- 执行
ip route,确认是否存在两条及以上default via xxx dev xxx(例如一条走ens33,另一条走docker0) - 若发现
default via 172.17.0.1 dev docker0,立即执行:sudo ip route del default via 172.17.0.1 dev docker0 - 验证只剩一条业务默认路由,例如:
default via 192.168.5.1 dev ens33 - 此时宿主机和已有容器的外网访问通常会立刻恢复
永久避免默认路由被Docker篡改
Docker服务本身不管理宿主机默认路由,但它在初始化docker0时可能因检测逻辑误加默认路径。关键在于启动前环境必须干净:
- 确保系统启动后、Docker启动前,宿主机路由表中仅存在且仅允许存在一条默认路由,且该路由绑定在你要用的业务网卡上(如
eth1或ens192) - 检查
/etc/netplan/或/etc/network/interfaces,删除任何为docker0或非业务接口配置的gateway项 - 禁用NetworkManager对
docker0的接管(如有):在/etc/NetworkManager/NetworkManager.conf中添加unmanaged-devices=interface-name:docker0 - 重启NetworkManager并验证
ip route无异常后再启Docker
隔离容器网络与业务网络平面
即使路由清理了,只要docker0子网和业务网段重叠(比如都是172.17.x.x),内核仍可能因最长前缀匹配失败而选错出口。必须解耦地址空间:
- 编辑
/etc/docker/daemon.json,强制指定不重叠的bip,例如:{"bip": "192.168.200.1/24"} - 停止服务:
sudo systemctl stop docker containerd - 彻底删除旧网桥:
sudo ip link delete docker0 - 启动Docker:
sudo systemctl start docker - 验证:
ip addr show docker0应显示新IP,且ip route | grep 192.168.200只出现一条直连路由
强制容器流量从指定网卡发出
当宿主机有内网卡(eth0)和公网卡(eth1)时,仅靠默认路由不够——需确保容器源IP经eth1 SNAT出去:
- 确认容器所在网桥的宿主机侧IP(如
192.168.200.1)能被eth1的网关路由(即二者在同一大网段,或已配置静态路由) - 添加SNAT规则:
sudo iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -o eth1 -j SNAT --to-source [eth1实际IP] - 开启IPv4转发:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward,并写入/etc/sysctl.conf持久化 - 该规则确保所有来自该容器子网的出向包,源地址都被替换为
eth1的IP,从而走对出口



















