MTU 黑洞导致 Docker 容器网络异常处理

最近更新时间: 2026-05-29 10:21:16

标准网络下的虚拟机 MTU 上限通常为 1480,Docker 默认 1500 会导致大包被分片或丢弃。需要把 Docker daemon 与已创建网络的 MTU 都改成 1480。

常见现象

MTU 不匹配的典型表现是「小包通、大包挂」——三次握手正常,业务数据一上量就异常:

  • curlwget 拉小页面正常,拉大文件中途 hang 住或长时间无进度
  • apt update / apt installyumpipnpm 拉到一半卡住、超时、Connection reset
  • git cloneReceiving objects 阶段卡死或反复重试
  • HTTPS 握手能完成,但加载页面长时间空白;HTTP 请求超时但 ping 正常
  • 容器之间或容器到外网 SSH 能登录但执行 ls 大目录、scp 大文件就断
  • 数据库连接能建立,但跑大结果集查询超时

问题确认

虚拟机内执行:

ip link show eno1 | grep mtu
# 期望看到 mtu 1480
# ip link show en0 | grep mtu # CentOS 系统

ip link show docker0 | grep mtu
# 看到 mtu 1500

或者通过容器执行:

docker run --rm nicolaka/netshoot ping -M do -s 1452 -c 3 8.8.8.8   # 应该通
docker run --rm nicolaka/netshoot ping -M do -s 1453 -c 3 8.8.8.8   # 应该失败:Message too long 或丢包

处理办法

1. 修改 Docker daemon 默认 MTU

编辑 /etc/docker/daemon.json(不存在则新建):

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json > /dev/null <<'EOF'
{
  "mtu": 1480
}
EOF

如果文件已存在其他配置,只需在 JSON 中加入 "mtu": 1480 字段,不要整体覆盖。

然后重启 Docker:

sudo systemctl restart docker

确认默认 bridge 网络配置:

docker network inspect bridge | grep -i mtu
# 期望看到 "com.docker.network.driver.mtu": "1480"

2. 已存在的自定义网络

daemon.jsonmtu 只对默认 bridge 网络生效。已经用 docker network create 创建的网络需要重建,或在创建时显式指定:

docker network create \
  --opt com.docker.network.driver.mtu=1480 \
  my-net

3. docker-compose 场景

docker-compose.yml 中为自定义网络指定 MTU:

networks:
  default:
    driver: bridge
    driver_opts:
      com.docker.network.driver.mtu: 1480

验证 MTU 配置

改完后先确认新容器的网卡 MTU 已生效:

docker run --rm nicolaka/netshoot ip link show eth0 | grep mtu
# 期望看到 mtu 1480

再跑一次不分片边界测试,确认 1480 的包能通过,超过 1480 的包会被拦住:

docker run --rm nicolaka/netshoot ping -M do -s 1452 -c 3 8.8.8.8
# -s 1452 = 1480 - 20 (IP头) - 8 (ICMP头),应该通

docker run --rm nicolaka/netshoot ping -M do -s 1453 -c 3 8.8.8.8
# -s 1453 会让 IP 包超过 1480,应该失败:Message too long 或丢包
以上内容是否对您有帮助?