核心目标是使容器数据包适配整条传输路径mtu,避免大包丢弃;需先验证路径mtu(如ping -m do -s 1420),再通过修改/etc/docker/daemon.json中"mtu"值并重启docker服务持久生效,或优先使用自定义bridge网络指定mtu。
修改 docker 默认 bridge 网络(即 docker0 网桥)的 mtu 值,核心目标不是盲目调大,而是让容器发出的数据包能完整通过整条传输路径——尤其当宿主机网卡本身 mtu 小于 1500(如云平台常见 1450 或 1400)时,不匹配就会导致大包被静默丢弃或强制分片,严重影响大文件、数据库同步、日志传输等场景。
先确认是否真由 MTU 引发问题
跳过验证直接改配置,容易白忙一场:
- 在容器内执行:
ping -M do -s 1472 8.8.8.8(1472 + 28 字节头 = 1500)。无响应或提示 “Packet too big”,说明路径不支持标准 MTU - 逐步减小
-s值(如试 1420 → 1372 → 1320),直到 ping 通;该值加 28 即为实际路径 MTU(例如 1420+28=1448 → 取整为 1450) - 查宿主机物理网卡:运行
ip link show eth0 | grep mtu,常见云环境返回 1450 或 1400 - 查当前
docker0:运行ip link show docker0 | grep mtu,若显示 1500 而宿主机是 1450,就存在错配风险
修改默认 docker0 网桥 MTU 的正确方式
默认 docker0 是 Docker 守护进程启动时自动创建的,不能运行时直接改。必须通过守护进程配置持久化生效:
- 编辑
/etc/docker/daemon.json,加入"mtu": 1450(数值需与宿主机网卡一致) - 保存后重启 Docker 服务:
sudo systemctl restart docker - 重启会导致所有运行中容器停止,所以建议安排维护窗口
- 重启后验证:
ip link show docker0 | grep mtu应显示新值;再进任一新启容器检查ip link | grep mtu
为什么推荐用自定义 bridge 替代默认 docker0
默认 docker0 不仅 MTU 难动态调整,还存在 DNS 不支持、IP 易漂移、网络混杂等隐患。生产环境更推荐显式创建自定义 bridge:
- 创建时直接指定 MTU:
docker network create --driver bridge --opt com.docker.network.driver.mtu=1450 my-bridge - 容器启动时指定该网络:
docker run --network my-bridge ... - 使用 Docker Compose 时,在
networks下声明并设driver_opts:
app-network:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: "1450"
配合 MTU 调整的必要补充
MTU 改对了只是第一步,缓冲区不匹配照样卡顿:
- 大包传输需足够大的 socket 缓冲区:应用代码中显式设置
SO_RCVBUF/SO_SNDBUF(如 4–8 MB),否则内核会截断 - 若用 host 模式或 macvlan,可进一步调高内核参数:
net.core.rmem_max和net.ipv4.tcp_rmem,确保 TCP 窗口能撑住高带宽延迟积(BDP) - 禁用 TCP SACK(
net.ipv4.tcp_sack=0)在某些 VXLAN 或老旧中间设备环境下可避免重传异常











