Container 无法访问外网 dns 配置错误怎么修复

文章导读
修复 Container 无法访问外网 DNS 配置错误,最推荐的方法是修改 Docker 守护进程配置文件 daemon.json 指定公共 DNS,或在启动容器时使用 `--dns` 参数临时指定。注意重启 Docker 服务会导致所有容器短暂中断,生产环境需在维护窗口操作。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

修复 Container 无法访问外网 DNS 配置错误,最推荐的方法是修改 Docker 守护进程配置文件 daemon.json 指定公共 DNS,或在启动容器时使用 `--dns` 参数临时指定。注意重启 Docker 服务会导致所有容器短暂中断,生产环境需在维护窗口操作。

先说结论:Container DNS 故障通常源于宿主机 DNS 配置失效或 Docker 嵌入式 DNS 转发异常,优先检查宿主机解析能力再调整容器配置。

  • 先确认:宿主机能否正常解析域名,检查 /etc/resolv.conf 是否指向无效地址
  • 先处理:修改 /etc/docker/daemon.json 配置全局 DNS 或启动时添加 `--dns` 参数
  • 再验证:在容器内执行 nslookup 或 ping 外网域名确认解析恢复

命令速用版

以下是直接修改配置和重启服务的常用命令,适用于大多数 Linux 环境下的 Docker 容器。

# 查看当前 Docker 配置
cat /etc/docker/daemon.json

# 临时启动容器指定 DNS
docker run `--dns` 8.8.8.8 `--dns` 1.1.1.1 -it ubuntu bash

# 修改配置后重启服务
systemctl restart docker

为什么会这样

Container 默认继承宿主机的 DNS 设置,当宿主机 DNS 配置错误或 systemd-resolved 占用本地回环地址时,容器无法解析外网域名。Docker 守护进程会启动一个嵌入式 DNS 服务器监听 127.0.0.11,容器将该地址作为默认 DNS,若宿主机上游 DNS 不可达,嵌入式 DNS 也无法完成转发。

分步处理

按照以下顺序排查和修复,每一步操作后都建议检查状态,避免盲目重启服务。

步骤 1:检查宿主机 DNS 状态
在宿主机执行 nslookup 或 dig 命令,确认宿主机本身能解析外网域名。如果宿主机无法解析,优先修复宿主机网络配置,例如修改 /etc/resolv.conf 或检查 NetworkManager 设置。

Container 无法访问外网 dns 配置错误怎么修复

步骤 2:检查 Docker daemon 配置
查看 /etc/docker/daemon.json 文件是否存在 dns 配置项。如果文件不存在,可以新建;如果存在,检查 dns 数组中的 IP 地址是否可达。推荐配置公共 DNS 如 8.8.8.8 或 223.5.5.5。

{
  "dns": ["8.8.8.8", "1.1.1.1"]
}

步骤 3:应用配置并重启
修改配置文件后,必须重启 Docker 服务才能生效。执行 systemctl restart docker 命令。注意该操作会重启所有运行中的容器,需评估业务影响。

步骤 4:单容器覆盖配置
如果不想重启服务,可以在运行特定容器时使用 `--dns` 参数覆盖全局配置。此方法仅对该容器生效,适合临时修复或测试。

怎么验证是否生效

修复完成后,进入容器内部进行网络测试,确保解析和连通性均正常。

验证命令:

Container 无法访问外网 dns 配置错误怎么修复
# 进入容器
docker exec -it <容器 ID> bash

# 测试域名解析
nslookup www.google.com

# 测试网络连通性
ping -c 4 8.8.8.8
ping -c 4 www.google.com

判断标准:nslookup 能返回非-authoritative answer 的 IP 地址,ping 域名无 unknown host 错误且能收到回复包。

常见坑

在处理 DNS 配置时,以下几个场景容易导致配置无效或反复故障。

  • 127.0.0.53 问题:Ubuntu 等系统使用 systemd-resolved 时,/etc/resolv.conf 可能指向 127.0.0.53,容器无法访问宿主机的本地回环 DNS,需在 daemon.json 指定外部 DNS。
  • 防火墙拦截:宿主机的 iptables 或 firewalld 可能拦截容器的 UDP 53 端口出站流量,检查 FORWARD 链规则。
  • 网络插件冲突:使用 Calico、Flannel 等 CNI 插件时,部分插件会管理 DNS 配置,手动修改 daemon.json 可能被覆盖,需查阅插件文档。
  • 配置语法错误:daemon.json 是严格的 JSON 格式,多一个逗号或缺少引号都会导致 Docker 服务启动失败,修改前建议备份。

常见问题

为什么容器内 DNS 服务器地址是 127.0.0.11?

这是 Docker 嵌入式 DNS 服务器的默认监听地址,用于容器间服务发现和外部域名转发,所有未指定 DNS 的容器默认都会使用该地址。

修改 daemon.json 后 Docker 启动失败怎么办?

通常是 JSON 格式错误,查看 journalctl -u docker 日志定位错误行,恢复备份的配置文件或修正语法后重试。

Kubernetes Pod DNS 失败怎么修复?

K8s 环境需检查 CoreDNS Pod 状态和 ConfigMap 配置,通常通过 kubectl edit configmap coredns -n kube-system 修改上游 DNS,而不是修改 Docker 配置。

参考来源

  • Docker Official Documentation, Container networking - DNS services, https://docs.docker.com/config/containers/container-networking/#dns-services
  • Ubuntu Documentation, systemd-resolved, https://ubuntu.com/server/docs/service-networking