什么是网络 MTU 问题
Docker 网络默认 MTU 1500。当链路叠加了 VXLAN、IPsec 或某些云网络封装后,可用 MTU 变小,而路径上的中间设备又可能不返回需要分片的 ICMP 消息,于是形成 MTU 黑洞:小请求正常,一传大响应就卡死。典型症状是 TLS 握手成功但下载中途挂起。
基本信息
| 默认值 | 1500(bridge 与 overlay 视驱动而定) |
|---|---|
| 问题场景 | overlay/VXLAN、IPsec、部分云网络 |
| 调整方式 | docker network create -o com.docker.network.driver.mtu=1400 |
| 验证命令 | ping -M do -s <大小> 目标(Linux) |
| 生效时机 | 网络创建时确定,改动需重建网络 |
典型使用场景
- 跨主机 overlay 网络中容器间大文件传输卡死时定位问题
- VPN 或专线链路上部署容器,先按封装开销下调 MTU
- 云主机接入容器网络,厂商链路有额外封装时做容量核算
- 排障采集:先验证大包能否通过,再判断是否为应用层问题
- 新建容器网络时按链路实际 MTU 预先规划,避免上线后返工
创建与验证
创建与验证
# 建网时下调 MTU,按底层链路减掉封装开销来定值
docker network create -d bridge \
-o com.docker.network.driver.mtu=1400 app-net
docker run --rm --network app-net alpine ip link show eth0 # 核对接口 MTU
# 用不分片的大包验证:能通过说明路径 MTU 足够
docker run --rm --network app-net nicolaka/netshoot \
ping -M do -s 1400 -c2 10.88.0.10症状与含义
| 现象 | 可能含义 | 下一步 |
|---|---|---|
| 小请求正常,大响应卡死 | MTU 黑洞,大包被静默丢弃 | 按链路封装下调 MTU 并复测 |
| 小包通、大包不通 | 路径 MTU 小于接口 MTU | 用 -M do 逐步试探实际值 |
| 握手后传数据挂起 | 中间设备不回 ICMP 分片消息 | 联系链路方确认封装开销 |
| 仅特定网段异常 | 该路径有额外隧道封装 | 单独核查该路径 MTU |
MTU 值应按底层链路实际减掉封装开销来定,调整后一定要用 ping -M do 复测大包能否通过,而不是只看接口值对不对。
overlay 网络的 MTU 由 daemon 的 mtu 选项或网络创建参数决定,跨主机通信时两端要保持一致;只在一端下调,另一个方向上仍然会丢大包。
同一宿主上不同驱动可以有各自的 MTU,排障时先确认问题发生在哪一层网络,再按该层的实际值核对,不要只查一处。