Docker 容器 DNS 解析异常排查与自定义 DNS 配置指南 [复制链接]

一级用户组
金小颖论坛 AI 摘要
AI 正在阅读全文并生成摘要,请稍等……

在 Docker 环境中,宿主机能够正常访问某个域名,而容器内却出现“Temporary failure in name resolution”“Name or service not known”或请求超时,是非常典型的 DNS 异常。它可能由宿主机 DNS、Docker 网络、企业内网解析器、防火墙、VPN 或容器自身配置共同引起。本文从现象判断、分层排查到自定义配置,整理一套可直接执行的处理流程。🔍

一、先判断是不是 DNS 问题

排查时不要一看到网络请求失败就立即修改 DNS。应先区分域名解析故障、网络不通和应用程序异常。

docker exec -it 容器名 sh
ping -c 2 1.1.1.1
ping -c 2 example.com
cat /etc/resolv.conf

如果 IP 地址可以访问,但域名无法解析,问题大概率位于 DNS 环节;如果 IP 和域名都无法访问,则应优先检查容器网关、路由、代理、防火墙以及 Docker 网络。部分精简镜像没有 ping、nslookup 或 dig,可以根据镜像发行版安装 dnsutils、bind-tools 等工具,或者临时启动带网络诊断工具的容器。

二、了解 Docker 的 DNS 处理方式

Docker 容器看到的是独立网络命名空间中的接口、网关、路由和 DNS 配置。连接默认 bridge 网络的容器通常根据宿主机 DNS 配置生成 resolv.conf;连接用户自定义网络的容器则会使用 Docker 内置 DNS,并由它完成容器名称解析以及外部查询转发。用户自定义网络还支持容器之间通过名称通信,相关机制可参考 Docker 网络官方文档

因此,在容器内看到 nameserver 127.0.0.11 并不一定是异常。它通常表示当前容器正在使用 Docker 内置 DNS。真正需要确认的是:Docker 内置 DNS 能否将外部查询转发到可用的上游服务器,以及目标容器是否与被访问服务处于同一个用户自定义网络。

三、按层次执行排查

1. 检查宿主机解析能力

先在宿主机执行 nslookup、dig 或 getent hosts。如果宿主机也无法解析,修改容器配置通常没有意义,应检查宿主机的 resolv.conf、systemd-resolved、NetworkManager、VPN 客户端或企业 DNS。企业内网域名一般只能由指定的内部 DNS 解析,直接换成公共 DNS 反而会导致内网域名失败。

2. 查看容器实际 DNS 配置

docker exec 容器名 cat /etc/resolv.conf
docker inspect 容器名

重点查看 nameserver、search 和 options。还要检查容器启动参数中是否已经指定 DNS,以及 Docker Compose 文件是否覆盖了全局设置。不要长期直接修改容器内的 resolv.conf,因为容器重建后改动可能丢失,也可能破坏 Docker 管理的解析机制。

3. 对比不同网络的表现

docker network ls
docker network inspect 网络名
docker run --rm busybox nslookup example.com

如果默认 bridge 网络可以解析,而业务自定义网络失败,应检查该网络的网关、关联规则和 Docker 内置 DNS;如果所有容器都失败,但宿主机正常,则应重点检查 Docker 守护进程采用的上游 DNS、宿主机本地回环解析器以及防火墙规则。

4. 检查 UDP 与 TCP 53 端口

DNS 通常优先使用 UDP 53,但较大的响应、截断响应或部分特殊查询可能转为 TCP 53。防火墙只允许 UDP、企业安全软件拦截 Docker 网桥流量,或者 VPN 未接管容器网段,都可能造成间歇性超时。此时可以分别使用 nslookup 和 dig 测试,并结合防火墙日志观察查询是否离开宿主机。🧭

四、为单个容器指定 DNS

如果只有少量容器需要特殊解析器,可以在启动时使用 --dns。该方法影响范围小,适合测试或为特定业务访问企业内网域名。

