返回首页

Docker 和 OpenStack 中的 MTU 不匹配:如何修复 CI/CD 失败

本文解释了 Docker 容器与 OpenStack 覆盖网络之间 MTU 不匹配如何导致 CI/CD 管道失败。介绍了诊断方法、分步问题解决方案以及防止其再次发生的最佳实践。

构建失败?可能是 Docker 中的 MTU 不匹配造成的
Advertisement 728x90

# Docker 与 OpenStack MTU 不匹配如何破坏 CI/CD:诊断与修复

周五晚上的构建失败往往不是随机故障——通常是 Docker 容器与 OpenStack 覆盖网络之间的 MTU 不匹配。只有在大规模数据传输时才会暴露问题,比如克隆仓库,小请求则一切正常。这会造成网络看似正常,直到真实负载来袭。

为什么小请求成功,大请求却失败

这个问题典型特征是选择性。像 curl -Iping 这样的小数据包命令总是成功。问题出现在需要大块数据传输的操作上:git clonedocker pull、工件下载。罪魁祸首?最大传输单元(MTU)——无需分片即可传输的最大 IP 数据包大小。

标准以太网网络 MTU 为 1500 字节。但在 OpenStack 等云环境中,VXLAN 或 GRE 等覆盖技术通过为每个数据包添加约 50 字节开销来构建隔离网络。因此,即便物理网络支持 1500,虚拟机数据包实际只剩 1450 字节。

Google AdInline article slot

Docker 默认使用 MTU 1500 的桥接网络,忽略底层基础设施特性。容器按此规格构建数据包。当抵达主机 1450 MTU 接口时,因 DF(Don't Fragment,不分片)标志无法传输。理想情况下,路径 MTU 发现机制会介入,但防火墙、安全组或路由器问题常阻挡“需要分片”的 ICMP 消息。

30 秒诊断问题

用这三个命令快速发现 MTU 不匹配:

  • 检查主机网络接口 MTU:

```

Google AdInline article slot

ip link show ens3 | grep mtu

```

在 OpenStack 中,预期值为 mtu 1450

Google AdInline article slot
  • 检查容器内 MTU:

```

docker run --rm alpine ip link show eth0 | grep mtu

```

Docker 默认 mtu 1500。如果高于主机,即为问题所在。

  • 运行禁止分片的 ping 测试:

```

docker run --rm alpine ping -s 1422 -M do -c 3 gitlab.example.com

docker run --rm alpine ping -s 1423 -M do -c 3 gitlab.example.com

```

第一个(1422 = 1450 − 28)应成功;第二个应报 Message too long

逐步修复

配置 Docker MTU

核心修复:让 Docker 使用正确 MTU。编辑 /etc/docker/daemon.json

{
  "mtu": 1450
}

重启 Docker 服务:

sudo systemctl restart docker

处理现有网络

注意:daemon.json 修改仅影响新网络。现存网络——尤其是 Docker Compose 创建的——保留旧 MTU。两种方案:

  • 全部重建:

```

docker compose down && docker compose up -d

```

  • 在 Docker Compose 中显式设置 MTU:

```yaml

networks:

app-net:

driver: bridge

driver_opts:

com.docker.network.driver.mtu: 1450

```

收尾步骤

重启 GitLab Runner 并测试:

sudo gitlab-runner restart
 docker run --rm alpine ping -s 1422 -M do -c 3 gitlab.example.com

测试通过,即大功告成。

常见陷阱与最佳实践

  • 别盲目降低 MTU “以防万一”。降到 1300 会因额外数据包导致吞吐量下降 10-15%。使用精确诊断值。
  • 自动化配置。将 MTU 写入基础设施配置(Terraform、Ansible、cloud-init)——避免手动调整。
  • 注意自定义网络daemon.json 不影响现有网络。用 docker network inspect 检查。
  • 别指望路径 MTU 发现。云环境常因 ICMP 阻挡而失效。

关键要点

  • MTU 不匹配仅在大规模数据传输时发作,隐蔽性强。
  • OpenStack 覆盖网络头部占用 50 字节 MTU。
  • Docker 默认 1500 在云中冲突。
  • 修复:让 Docker MTU 匹配主机接口。
  • 在部署流水线中自动化设置。

— Editorial Team

Advertisement 728x90

继续阅读