记一次 Docker Swarm 集群下访问异常的排查:VXLAN 4789 端口被阻断

8 阅读3分钟

一、问题背景

在一套 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 网络问题的几个关键点

  1. 端口能通 ≠ VXLAN 能用
  2. 一定要 手动 VXLAN 测试
  3. 不要完全相信 nc 的 UDP 测试
  4. 云环境、防火墙对 4789 非常敏感
  5. --data-path-port 是一个被忽略但非常有用的参数

八、结语

这次问题表面是:

“manager 访问不到 worker 的服务”

但本质是:

Docker Swarm overlay 网络 VXLAN 被防火墙拦截

如果你在生产环境遇到类似问题,不要只停留在容器层面排查
一定要下沉到网络和内核层,VXLAN 手动验证非常关键。