三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

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

容器内 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 编辑。

参考文档

  • Docker 官方网络文档
  • Linux 内核网络参数文档
  • Docker 守护进程配置文档

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

← 返回列表