这个坑值得记一笔。腾讯云 2 核 4G 的 Debian 12 上跑 Docker 24.0,容器内 ping 8.8.8.8 全部超时,curl -I https://www.baidu.com 却能返回 200,运维据此判断网络不通,白查了两小时。

刚开始盯着「docker 的 iptables 规则只处理 TCP 与 UDP 的 MASQUERADE,ICMP 走的是另一条路径」,折腾了半个多小时,排掉了。

真正麻烦的地方在于,几个原因的现象几乎一样。ICMP 属于需要额外放行的协议,安全组默认只放行 TCP,ping 失败不代表出网不通;容器默认没开 NET_RAW 能力,部分镜像里的 ping 根本没有权限发原始包;自定义网络开了 internal 选项,容器只能访问同网段,DNS 却还能走宿主机转发。

第一件事是用 TCP 的方式确认出网是否正常

docker exec -it web curl -sS -o /dev/null -w '%{http_code}' https://www.baidu.com

接着在容器里查路由和出口地址

docker exec -it web ip route get 1.1.1.1

补上 NET_RAW 能力后再测 ICMP

docker run --rm --cap-add NET_RAW alpine ping -c 2 8.8.8.8

剩下的就是核对自定义网络是否被设成 internal

docker network inspect bridge -f '{{.Internal}}'

改完先别撤,确认这几项。容器内 curl 返回 200 且耗时在百毫秒级,加上 NET_RAW 后 ping 有回包,docker network inspect 的 Internal 为 false。

把 ping 通当成网络健康的判断标准很容易误判,云上先看安全组的协议维度;排查出网优先用 curl 或 nc 打具体端口。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189