双子网Docker Swarm集群中如何激活Overlay路由网格?
Docker Swarm跨子网路由网格失效问题与解决方案
环境配置(Oracle VirtualBox)
| 子集群 | 节点 | 网卡接口 | IPv4地址 |
|---|---|---|---|
| sub-cluster1 | manager1 | enp0s9(Host-Only) | 192.168.50.3 |
| enp0s8(NAT-Network) | 10.0.1.3 | ||
| worker1-1 | enp0s8(NAT-Network) | 10.0.1.4 | |
| worker1-2 | enp0s8(NAT-Network) | 10.0.1.5 | |
| sub-cluster2 | manager2 | enp0s9(Host-Only) | 192.168.100.3 |
| enp0s8(NAT-Network) | 20.0.1.3 | ||
| worker2-1 | enp0s8(NAT-Network) | 20.0.1.4 | |
| worker2-2 | enp0s8(NAT-Network) | 20.0.1.5 |
已执行操作
- 所有节点通过ufw开放Swarm必备端口:
sudo ufw allow 2377/tcp sudo ufw allow 4789/udp sudo ufw allow 7946/tcp sudo ufw allow 7946/udp
- Swarm集群初始化与节点加入:
- 在manager1上初始化集群:
docker swarm init --advertise-addr 192.168.50.3
- 获取manager令牌并加入manager2:
docker swarm join-token manager docker swarm join --token <MANAGER-JOINING-TOKEN-FROM-MANAGER1> 192.168.50.3:2377
- 加入worker节点(使用子网内NAT-Network IP):
# sub-cluster1的worker节点 docker swarm join --token <WORKER-JOINING-TOKEN-FROM-MANAGER1> 10.0.1.3:2377 # sub-cluster2的worker节点 docker swarm join --token <WORKER-JOINING-TOKEN-FROM-MANAGER2> 20.0.1.3:2377
- 创建overlay网络并部署服务:
docker network create --driver overlay --attachable --subnet 30.0.1.0/24 my-overlay-mesh docker service create \ --name nginx-rMesh \ --network my-overlay-mesh \ --constraint node.role==worker \ --replicas 4 --replicas-max-per-node 2 \ --publish target=80,published=80 \ nginx
问题现象
docker node ls显示所有节点成功加入,但跨子网(10.0.1.x与20.0.1.x)节点无法互ping;manager间可通过Host-Only IP互ping,同子网内manager与worker可正常通信。- overlay网络仅在manager节点创建,部署服务后才同步到worker节点。
- 无法通过manager的Host-Only IP(如
curl http://192.168.50.3)访问nginx服务。 - 补充:若用10.0.1.3初始化Swarm,同子网路由网格正常,但无法加入第二个子网的节点。
问题核心原因
- 跨子网连通性缺失:Swarm路由网格依赖节点间三层连通性,当前两个NAT子网无路由规则,导致跨子网流量无法传输,控制平面和数据平面通信中断。
- 集群通信地址不统一:manager用Host-Only IP加入集群,worker用NAT-Network IP加入,节点间通信地址分属不同不可达网络,路由网格无法正确转发流量。
- Overlay网络同步逻辑:Overlay网络默认仅在有服务调度到节点时创建,这是正常行为,但核心问题仍为跨子网连通性不足。
最优解决方案
方案1:配置跨子网静态路由(推荐)
为两个NAT子网添加路由规则,实现跨子网连通:
- 步骤1:确认VirtualBox中两个NAT-Network的网关分别为
10.0.1.1和20.0.1.1。 - 步骤2:在各节点添加静态路由:
- sub-cluster1节点(manager1、worker1-1、worker1-2)执行:
sudo ip route add 20.0.1.0/24 via 10.0.1.1 - sub-cluster2节点(manager2、worker2-1、worker2-2)执行:
sudo ip route add 10.0.1.0/24 via 20.0.1.1
- sub-cluster1节点(manager1、worker1-1、worker1-2)执行:
- 步骤3:统一集群通信地址:用manager1的Host-Only IP初始化集群,所有worker节点也通过Host-Only网络IP加入(需为worker配置Host-Only网卡,分配对应子网IP,确保跨子网Host-Only网络连通)。
方案2:统一使用Host-Only网络替代NAT-Network
将所有节点的通信统一到同一Host-Only网络:
- 为所有节点添加同一段Host-Only网卡(如
192.168.60.0/24),分配唯一IP:- manager1:
192.168.60.3 - manager2:
192.168.60.4 - worker1-1:
192.168.60.5 - worker1-2:
192.168.60.6 - worker2-1:
192.168.60.7 - worker2-2:
192.168.60.8
- manager1:
- 所有节点通过该Host-Only IP完成Swarm初始化与加入操作,确保全集群在同一可达网络内。
方案3:优化服务部署(辅助操作)
无需自定义overlay网络,直接使用Swarm默认ingress网络部署服务,确保端口转发规则正确:
docker service create \ --name nginx-rMesh \ --constraint node.role==worker \ --replicas 4 --replicas-max-per-node 2 \ --publish target=80,published=80,mode=ingress \ nginx
(注:此方案需先解决跨子网连通性问题,否则仍无法正常访问)
关键注意事项
- Swarm集群所有节点必须保证三层连通性(可互ping),这是路由网格工作的基础。
- 初始化和加入Swarm时,
--advertise-addr与加入地址必须为全集群可达的统一网络地址,避免混合使用不同网络的IP。 - 防火墙需允许Swarm控制平面(2377/tcp)、节点间通信(7946/tcp/udp)和overlay网络流量(4789/udp)的双向通行。
内容的提问来源于stack exchange,提问作者jislam
相关产品推荐
相关产品推荐

