核心是让容器网络路径上的mtu值统一匹配最小链路mtu,而非盲目调大;需先用ping -m do -s等命令实证检测路径mtu,再通过修改daemon.json设全局mtu或在docker-compose.yml中networks下配置driver_opts: com.docker.network.driver.mtu修复。

核心是让容器网络路径上的 MTU 值统一匹配最小链路 MTU,而不是盲目调大。Docker Compose 默认使用 bridge 网络(即 docker0 网桥),一旦宿主机物理网卡、云平台虚拟交换机或隧道封装层的 MTU 小于 1500(如常见 1450、1400、1492),而容器仍按默认 1500 发包,就会触发静默丢包——小包正常、大包中断、TLS 握手超时、文件上传卡死。
先实证确认是不是 MTU 问题
别猜,用命令验证:
- 在容器内执行:ping -M do -s 1472 8.8.8.8(1472 + 28 字节头 = 1500)。失败则逐步减小 -s 值(如 1400、1300),直到能通;该值 + 28 就是当前有效路径 MTU
- 查宿主机网卡:ip link show eth0 | grep mtu(注意:云主机常为 1450)
- 查 docker0:ip link show docker0 | grep mtu(若显示 1500 而宿主机是 1450,已错配)
- 看内核日志:dmesg | grep "too long",出现 “dropped packet, size 1514 > 1500” 是典型证据
修复 Docker Compose 默认 bridge 网络的 MTU
这是最常见场景,影响所有未指定 network 的服务:
- 修改 /etc/docker/daemon.json,加入:{"mtu": 1450}(数值需与你测出的路径 MTU 一致)
- 重启 Docker:sudo systemctl restart docker
- 验证:ip link show docker0 应显示对应 mtu 值,之后新启动的 Compose 服务自动继承
- 已有容器需重新 up(docker-compose down && up -d),旧容器不会自动更新
对自定义网络或特定服务显式设 MTU
若你在 docker-compose.yml 中定义了自定义网络(如 driver: bridge),必须显式注入 MTU:
- 在 docker-compose.yml 的 networks 段添加:
driver_opts:
com.docker.network.driver.mtu: "1450" - 完整示例:
networks:
app-network:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: "1450" - 这样所有接入该网络的服务(包括通过 service_name 通信的容器)都使用统一 MTU,避免内部桥接再出错配
补充验证与注意事项
修复后务必交叉验证:
- 进任一容器执行 ip link show eth0 | grep mtu,确认值已生效
- 用 curl -v --data-binary @largefile.zip http://other-service:8080/upload 测试真实业务大包是否稳定
- 若用 Kubernetes + Compose(如 Kompose 或 Kind),MTU 需同步适配 CNI 插件(如 Calico 的 ippool.mtu)
- Windows 容器同理,但需确保基础镜像支持 PowerShell 网络配置或已启用 NET_ADMIN 权限











