Docker 容器内 ping 域名报错或解析失败,通常不是容器本身挂掉,而是 DNS 配置没落到容器里。
本文根据实际排查经验,按“看网络模式→查 resolv.conf→改 docker 配置→验证”的顺序,帮你定位问题并恢复域名解析。
先确认容器网络模式
很多 DNS 故障与容器网络模式有关。
执行:
docker inspect <容器名> -f '{{.HostConfig.NetworkMode}}'
bridge(默认):容器会复制宿主机的 DNS 设置,但行为受 Docker 版本和宿主机配置影响。host:容器直接使用宿主机网络栈,DNS 解析完全依赖宿主机/etc/resolv.conf。none:没有网络,自然无法解析域名。
判断:如果宿主机能解析域名而容器不行,优先看容器生成的 resolv.conf。
查看容器内的 resolv.conf
容器内的 DNS 配置由 Docker 引擎管理。
进入容器或直接读取:
docker exec <容器名> cat /etc/resolv.conf
排查要点:
nameserver必须是可达的 DNS 服务器地址。- 如果看到
nameserver 127.0.0.11,说明 Docker 内置 DNS 服务在工作。 - 如果 nameserver 指向
127.0.0.1:53或宿主机内网 IP,且宿主机没开 DNS 转发,就会出现“能 ping IP、不能 ping 域名”的典型现象。
重点:127.0.0.11 是 Docker 自带的嵌入式 DNS,只有配置了自定义网络(如 docker network create)才会自动启用。
使用默认 bridge 网络时,Docker Daemon 会从宿主机 /etc/resolv.conf 读取 DNS,把它复制到容器里。
按需修改 DNS 配置
常见的修复方式有三种,场景不同用法不同。
方式一:运行容器时指定 DNS
临时测试时最推荐:
docker run -d --name test --dns 223.5.5.5 --dns 8.8.8.8 nginx
方式二:修改 Docker Daemon 默认 DNS
如果你希望对所有容器生效,编辑 /etc/docker/daemon.json:
{
"dns": ["223.5.5.5", "8.8.8.8"]
}
然后重启 Docker:
sudo systemctl restart docker
注意:修改后需要重新创建容器,已有容器不会自动应用新 DNS。
方式三:使用自定义网络
创建自定义 bridge 网络,Docker 会自动内置 DNS 服务器:
docker network create mynet
docker run -d --name test --network mynet nginx
自定义网络下,容器之间可以用容器名互访,DNS 由 127.0.0.11 接管。
常见故障与避坑清单
- 宿主机使用 systemd-resolved:
/etc/resolv.conf指向127.0.0.53,Docker 容器直接复制后无法访问宿主机的本地 stub resolver。解决方法是在 daemon.json 里显式指定dns,或把 systemd-resolved 配置为可被容器访问的外部 DNS。 - 容器内缺少 nslookup 命令:用
getent hosts baidu.com或ping -c 1 域名测试。 - 防火墙拦截 UDP 53:检查宿主机防火墙是否放行容器网段的 DNS 请求。
- 重启 Docker 后容器消失:先排查是否使用
--restart=always,DNS 修改属于重建容器,注意备份数据。
验证域名解析是否恢复
在容器内执行:
docker exec <容器名> getent hosts www.baidu.com
或者:
docker exec <容器名> ping -c 2 www.baidu.com
如果返回 IP 地址并 ping 通,说明 DNS 配置已生效。
再确认一下:
docker inspect <容器名> -f '{{json .HostConfig.Dns}}'
看到输出的 DNS 列表与预期一致就代表修复完成。
如果你正被 Docker 容器无法解析域名的问题卡住,先不要急着重装 Docker。
按本文说的顺序检查网络模式、容器的 resolv.conf 和 daemon.json,大多数情况几分钟就能解决。
更多容器网络问题,可以先从 docker network ls 开始排查。