多宿主机 Docker 网段冲突本质是各主机默认 bridge(如172.17.0.0/16)与本地业务网段重叠或彼此交叉,导致路由错判;须逐台检查业务网段与Docker子网并统一规划为互斥CIDR(如10.200.0.0/16),再通过daemon.json配置bip、删除docker0、启用SNAT及ip_forward,并推荐全面采用显式自定义bridge网络替代默认bridge。

多宿主机环境下 Docker 网络网段冲突,本质是不同主机上的 Docker 默认桥接网段(如 172.17.0.0/16)与各自所在局域网重叠,或彼此之间网段重复,导致跨主机通信时路由无法正确识别目标——流量可能被本地 docker0 拦截、发往错误网关,甚至出现“容器能 ping 宿主机却无法互通其他主机”的静默失败。
确认是否真存在跨主机网段重叠
不能只看单台机器。需逐台检查并比对:
- 每台宿主机执行:
ip route | grep '^default\|^192\.168\|10\.\|172\.' | head -2,提取其实际业务网段(如192.168.10.0/24或10.20.30.0/24) - 每台宿主机执行:
docker network inspect bridge | grep -E '"Subnet"|Gateway',记录默认 bridge 的子网(如172.17.0.0/16) - 汇总所有宿主机的业务网段 + 所有 Docker 子网,检查是否有任意两个网段存在包含或交叉(例如 A 主机用
172.17.5.0/24,B 主机 Docker 用172.17.0.0/16→ 冲突)
统一规划并修改各宿主机的 Docker 默认网段
避免“各改各的”造成新冲突,应提前统一分配不重叠、不与任何业务网段交集的私有 CIDR:
- 推荐从
10.200.0.0/16、192.168.200.0/24或10.255.0.0/16中选一个作为全局 Docker 基础网段 - 在每台宿主机上编辑
/etc/docker/daemon.json,写入明确 bip(例如:{"bip": "10.200.1.1/24"}),注意不同主机可微调第三段(如10.200.1.1/24、10.200.2.1/24),确保子网互不重叠 - 停服务:
sudo systemctl stop docker containerd;删旧网桥:sudo ip link delete docker0;再启动:sudo systemctl start docker
强制跨主机流量走指定物理路径
仅统一 Docker 网段还不够——多宿主机间若通过不同网卡互联(如 eth0 内网直连、eth1 走交换机),需确保容器出向流量经由正确的出口网卡:
- 确认每台宿主机用于跨主机通信的业务网卡 IP(如
10.200.10.5),该 IP 所在子网必须与你分配的 Docker bip 可路由(或配置静态路由) - 在每台宿主机添加 SNAT 规则,将本机 Docker 子网流量固定从该业务网卡发出:
sudo iptables -t nat -A POSTROUTING -s 10.200.1.0/24 -o eth0 -j SNAT --to-source 10.200.10.5 - 开启转发:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward,并写入/etc/sysctl.conf持久化
用自定义网络替代默认 bridge(推荐长期方案)
默认 bridge 在多宿主机场景下缺乏可控性。更健壮的做法是弃用它,全部使用显式声明的自定义 bridge 网络:
- 为每个服务或集群创建独立网络,指定不重叠子网:
docker network create -d bridge --subnet=192.168.101.0/24 --gateway=192.168.101.1 app-net-01 - 启动容器时强制绑定:
docker run --network=app-net-01 …;Compose 中明确声明:networks: { app-net-01: { driver: bridge, ipam: { config: [{ subnet: "192.168.101.0/24" }] } } } - 这样可完全规避 docker0 自动分配逻辑,也便于后续对接 Consul、Calico 等跨主机网络插件



















