docker基于静态路由实现跨宿主机访问
原理与背景
在默认情况下,Docker 安装在不同宿主机上时,默认网桥 docker0 的网段通常都是 172.17.0.1/16。这就导致了两个问题:
- IP 冲突:不同主机上的容器 IP 可能完全一样。
- 路由不可达:宿主机 A 不知道宿主机 B 的容器网段在哪里,数据包出了宿主机网卡就被丢弃了。
实现原理:
本方案的核心思想是**“直连路由”**。
- 规划网段:手动修改每台宿主机 Docker 的默认网段,保证互不冲突。
- 添加路由:在宿主机 A 上添加一条静态路由规则,告诉操作系统:“如果你想访问 B 主机的容器网段,请把数据包发给 B 主机的 IP 地址”。
- 前提条件:宿主机 A 和 宿主机 B 必须在同一个物理网络(或二层网络)中,且宿主机之间可以互通。
环境准备
准备两台 Linux 服务器,确保它们之间可以 Ping 通。
| 主机名 | 宿主机 IP (eth0) | 规划 Docker 网段 (docker0) |
|---|---|---|
| Node-1 | 192.168.1.100 | 172.17.1.1/24 |
| Node-2 | 192.168.1.101 | 172.17.2.1/24 |
实战步骤
修改 Docker 默认网段 (防止 IP 冲突)
这是最关键的一步。我们需要修改 /etc/docker/daemon.json 文件,使用 bip 参数指定不同的子网。
在 Node-1 (192.168.1.100) 上执行:
1 | mkdir -p /etc/docker |
在 Node-2 (192.168.1.101) 上执行:
1 | mkdir -p /etc/docker |
验证:
在两台机器上分别执行 ifconfig docker0,确认 IP 地址已经变成了我们规划的 172.17.1.1 和 172.17.2.1。
启动测试容器
我们在两台机器上分别启动一个容器,查看其 IP。
Node-1:
1 | docker run -itd --name c1 busybox |
Node-2:
1 | docker run -itd --name c2 busybox |
此时尝试 Ping:
在 Node-1 的容器 c1 里 ping 172.17.2.2 (Node-2 的容器)。
结果: 肯定不通。因为数据包到了 Node-1 宿主机后,它不知道 172.17.2.0/24 网段该往哪里发。
添加静态路由 (核心步骤)
我们需要“告诉”宿主机如何转发数据。
在 Node-1 (192.168.1.100) 上添加去往 Node-2 容器网段的路由:
1 | # 语法:ip route add [目标网段] via [下一跳IP(即对方宿主机IP)] dev [本机网卡] |
在 Node-2 (192.168.1.101) 上添加去往 Node-1 容器网段的路由:
1 | # 路由是双向的,回包也需要路径 |
检查路由表:
执行 route -n,你应该能看到新增的路由规则。
配置防火墙与转发 (避坑指南)
很多时候路由加了还是不通,是因为 Linux 的 iptables 默认拦截了转发包。
所有节点都要执行:
开启内核转发 (通常 Docker 安装时会自动开启,但检查一下更稳妥):
1
2echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p调整 iptables 规则 (允许转发):
如果你的iptables -L FORWARD策略是 DROP,需要放行:1
iptables -P FORWARD ACCEPT
(或者更精细地只放行特定的网段,生产环境建议配置具体规则)
最终验证
现在再次进行 Ping 测试。
在 Node-1 的容器 c1 中:
1 | docker exec -it c1 ping 172.17.2.2 |
预期结果:
1 | PING 172.17.2.2 (172.17.2.2): 56 data bytes |
通信成功!此时,Container A 访问 Container B,就像访问同一个局域网的机器一样流畅。
优缺点总结
优点
- 性能极佳:没有 VXLAN 的封包解包损耗,没有 NAT 转换,直接走三层路由转发,接近物理网络速度。
- 原理透明:完全依赖 Linux 路由表,方便抓包调试,易于理解网络流向。
- 无额外依赖:不需要 Consul、Etcd 或 Swarm 等额外的存储或管理组件。
缺点
- 配置繁琐:每增加一台主机,所有其他主机都需要手动添加路由规则(N 台主机需要维护 N*(N-1) 条路由),维护成本呈指数级上升。
- IP 管理复杂:需要人工精心规划每台机器的 Docker 网段,确保不冲突。
- 不灵活:容器飘移(迁移)到另一台宿主机后,IP 变化会导致路由失效。
总结
这种“静态路由”方案非常适合主机数量固定、网络拓扑简单的场景,或者用于学习 Docker 网络底层原理。
对于大规模动态集群,建议使用 Calico(BGP 路由自动广播)或 Overlay(Swarm/K8s)网络方案。











