容器内 ping 不通外网但宿主机能 ping 通,怎么排查 Docker 网络配置?

这种情况通常是宿主机内核 IP 转发未开启,或者 Docker 依赖的 iptables NAT 规则丢失导致的。优先检查内核转发配置和防火墙策略,大多数情况下重启 Docker 服务或修正 sysctl 配置即可恢复。

先说结论:宿主机网络正常但容器不通,问题多半出在宿主机内核转发开关或 Docker 的 NAT 规则上。

  • 先确认:检查宿主机 net.ipv4.ip_forward 是否为 1
  • 先处理:重启 Docker 服务或手动修复 iptables 规则
  • 再验证:在容器内 ping 外网 IP 及域名测试连通性

命令速用版

以下是排查和修复过程中最常用的几条命令,可直接在宿主机终端执行:

# 1. 检查 IP 转发状态
cat /proc/sys/net/ipv4/ip_forward

# 2. 临时开启 IP 转发
sudo sysctl -w net.ipv4.ip_forward=1

# 3. 重启 Docker 服务(重建 NAT 规则)
sudo systemctl restart docker

# 4. 检查 iptables NAT 规则
sudo iptables -t nat -L -n | grep MASQUERADE

# 5. 查看 Docker 网络详情
docker network inspect bridge

为什么会这样

Docker 容器默认运行在隔离的网络命名空间中,通过虚拟网桥 docker0 与宿主机通信。容器访问外网时,数据包需要经过宿主机进行 NAT 转发。如果宿主机内核禁用了 IP 转发功能,或者 iptables 中负责地址转换的 MASQUERADE 规则缺失,数据包就无法被正确路由到外部网络。此外,DNS 配置错误也会导致能 ping 通 IP 但无法解析域名的情况。

分步处理

第一步:检查并开启 IP 转发
执行cat /proc/sys/net/ipv4/ip_forward,若输出为 0,说明转发未开启。可执行sudo sysctl -w net.ipv4.ip_forward=1临时开启。若要永久生效,需将net.ipv4.ip_forward=1写入/etc/sysctl.conf并执行sysctl -p

第二步:恢复 NAT 规则
执行sudo iptables -t nat -L -n | grep MASQUERADE查看规则。若无输出,说明规则丢失。通常执行sudo systemctl restart docker即可让 Docker 自动重建规则。

注意:若 FORWARD 链策略为 DROP,可临时运行sudo iptables -P FORWARD ACCEPT测试,生产环境建议配置更精细的防火墙规则,该操作会开放所有转发流量,可能降低宿主机网络安全性。

第三步:配置 DNS
若能 ping 通 8.8.8.8 但无法解析域名,需配置 Docker 守护进程 DNS。编辑/etc/docker/daemon.json,添加{"dns": ["114.114.114.114", "8.8.8.8"]},然后重启 Docker 服务。

第四步:检查防火墙干扰
部分发行版默认的 firewalld 可能与 Docker 冲突。若上述步骤无效,尝试暂时禁用 firewalld 或配置其适配 Docker 网络。

第五步:检查 Docker 网络详情
使用docker network inspect bridge查看网桥配置。检查 "IPAM" 配置中 "Subnet" 和 "Gateway" 是否正常,确认容器是否获取到了预期网段的 IP 地址。

怎么验证是否生效

启动一个测试容器,例如docker run -it `--rm` alpine ping 8.8.8.8

成功示例:

PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=57 time=20.123 ms

失败示例:

ping: sendto: Network unreachable
# 或
ping: bad address 'google.com'

若能收到回复,说明网络层连通。接着测试域名解析,执行docker run -it `--rm` alpine ping google.com。若两者均正常,则网络配置已修复。

常见坑

  • 默认 bridge 网络下,容器间无法通过容器名互相 ping 通,需使用自定义网络或 IP 地址。
  • 重启宿主机后,若未配置 sysctl 永久生效,IP 转发可能会恢复为关闭状态。
  • 手动修改 iptables 规则后重启 Docker,规则可能会被 Docker 覆盖或重置,建议优先通过重启 Docker 服务来修复规则。
  • 修改 sysctl 配置若未正确处理文件权限可能导致生效失败,确保使用 sudo 编辑。

参考文档

原文链接:https://www.zjcp.cc/ask/11103.html

posted @ 2026-05-14 22:34  茶猫云呀  阅读(0)  评论(0)    收藏  举报