朕喜技术(ZhenxiJS)
2026.08.29
1 分钟阅读

容器内 DNS 解析失败修复指南:Name or service not known 但 ping IP 正常

关键词:docker dns 解析失败, resolv.conf, Name or service not known, Could not resolve host, socket.gaierror, 192.0.2.1, docker compose dns, 容器域名解析超时, ExtServers, docker 内嵌 dns 127.0.0.11 技术栈:Docker / Docker Compose / Alpine / Linux / DNS

问题背景

微服务容器突然无法访问外部 API,应用日志大量出现 socket.gaierror: [Errno -2] Name or service not known。排查发现:容器内 curl https://www.baidu.com 报 curl: (6) Could not resolve host,但 ping 8.8.8.8 完全正常,curl http://1.1.1.1 也能访问。网络通但域名全解析失败。

复现步骤

cd scenario/2026-08-29-0800
docker compose up -d --build
docker compose exec app sh

容器内观察:

cat /etc/resolv.conf          # nameserver 127.0.0.11, 注释里有 ExtServers: [192.0.2.1]
nslookup www.baidu.com        # connection timed out
ping -c 1 8.8.8.8             # 正常

根本原因

docker-compose.yml 配置了不可达的 DNS 服务器:

dns:
  - 192.0.2.1    # RFC 5737 TEST-NET 保留地址,不响应真实 DNS 查询

192.0.2.1 属于 RFC 5737 定义的 TEST-NET 保留网段(192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24),仅用于文档和示例,不会响应任何真实 DNS 请求。

Docker 容器内 /etc/resolv.conf 显示 nameserver 127.0.0.11(Docker 内嵌 DNS resolver),但这个内嵌 DNS 会将查询转发到 compose 配置的 dns: 上游(即 192.0.2.1)。上游不可达 → 查询超时 → 解析失败。

解决办法

方法一:正确持久修复(推荐)—— 修改 docker-compose.yml

# 修改前(问题)
dns:
  - 192.0.2.1

# 修改后(修复,使用公共 DNS)
dns:
  - 223.5.5.5        # 阿里公共 DNS
  # 或 114.114.114.114 / 8.8.8.8

然后重建容器:

docker compose down
docker compose up -d --build

方法二:临时紧急修复 —— 容器内改 resolv.conf

docker compose exec app sh
echo "nameserver 223.5.5.5" > /etc/resolv.conf

⚠️ 注意:此方法在容器重启后会失效,因为 Docker Engine 启动容器时会根据 compose dns: 配置重新生成 resolv.conf。

验证

nslookup www.baidu.com        # 返回 IP:183.2.172.177 ✅
curl -sI https://www.baidu.com  # HTTP 200 ✅
cat /etc/resolv.conf | grep ExtServers   # ExtServers: [223.5.5.5] ✅

经验与避坑

  1. 区分「网络不通」与「DNS 不通」:ping IP 通但域名解析失败,99% 是 DNS 问题。用 nslookup / dig 精确诊断,别只盯着 curl 报错。
  2. Docker 容器的 DNS 由 compose 的 dns: 控制:容器内改 resolv.conf 只是临时的,重启即被 Docker Engine 重写。想持久修改必须改 compose 配置或 daemon.json。
  3. 看 resolv.conf 底部注释能快速定位:Docker 生成的 resolv.conf 带有注释 # ExtServers: [xxx] 和 # Based on host file,直接揭示内嵌 DNS 转发目标。
  4. RFC 5737 TEST-NET 地址是坑:192.0.2.x、198.51.100.x、203.0.113.x 是文档保留地址,用于示例或测试时务必记得换成真实 DNS。
  5. DNS 故障会连锁放大:DNS 挂了以后,apk/apt/pip 等包管理器也无法下载包(因为它们也要解析域名),会导致「查不了 DNS → 装不了工具 → 更没法诊断」的死循环。遇到这种情况直接用宿主机工具或先修 DNS。
  6. 推荐公共 DNS:国内环境 223.5.5.5(阿里)、114.114.114.114(114DNS);国际 8.8.8.8、1.1.1.1(Cloudflare)。

版权声明

本文为博主原创文章,遵循 CC BY-NC-SA 4.0 许可协议。 转载请注明出处:http://localhost/blogs/2026-08-29-0800-dnsname-or-service-not-known

分享这篇文章