核心是让容器网络层mtu与跨主机路径最小mtu对齐,避免大包静默丢弃;需实证测出真实路径mtu(如1450),查宿主机网卡mtu、cni封装开销,统一在cni层设全局mtu,必要时pod内显式配置,并验证生效。
核心是让容器网络层 mtu 与跨主机路径中最小 mtu 对齐,避免因包过大被静默丢弃——小包通、大包断,本质不是带宽问题,而是路径封装开销未被适配。
先实证定位真实路径 MTU
别猜,用 ICMP 测试直接抓出瓶颈点:
- 进任一跨主机通信的容器,执行:
ping -M do -s 1472 8.8.8.8(1472 + 28 = 1500);无响应就逐步减-s值(1420 → 1372 → 1320),直到能通,该值加 28 即为实际路径 MTU(如 1420+28=1448 → 取整 1450) - 查宿主机物理网卡:
ip link show eth0 | grep mtu,云环境常见为 1450 或 1400 - 查 CNI 隧道开销:Calico 默认 VXLAN 封装加 50 字节,Flannel UDP 模式加 50,Cilium Geneve 加 64——推荐 MTU 往往比底层网卡小 50~100
- 看内核证据:
dmesg | grep "too long",出现dropped packet, size 1514 > 1450就是铁证
统一在 CNI 层设全局 MTU(最稳方案)
让所有新建 Pod 自动继承,不依赖单个容器配置:
-
Calico:编辑 IPPool(如
default-ipv4-ippool),添加mtu: 1450字段,kubectl apply生效 -
Flannel:修改
kube-flannel-cfgConfigMap 中的net-conf.json,加入"MTU": 1450,重启 flanneld DaemonSet -
Cilium:Helm values 设置
global.devices.eth0.mtu=1450,或通过CiliumClusterwideNetworkPolicy强制下发
对 Windows 容器或特殊 Pod 显式注入
当 CNI 不支持动态 MTU 或需差异化配置时,靠容器自身能力补位:
- Pod spec 中必须加
securityContext.capabilities.add: ["NET_ADMIN"] - 传入环境变量:
env: [{name: MTU, value: "1450"}] - 启动脚本里执行:
ip link set eth0 mtu $MTU(Linux)或netsh interface ipv4 set subinterface "Ethernet" mtu=1450 store=persistent(Windows)
验证是否真正生效
改完不验证等于没改:
- 进 Pod 执行:
ip link show eth0 | grep mtu,确认输出为设定值(如mtu 1450) - 跨主机跑大包测试:
curl -v --data-binary @1MB.bin http://other-node-service,观察是否仍超时或重试 - 抓包确认无分片:
tshark -i eth0 -Y "ip.frag_offset > 0 || ip.flags.mf == 1",结果为空才说明已规避分片











