摘要
本文说明一种常见现象:宿主机可以上网,但进入 Docker 容器后 ping 域名出现 Temporary failure in name resolution。原因多与容器内 DNS 配置有关。通过在宿主机 修改 Docker 的 daemon.json 指定公共 DNS,并重启 Docker 服务,可使新建容器长期获得可用的域名解析能力。
关键词: Docker、DNS、daemon.json、Temporary failure in name resolution、Linux
一、现象描述
在容器内执行:
bash
ping www.baidu.com
报错:
text
ping: www.baidu.com: Temporary failure in name resolution
而宿主机上同样的命令正常;有时在容器里 ping 公网 IP (如 223.5.5.5)却是通的。
这说明:网络路由大致正常,问题集中在 DNS 解析。
二、原因简述
- 容器内的
/etc/resolv.conf往往由 Docker 根据宿主机环境生成。若宿主机使用127.0.0.53(systemd-resolved)等仅本机有效 的地址,在容器里127.0.0.53指向容器自身,导致解析失败。 - 部分环境下路由器或内网 DNS 对容器网段不友好,也会出现类似现象。
- 在容器里临时 改
resolv.conf可能立刻生效,但容器重建或重启后易被覆盖,不适合作为长期方案。
因此更稳妥的做法是:在 Docker 守护进程层面为容器指定可靠的公共 DNS。
三、解决办法:修改宿主机 /etc/docker/daemon.json
适用场景: 希望默认所有新建容器都使用固定、可用的 DNS,且由运维在宿主机统一配置。
3.1 编辑配置文件
在宿主机(不是容器内)使用 root 权限编辑或创建:
/etc/docker/daemon.json
若文件已存在其他配置,需合并为合法 JSON(注意逗号),示例:
json
{
"dns": ["223.5.5.5", "114.114.114.114"]
}
说明:
223.5.5.5、114.114.114.114为国内常用的公共 DNS,可按需换成8.8.8.8等。- 若原文件已有键(如
registry-mirrors),应写成一个对象,例如:
json
{
"registry-mirrors": ["https://你的镜像地址"],
"dns": ["223.5.5.5", "114.114.114.114"]
}
3.2 重启 Docker
bash
sudo systemctl restart docker
四、验证步骤
- 新建或重建一个测试容器进入 shell。
- 执行:
bash
cat /etc/resolv.conf
ping -c 2 www.baidu.com
应能看到配置的 nameserver,且域名解析与 ping 正常。
五、注意事项与排错
- JSON 语法 :
daemon.json格式错误会导致 Docker 启动失败,修改后可用sudo docker info或systemctl status docker确认服务正常。 - 仅改容器内 resolv.conf :适合临时排障;永久方案 仍建议本文的
daemon.json或docker run --dns。 - ping IP 通、域名不通 :基本可断定是 DNS;若 IP 也不通,需再查路由、防火墙、VPN 等。
- IPv6 :部分环境解析到 AAAA 后走 IPv6,若仅 IPv4 异常可能表现复杂,可结合
ping -4/dig进一步排查。
六、小结
| 项目 | 说明 |
|---|---|
| 修改位置 | 宿主机 /etc/docker/daemon.json |
| 核心配置 | "dns": ["223.5.5.5", "114.114.114.114"] |
| 必做操作 | sudo systemctl restart docker |
| 旧容器 | 需重建后新 DNS 才稳定生效 |
| 典型现象 | 宿主机有网,容器内 Temporary failure in name resolution |
可在不进入每个容器改文件的前提下,统一解决 Docker 环境的 DNS 问题,适合个人开发机与内网服务器长期使用。