Docker Swarm IPv6 overlay MTU 大 20 字节:怎样确认并安全调整

用 DF 探测确认 1450/1430 边界,再通过新网络灰度迁移避免直接中断生产服务

Docker Swarm 使用 IPv6 data path 时,确认 overlay MTU 比真实路径大 20 字节的问题,并通过新网络灰度调整与安全回退。

Docker Swarm 把 IPv6 地址用于节点间 data path 时,如果普通小请求正常、大响应或接近 MTU 的连接卡住,先检查 overlay 接口是否仍为 1450,而底层网卡 MTU 是 1500。Moby 上游在 2026 年 9 月记录的边界是:IPv6 外层的 VXLAN 头部需要 70 字节,但当前 overlay 按 50 字节扣减,容器接口因此比真实路径大 20 字节。未加密网络在 1500 底层上应按 1430 验证,而不是直接把防火墙、DNS 或应用判为故障。

本文适用于 Linux Docker Engine 25.0.0 以后、Swarm 节点间使用 IPv6 data path 的场景。只读检查不会收费,也不会修改数据。调整 MTU 需要新建网络并迁移服务,会滚动重启任务;删除现有 overlay 或 ingress 可能直接中断通信。默认做法是先新建测试网络验证,再逐个无状态服务迁移,不能原地删除生产网络。

先确认 data path 确实走 IPv6

在 Swarm 管理节点执行以下只读命令。把 YOUR_NETWORK 和 YOUR_SERVICE 换成实际名称。docker info 与 docker node inspect 用于确认集群和节点地址,网络与服务检查用于确认故障流量经过哪个 overlay。

docker version
docker info --format '{{json .Swarm}}'
docker node ls
docker node inspect self --pretty
docker network inspect YOUR_NETWORK
docker service inspect YOUR_SERVICE --pretty
docker service ps YOUR_SERVICE --no-trunc

如果节点的 data path 地址是 IPv6,且调用方与目标任务分布在不同节点,才符合本问题前提。若只使用 IPv4 data path,或失败发生在公网入口、宿主机端口和 routing mesh,应转向对应网络路径排查,不要套用 20 字节结论。

怎样确认 1450 与 1430 的边界

先进入一个已经带有 ping 工具的测试容器,读取接口 MTU。不要为了测试在生产应用容器内安装软件。以下 eth0 只是常见名称,应先用 ip link 确认真实 overlay 接口。

ip link
cat /sys/class/net/eth0/mtu
ip -6 route

底层网卡 MTU 为 1500、overlay 接口显示 1450,并不代表跨节点一定能承载 1450 字节。用不会写数据的目标容器名做 DF 探测;-M do 表示禁止分片,-s 是 ICMP 数据长度。上游复现中,1402 加 IPv4 ICMP 头后形成 1430 字节包可以通过,1422 对应 1450 字节包会失败。

ping -c 3 -W 2 -M do -s 1402 TARGET_SERVICE
ping -c 3 -W 2 -M do -s 1422 TARGET_SERVICE

若 1430 成功而 1450 稳定失败,同时小请求正常,特征与 Moby #53765 一致。若两者都失败,先检查服务发现、节点间 4789/UDP、7946/TCP+UDP 与底层 IPv6 路由;若两者都成功,则当前路径可能已通过更大的底层 MTU、路径 MTU 发现或其他设置避开该边界。

结果判断下一步
IPv6 data path,1450 接口;1430 通、1450 不通高度符合 20 字节 MTU 偏差新建较小 MTU 的测试 overlay
1430 与 1450 都不通不只是 MTU 偏差查路由、防火墙、服务发现和任务状态
小包通,大 TCP 响应卡住可能是 PMTU/MSS 问题结合 tracepath、抓包与应用超时继续确认
只在同一节点经宿主机 IP 失败属于另一条 Swarm 路径参考 29.8.0 同节点端口回归排查

用新网络灰度验证,不要删除原网络

上游给出的临时方案,是创建网络时把 com.docker.network.driver.mtu 设为比底层 MTU 小 20 字节。底层为 1500 时传入 1480,Docker 再扣除当前固定的 50 字节,容器接口得到 1430。以下命令会创建新 overlay,但不会自动迁移任何服务;名称和网段要按现场替换,并避开现有 VPC、VPN 与容器网段。

docker network create \
  --driver overlay \
  --attachable \
  --opt com.docker.network.driver.mtu=1480 \
  YOUR_IPV6_MTU_TEST_NETWORK

docker network inspect YOUR_IPV6_MTU_TEST_NETWORK

先把一个无状态测试服务接入新网络,重复接口 MTU、1430/1450 探测和真实健康检查。不要同时迁移数据库、队列或全部反向代理。若启用了 --opt encrypted,还存在 IPsec 额外开销;上游提到的 1404 仍是未实测说明,本文不把它写成生产固定值,应在自己的路径上逐级探测。

迁移服务时怎样控制停机和费用

创建 overlay 网络本身通常不产生单独云资源费用,但跨节点流量、云服务器和负载均衡仍按云厂商规则计费。服务增加或移除网络会触发任务更新,可能出现短暂连接重建。先确认副本数、更新并行度、健康检查和回滚配置,再在低峰迁移一个无状态服务。

docker service inspect YOUR_SERVICE --pretty
docker service update --network-add YOUR_IPV6_MTU_TEST_NETWORK YOUR_SERVICE
docker service ps YOUR_SERVICE --no-trunc

新网络验证通过后,再让调用方和目标服务都使用新网络,并按服务名访问。确认一个完整业务周期稳定后,才评估移除旧网络连接。原网络只有在没有服务与独立容器占用、且回滚窗口结束后才能删除。

失败分支与回退

若接入新网络后 DNS 解析失败,先确认调用方和目标服务是否同时连接该网络;若任务反复重启,检查镜像启动参数、健康检查和调度事件,不要继续扩大迁移。若 1430 仍不能通过,说明底层实际 MTU 可能低于 1500,应用 tracepath 或云网络文档确认真实上限,再重新计算测试值。

回退时先把服务流量切回原网络和原服务地址,再执行 docker service update --network-rm YOUR_IPV6_MTU_TEST_NETWORK YOUR_SERVICE。确认任务恢复、原路径可用后再删除测试网络。回退不会恢复已经删除的数据,因此本流程从不删除卷、镜像或 Docker 数据目录。

修复后如何验收

  1. 新网络内接口 MTU 与计划值一致,1500 底层的未加密测试网络应看到 1430。
  2. 跨节点 1430 字节 DF 探测稳定成功,真实 HTTP 健康检查和大响应不再卡住。
  3. docker node ls 中节点为 Ready,docker service ps 中任务没有持续重启。
  4. 应用错误率、超时与重传恢复到变更前正常范围。
  5. 记录临时 MTU、底层 MTU、网络名称与回退步骤;上游修复发布后先在测试网络复核,不直接全量恢复默认值。

相关教程

官方与上游来源

云服务器教程Docker Swarm 29.8.0 升级后同节点宿主机 IP 端口不通:怎样取证与回退2026-09-30云服务器教程Docker 执行 buildx prune 后缓存全失效:怎样判断并恢复 BuildKit 命中2026-09-28云服务器教程Docker push 报 timeout awaiting response headers:怎样排查 containerd 镜像提交超时2026-09-27

加入开发者交流社区

与全球开发者、运维和工作室一起交流技术、分享经验、配置、账号与最新优惠信息

  • 云平台使用交流
  • 资源优惠信息
  • 最新教程与资讯
  • 开发者经验分享
联系 Telegram 客服
加入开发者交流社区