一、问题背景
在一套 Docker Swarm 集群 中,集群包含:
- 1 个 manager 节点
- 1 个 worker 节点
在 worker 节点上部署了一个 Web 服务,监听 8102 端口,并通过 Swarm 的 service 方式对外暴露端口。
现象如下:
- ✅ 直接访问 worker 节点 IP:8102 正常
- ❌ 通过 manager 节点 IP:8102 无法访问
- manager 节点上可以看到 8102 端口已经成功暴露
这看起来像是一个典型的 Swarm 跨节点转发异常问题。
二、初步判断与排查思路
Docker Swarm 的 overlay 网络 基于 VXLAN 实现,默认使用:
- UDP 4789:数据平面(容器网络通信)
- TCP/UDP 7946:节点发现与 gossip
因此第一反应是:
是否存在 VXLAN 数据通道异常?
三、UDP 4789 端口连通性测试
1️⃣ worker 节点监听 UDP 4789
nc -u -l 4789 # worker
2️⃣ manager 节点向 worker 发送 UDP 数据
echo test | nc -u <worker_ip> 4789 # manager
3️⃣ 抓包确认是否收到数据
tcpdump -ni any udp port 4789
测试结果
- UDP 数据包 可以正常发送和接收
- 表面看起来 4789 端口是通的
⚠️ 注意:
UDP 端口能通 ≠ VXLAN 一定能正常工作
VXLAN 对报文格式、MTU、策略、状态都有要求
四、直接进行 VXLAN 手动测试(关键步骤)
为了进一步验证 VXLAN 是否真的可用,绕过 Docker,直接用 Linux 内核 VXLAN 做点对点测试。
❌ VXLAN 使用默认端口 4789(测试失败)
worker 节点
ip link del vxlan-test 2>/dev/null
ip link add vxlan-test type vxlan \
id 100 \
dev ens18 \
remote 10.100.23.102 \
dstport 4789
ip addr add 192.168.100.1/24 dev vxlan-test
ip link set vxlan-test up
manager 节点
ip link del vxlan-test 2>/dev/null
ip link add vxlan-test type vxlan \
id 100 \
dev ens18 \
remote 10.100.23.101 \
dstport 4789
ip addr add 192.168.100.2/24 dev vxlan-test
ip link set vxlan-test up
测试结果
- VXLAN 接口创建成功
- 192.168.100.1 ↔ 192.168.100.2 无法通信
👉 说明 VXLAN over UDP 4789 实际不可用
✅ VXLAN 改用 5000 端口(测试通过)
worker 节点
ip link del vxlan-test 2>/dev/null
ip link add vxlan-test type vxlan \
id 100 \
dev ens18 \
remote 10.100.23.102 \
dstport 5000
ip addr add 192.168.100.1/24 dev vxlan-test
ip link set vxlan-test up
manager 节点
ip link del vxlan-test 2>/dev/null
ip link add vxlan-test type vxlan \
id 100 \
dev ens18 \
remote 10.100.23.101 \
dstport 5000
ip addr add 192.168.100.2/24 dev vxlan-test
ip link set vxlan-test up
测试结果
- VXLAN 接口正常
- 192.168.100.1 ↔ 192.168.100.2 通信正常
🎯 这一步基本已经可以下结论了。
五、问题根因分析
综合现象可以确认:
-
UDP 4789 表面可达
-
但 VXLAN 报文被防火墙或网络设备拦截或异常处理
-
可能的原因包括:
- 云厂商安全策略
- 服务器防火墙对 VXLAN 报文的限制
- 上层防火墙/交换机不允许 VXLAN(常见于 4789)
而 5000 端口 未被拦截,因此 VXLAN 可以正常工作。
六、解决方案:修改 Docker Swarm VXLAN 端口
Docker Swarm 支持自定义数据平面端口:
docker swarm init --data-path-port 5000
或者在已有集群中重新初始化 Swarm(注意业务影响)。
修改后:
- Swarm overlay 网络走 UDP 5000
- manager 节点访问 worker 服务恢复正常
- 8102 端口转发问题解决
七、经验总结
🔍 排查 Swarm 网络问题的几个关键点
- 端口能通 ≠ VXLAN 能用
- 一定要 手动 VXLAN 测试
- 不要完全相信
nc的 UDP 测试 - 云环境、防火墙对 4789 非常敏感
--data-path-port是一个被忽略但非常有用的参数
八、结语
这次问题表面是:
“manager 访问不到 worker 的服务”
但本质是:
Docker Swarm overlay 网络 VXLAN 被防火墙拦截
如果你在生产环境遇到类似问题,不要只停留在容器层面排查,
一定要下沉到网络和内核层,VXLAN 手动验证非常关键。