快速修复
# 一键:用国内公共 DNS 重跑容器
docker run --rm --dns 223.5.5.5 --dns 119.29.29.29 <镜像> wget -qO- http://example.com
你会遇到什么
容器里访问域名报解析失败(wget: bad address 'github.com' / curl: (6) Could not resolve host / Temporary failure in name resolution),但宿主上同样域名正常、IP 直连也通。常出现在给容器配过 --dns、或换了网络环境(校园网/公司网/代理)之后。
最经典的坑:网上教程让你配 --dns 8.8.8.8,而多数国内网络对 8.8.8.8 的 UDP 53 不友好。
本文路径:快速修复(30 秒一段命令)→ 一步步排查(可跳读)→ 原理与变体(症状/原因/证据)。赶时间直接跳到「快速修复」。
为什么会这样
容器用自己的 /etc/resolv.conf 解析。默认 docker 继承宿主的 nameserver 生成一份;但一旦用 docker run --dns、compose 的 dns:、或 daemon.json 的 "dns" 覆盖,容器就只问指定的 DNS。该 DNS 不可达、或域名只在特定 DNS 有记录(内网域名)→ 解析失败。
- 错误文案取决于程序:busybox 报
bad address,glibc 程序报Temporary failure in name resolution——同一问题不同长相。 - IP 直连能通、域名不行 = DNS 层问题,先分层再动手。
实测环境:WSL Ubuntu,docker 29.1.3,alpine:3.20,校园网无代理,2026-08-29。
容器没有自己的 DNS 服务,它只是按 /etc/resolv.conf 把解析请求转发给 nameserver——这份配置默认由 docker 继承宿主生成,但一旦 --dns/compose dns:/daemon.json 覆盖,就变成「只问指定的服务器」。
DNS 走 UDP 53 明文请求,国内网络对 8.8.8.8 丢包是常见现实,「网上教程的万能 DNS」在你这儿可能恰恰是断点。
确定性判断路径:IP 直连通 + 域名不通 = 问题在解析链路;容器内 cat /etc/resolv.conf 看 nameserver 是谁;内网域名必须用内网/VPN 分配的 DNS——公共 DNS 上根本没有这条记录,换多少公共 DNS 都白换。
一步步来
1. 分层确认 — 必做
宿主 getent hosts github.com 正常 → 容器内看解析配置:
docker run --rm <镜像> cat /etc/resolv.conf
nameserver 是被覆盖过的(可能带 Overrides: [nameservers])→ 问题在指定 DNS。
2. 单容器指定可用 DNS — 必做
docker run --dns 223.5.5.5 --dns 119.29.29.29 ...
223.5.5.5(阿里)/ 119.29.29.29(腾讯)国内公共 DNS,实测可用。
3. compose 场景 — 必做
services:
app:
dns:
- 223.5.5.5
- 119.29.29.29
4. 全局默认(影响所有容器) — 必做
daemon.json 加 "dns": ["223.5.5.5", "119.29.29.29"] 后重启 daemon。
5. 配 8.8.8.8 前先测 — 必做
timeout 5 bash -c 'echo > /dev/tcp/8.8.8.8/53' && echo reachable
通了才用;不通换国内公共 DNS。内网域名解析失败时,把内网/VPN 分配的 DNS 加进 --dns,必要时与公共 DNS 并列。
怎么确认修好了
docker run --rm --dns 223.5.5.5 <镜像> wget -qO- http://github.com >/dev/null && echo OK
不再报解析失败即成功。实测:默认继承宿主 DNS → wget 成功(exit 0);--dns 192.0.2.1(必然不可达)→ bad address(exit 1);--dns 8.8.8.8 校园网可达 → 成功;--dns 223.5.5.5 → 成功。
其它环境的表现
| 环境 | 说明 |
|---|---|
| 校园网/家宽 | 8.8.8.8 可能不可达,用 223.5.5.5 / 119.29.29.29 |
| 公司内网域名 | 加内网/VPN DNS,必要时与公共 DNS 并列 |
| WSL + Docker Desktop | 升级后偶发,同样按上面分层排查 |
| compose | 服务级 dns: 配置 |
症状
容器内访问域名报解析失败(宿主上同样域名正常):
wget: bad address 'github.com' # busybox/alpine wget
curl: (6) Could not resolve host: github.com # curl
Temporary failure in name resolution # ping / apt-get 等 glibc 程序
特征:IP 直连能通、域名不行(wget http://<IP>/ 成功证明是 DNS 层);宿主解析正常、容器内失败;常出现在给容器配过 --dns、或换了网络环境(校园网/公司网/代理)之后;WSL + Docker Desktop 升级后也可能偶发(for-win#13808)。
原因
容器用自己的 /etc/resolv.conf 做解析。默认 docker 会继承宿主的 nameserver 生成一份;但一旦用 docker run --dns <ip>、compose 的 dns:、或 daemon.json 的 "dns" 覆盖,容器就只问指定的 DNS。若该 DNS 不可达(国内网络配 8.8.8.8 是最经典坑:多数国内网络 UDP 53 被墙/丢包)、或域名本身只在特定 DNS 有记录(内网域名),解析就失败。错误文案取决于程序:busybox 报 bad address,glibc 程序报 Temporary failure in name resolution,同一问题不同长相。
解法
- 先分层:宿主
getent hosts github.com正常 → 容器内cat /etc/resolv.conf看 nameserver 是什么(被覆盖过的会显示Overrides: [nameservers])。 - 单容器指定可用 DNS(最常用):
docker run --dns 223.5.5.5 ...(阿里)或--dns 119.29.29.29(腾讯)——国内公共 DNS,实测可用。 - compose:服务下加
dns: [223.5.5.5, 119.29.29.29]。 - 全局默认:daemon.json 加
"dns": ["223.5.5.5", "119.29.29.29"]后重启 daemon(影响所有容器,改前确认)。 - 配 8.8.8.8 前先测(国内网络差异大):
timeout 5 bash -c 'echo > /dev/tcp/8.8.8.8/53'通了才用;不通就换国内公共 DNS。 - 内网域名:容器解析公司/校园内网域名失败时,把内网 DNS(或 VPN 分配的 DNS)加进
--dns,必要时与公共 DNS 并列。
验证证据
- 本地实测(2026-08-29,WSL Ubuntu,docker 29.1.3,alpine:3.20,校园网无代理):
- 基线:默认 DNS 继承宿主(resolv.conf 显示 nameserver 223.5.5.5 / 119.29.29.29),容器内 wget github.com 成功(exit 0);
- 复现:
--dns 192.0.2.1(保留地址必然不可达)→ 容器内wget: bad address 'github.com'(exit 1),resolv.conf 显示nameserver 192.0.2.1+Overrides: [nameservers]; - 经典坑实测:校园网
8.8.8.8:53可达(/dev/tcp探测通)→--dns 8.8.8.8解析成功(exit 0)——国内网络差异大,配前必须测; - 修复:
--dns 223.5.5.5→ wget github.com 成功(exit 0)。 - 实测复现日志(2026-08-29)
相关 canonical
按「前置 → 同根 / 同域 / 相关」读:
- 只有个别网站打不开(其他网站正常)——分层定位(相邻:单域名失败,同一套分层法)
- 前置(先排除):
- Docker daemon 连不上(前置:容器能跑 = daemon 正常)
- 同根(同一根因):
- docker pull 失败/镜像加速(同根:no such host 同为 DNS 层,宿主 vs 容器内)
适用工具 (1)
本问题方案已挂到下列工具的方案页——从工具页也能回到这里,双向可达。
docker · 外部工具来源与证据
← 编码代理与终端 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