根本原因是docker自动添加的default via 172.17.0.1 dev docker0路由干扰宿主机原有路由决策,导致外网流量误入docker0;需三步解决:立即删除冲突路由、修改daemon.json中bip为不重叠网段(如192.168.200.1/24)、配置snat并启用ip_forward。

多网卡宿主机上 Docker 容器无法访问外网,或宿主机与内网服务失联,根本原因不是容器配置错了,而是 Docker 自动添加的路由条目干扰了系统原有路由决策——特别是那条 default via 172.17.0.1 dev docker0,和你业务网卡(如 ens33、eth1)的默认路由并存,导致内核按最长前缀匹配把本该走物理网卡的流量误导向 docker0 网桥。
立即恢复通信:删掉冲突的默认路由
这是最快速见效的操作,5 秒内就能让现有容器恢复上网:
- 运行
ip route,确认是否同时存在两条default via路由,例如一条走ens33(你的业务出口),另一条走docker0 - 直接删除 Docker 擅自加的那条:
sudo ip route del default via 172.17.0.1 dev docker0 - 再执行
ip route,确保只剩一条业务默认路由,比如default via 192.168.5.1 dev ens33
永久规避重叠:改掉 docker0 默认网段
Docker 默认用 172.17.0.0/16,一旦你宿主机内网也在这个范围(比如 172.16.0.0/12 或 172.17.10.0/24),内核就会优先匹配更长前缀,流量卡在网桥里出不去:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 编辑
/etc/docker/daemon.json,写入明确不重叠的网段,例如:{"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只有一条直连路由
强制出口路径:配 SNAT + 开启转发
光靠默认路由还不够。当宿主机有 eth0(内网)和 eth1(公网)时,必须明确告诉系统:“所有容器发出去的包,必须从 eth1 走”:
- 确认容器网桥在宿主机侧的 IP(比如
192.168.200.1),这个地址最好属于eth1所在子网,或能被其网关转发 - 加 SNAT 规则(假设
eth1的公网 IP 是203.0.113.10):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持久化:net.ipv4.ip_forward = 1
注意不同网络模式的影响
别忽略模式差异带来的路由依赖变化:
- bridge 模式(默认):完全依赖宿主机默认路由 + iptables NAT,上面三步必须做完
-
host 模式:容器直接复用宿主机网络栈,
ip route和宿主机一模一样,多网卡路由问题会原样暴露,慎用 -
DNS 不要继承:避免容器因宿主机
/etc/resolv.conf混乱而解析失败,启动时显式指定:docker run --dns 8.8.8.8 ...










