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