记录一次docker网络故障-mtu

事件: docker-network

简述

  1. 从云服务器上通过 wg 隧道将网站的请求转到内网
  2. 配置后,页面打开无响应最后超时

排查步骤

  1. 从云服务器宿主机测试目标站点
1
2
3
4
5
curl -i -s -o /dev/null -w "%{http_code}\n" http://192.168.5.30  -H "Host: www.chenwx.top"
200

curl -i http://192.168.5.30  -H "Host: www.chenwx.top"
# 正常打开页面

查看内网服务的nginx日志, 正常响应, 且耗时很低。

  1. 更换容器网络进行验证
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
docker run --rm -it --network host nginx:1.25.3-alpine \
     curl -I -s -o /dev/null -w "%{http_code}\n" \
     -H "Host: www.chenwx.top" http://192.168.5.30
成功响应 200

docker run --rm -it --network host nginx:1.25.3-alpine \
     curl -H "Host: www.chenwx.top" http://192.168.5.30
成功响应 html

docker run --rm -it --network bridge nginx:1.25.3-alpine \
     curl -I -s -o /dev/null -w "%{http_code}\n" \
     -H "Host: www.chenwx.top" http://192.168.5.30
成功响应 200

docker run --rm -it --network bridge nginx:1.25.3-alpine \
     curl -H "Host: www.chenwx.top" http://192.168.5.30
未响应 html, 阻塞

说明问题只存在于桥接网络, 且小包正常, 带数据的大包会失败, 99%是 MTU 的问题。
因为我的 wg 网络设置的 MTU 值是 1408, 再大腾讯云的服务器就不行了;

  1. 检查当前 MTU
1
2
3
4
5
6
7
8
9
[root@ecs2 nginx]# docker network inspect bridge   --format='{{json .Options}}' | jq .
{
  "com.docker.network.bridge.default_bridge": "true",
  "com.docker.network.bridge.enable_icc": "true",
  "com.docker.network.bridge.enable_ip_masquerade": "true",
  "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
  "com.docker.network.bridge.name": "docker0",
  "com.docker.network.driver.mtu": "1500"
}

修改值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
/etc/docker/daemon.json
{
  "mtu": 1408
}

# 再看值已经变了
[root@ecs2 nginx]# docker network inspect bridge   --format='{{json .Options}}' | jq .
{
  "com.docker.network.bridge.default_bridge": "true",
  "com.docker.network.bridge.enable_icc": "true",
  "com.docker.network.bridge.enable_ip_masquerade": "true",
  "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
  "com.docker.network.bridge.name": "docker0",
  "com.docker.network.driver.mtu": "1408"
}
  1. 再次测试还是失败

确认因为自己用的一个单独创建的 docker 网络, 所以值是没有变的, 即 daemon.json 内的 mtu 不影响独立创建的网络

1
2
docker network inspect traefik  --format='{{json .Options}}' | jq .
{}      # 实际还是个空值
  1. 删除原有网络后, 再新建一个自定义 MTU 的网络
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11

docker compose down

docker network rm traefik

docker network create traefik --opt com.docker.network.driver.mtu=1408

[root@ecs2 nginx]# docker network inspect traefik   --format='{{json .Options}}' | jq .
{
  "com.docker.network.driver.mtu": "1408"
}
  1. 启动服务, 验证通过
Licensed under CC BY-NC-SA 4.0
转载或引用本文时请遵守许可协议,知会作者并注明出处
不得用于商业用途!
最后更新于 2025-08-24 00:00 UTC