LabHub
学习 学习路径 课程

网络基础

MTU 与路径 — 只因为大小就失败的通信

在 LabHub 中继续学习

一句话总结

TCP 只根据本机接口的 MTU 决定报文段大小,不知道路径中间是否有更窄的区段;若阻断告知这一情况的 ICMP,就会形成只有大数据包悄然消失的黑洞。

概念图: 1500 字节 · 1460 字节 · 双方都只根据自己的接口 MTU 决定 MSS。 · 只有超过阈值的数据包会消失,所以症状按大小分化。

为什么需要它

有一种故障的症状非常独特:

出现这种组合时,几乎可以直接判断为路径 MTU 问题。它通常发生在新增 VPN、隧道、覆盖网络或路径变化后。

工作原理

MTU 是接口一次可发送的最大 IP 数据包大小,以太网默认是 1500 字节。TCP 减去 20 字节 IPv4 首部和 20 字节 TCP 首部,把 1460 字节设为 MSS,并在握手的 SYN 包选项中告知对方。

关键在于:双方都只根据自己的接口 MTU 决定 MSS。 没人知道中间是否有更窄的链路。即使双方同意交换 1460 字节,中间若有 1420 字节的隧道也无法兑现。

因此小请求能成功:健康检查用一个报文段即可通过,只有超过阈值的数据包会消失,所以症状按大小分化。 TLS 握手卡住也一样,ClientHello 很小,而服务器证书链可达数千字节,很快就会产生满尺寸报文段。

TCP 原本通过**路径 MTU 发现(PMTUD)**解决此问题。Linux 在 TCP 包上设置 DF(禁止分片)位;中间路由器收到大于下一跳 MTU 的 DF 包时将其丢弃,并以 **ICMP 类型 3 代码 4(Fragmentation Needed)**告知下一跳 MTU。发送方缓存该值,缩小报文段后重发。

若阻断该 ICMP,发送方会不断发送同样大的包并不断被丢弃,重传也没有用。连接仍处于 ESTABLISHED,直到应用自己的超时才结束,这就是 PMTUD 黑洞

“为了安全阻断全部 ICMP”本身会制造故障。可酌情阻断 echo request/reply,但类型 3 代码 4 必须放行。IPv6 更无选择,因为路由器不负责分片,ICMPv6 Packet Too Big(类型 2)是必需的。

记住封装开销有助于诊断:VXLAN 50 字节(有效 MTU 1450),WireGuard 60–80 字节(1440–1420),GRE 24 字节(1476),IPsec ESP 最多约 73 字节。

实际工作中的表现

Kubernetes 因覆盖网络经常遇到此问题。节点接口为 1500 时,若 VXLAN 接口和 Pod eth0 也设为 1500,就会形成黑洞;VXLAN 占用 50 字节,应该设为 1450。典型症状是 Pod 间小请求正常、大正文 POST 卡住,kubectl exec 正常,但日志很多的 Pod 执行 kubectl logs 时中途停住。

现实方案是在隧道入口进行 MSS 钳制:路由器直接调低经过的 SYN 包中的 MSS,不再依赖 ICMP。但它只适用于 TCP,QUIC 等 UDP 协议仍须自行调整大小。

后续测验将确认什么

确认看到“小请求正常,大响应卡住”时能立即想到 MTU,并能解释为何它会无错误地停住。