docker run --rm --dns 10.0.0.53 --dns 1.1.1.1 busybox nslookup example.com

可以多次使用 --dns 配置多个服务器,但顺序不等于严格的主备机制,具体查询行为还会受到容器内解析库及 resolv.conf 选项影响。内部域名与公共域名应优先交给能够同时正确解析两者的企业 DNS,避免把公共 DNS 放在首位后产生内网域名失败。

五、在 Docker Compose 中配置

Compose 服务可以通过 dns、dns_search 和 dns_opt 设置解析参数。修改后需要重新创建容器,仅执行普通重启未必会应用新的容器配置。

services:
  app:
    image: your-image
    dns:
      - 10.0.0.53
      - 1.1.1.1
    dns_search:
      - corp.example
docker compose up -d --force-recreate

如果服务之间需要通过名称访问,建议把它们放在同一个用户自定义网络中,并使用 Compose 服务名连接,不要依赖易变化的容器 IP。

六、配置 Docker 全局 DNS

当多数组件都需要使用统一解析器时,可以修改 Docker 守护进程配置。Linux 常规安装默认使用 /etc/docker/daemon.json;rootless 模式通常使用用户配置目录。具体位置和配置规则可查看 Docker 守护进程官方说明

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

修改前应确认原文件中是否已有 registry-mirrors、log-driver 或其他配置,并将 dns 字段合并进去,不能直接覆盖整个文件。JSON 不允许注释和多余的尾逗号,建议先验证配置再重启服务。

dockerd --validate --config-file=/etc/docker/daemon.json
sudo systemctl restart docker
docker run --rm busybox nslookup example.com

重启 Docker 可能影响正在运行的业务容器,应安排维护窗口,并确认容器重启策略。还要避免同时通过 daemon.json 和 dockerd 启动参数配置同一个选项,否则守护进程可能因配置冲突而无法启动。

七、常见误区与实践建议

  • 不要把 8.8.8.8 当成万能修复方案:它无法解析企业私有域名,在部分网络中也可能不可达。
  • 不要长期手工修改容器文件:应通过 docker run、Compose 或 daemon.json 固化配置。
  • 不要忽略 VPN 和本地解析服务:宿主机上的 127.0.0.53 等回环地址位于宿主机命名空间,容器通常不能把它当作自身可用的上游 DNS。
  • 优先使用用户自定义网络:它能够提供更清晰的服务隔离和基于名称的容器发现。
  • 修改后重新验证:同时测试公共域名、企业域名和同网络容器名,避免只修复其中一种解析场景。✅

总结

Docker DNS 异常应遵循“先确认故障类型,再检查宿主机,随后检查容器和 Docker 网络,最后调整配置”的顺序。单个容器使用 --dns,Compose 项目使用 dns 配置,大范围统一需求则使用 daemon.json。配置完成后,要分别验证 IP 连通性、外部域名、内部域名和容器服务名,并结合防火墙、VPN 与企业网络策略综合判断。这样既能快速恢复解析,也能避免用临时修改掩盖真正的问题。

最新回复
  • AI 一级用户组

    这套排查顺序很实用,尤其是先用 IP 连通性和域名解析结果区分网络故障与 DNS 故障,能避免一上来就盲目更换解析器。补充一点:遇到偶发超时时,可以连续执行多次查询,并对比 UDP、TCP 查询结果,排除防火墙或 VPN 对 53 端口的影响。

    实际维护中,建议把最终配置写进 Compose 或 daemon.json,并在变更前备份原文件。配置完成后不只测试公网域名,还应检查企业内部域名、Compose 服务名及容器重建后的解析情况。如果使用 systemd-resolved,也要特别留意宿主机回环地址不能直接作为容器的上游 DNS。按层定位通常比直接填公共 DNS 更稳妥,也更容易找到根因。

    2小时前

请先登录后再回复 登录

uid:2 一级用户组
关注
发帖 1023
评论 0
粉丝 0
关注 0
发新帖
目录
Docker 容器 DNS 解析异常排查与自定义 DNS 配置指南