容器能 ping 通 8.8.8.8 但无法解析域名或超时,大概率是 dns 配置、docker0 网桥异常、net.ipv4.ip_forward 未启用或 iptables nat 规则缺失所致,需依次检查这四点。

容器能 ping 通 8.8.8.8 但无法访问域名或超时,大概率不是容器“没网”,而是宿主机网络转发、NAT 规则或 DNS 配置断在了中间环节。直接查这四个地方最省时间。
检查 docker0 网桥是否存在且有合法 IP
所有 bridge 模式容器都靠它出向,没它等于没出口。
- 运行
ip addr show docker0,必须看到类似inet 172.17.0.1/16的 IPv4 地址;若输出为空,说明网桥根本没创建 - 若地址是
0.0.0.0或和物理网卡(如eth0)同网段(比如也是192.168.1.x),说明冲突,后续转发会失败 - 临时修复:停 Docker(
systemctl stop docker),清残留(iptables -t nat -F+ifconfig docker0 down),再启动 - 彻底重建:停服务后删
/var/lib/docker/network/*,再启服务,Docker 会重新初始化网桥
确认 net.ipv4.ip_forward 已启用且生效
这是 Linux 内核开关,不打开,宿主机就拒绝把 docker0 进来的包转发出去——哪怕 iptables 规则全对也没用。
- 查状态:
cat /proc/sys/net/ipv4/ip_forward,返回1才算开 - 临时开:
sysctl -w net.ipv4.ip_forward=1 - 永久开:往
/etc/sysctl.conf追加net.ipv4.ip_forward=1,再执行sysctl -p - 特别注意 CentOS/RHEL 系统:还要确保对应出口网卡也开了转发,例如
cat /proc/sys/net/ipv4/conf/eth0/forwarding也得是1;否则 NetworkManager 会把它关掉
验证 iptables NAT 规则是否完整
Docker 启动时本该自动加一条 SNAT 规则,把容器源 IP 替换成宿主机 IP。一旦被 firewalld、ufw 或手动清理过,外网回包就找不到路。
- 查规则:
iptables -t nat -S POSTROUTING | grep docker - 正常应看到:
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE - 若缺失,手动补(替换
eth0为你的实际出口网卡):iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -o eth0 -j MASQUERADE - 用 firewalld 的系统,别只改 iptables:
firewall-cmd --add-masquerade --permanent && firewall-cmd --reload
排查 DNS 解析导致的“假性超时”
很多报错写 curl: (7) Failed to connect 或 Connection timed out,其实底层是 getaddrinfo() 卡住——压根没发出去,只是域名死在解析阶段。
- 先进容器:
docker exec -it <container> sh</container> - 先试 IP:
ping -c 3 8.8.8.8→ 若通,基本排除路由/NAT 问题 - 再试域名:
nslookup google.com或curl -v http://httpbin.org/ip(看是否卡在 DNS) - 优先改 Docker daemon 全局配置:
/etc/docker/daemon.json加"dns": ["114.114.114.114", "8.8.8.8"],然后systemctl restart docker - 避免改容器内
/etc/resolv.conf:它可能被 Docker 覆盖,且不持久
真正难缠的是 IPv4 转发和网卡级 forwarding 双重关闭,或者 firewalld 和 iptables 规则互相覆盖。这两个点经常被忽略,一查就卡半天。











