Docker 容器无法解析域名通常是因为容器继承了宿主机无效的 DNS 配置,或者自定义网络缺少 NAT 转发规则。优先检查容器内 resolv.conf 文件并尝试指定公共 DNS 服务器。
先说结论:大部分 DNS 故障源于容器内 DNS 服务器地址不可达,少数情况是宿主机 iptables 规则缺失导致外网完全不通。
- 先确认:容器内 ping IP 是否通,区分是 DNS 问题还是网络链路问题
- 先处理:通过 daemon.json 或启动参数强制指定可靠 DNS
- 再验证:使用 nslookup 测试域名解析是否恢复
命令速用版
如果急需恢复业务,可以在启动容器时直接指定 DNS:
docker run `--dns` 8.8.8.8 `--dns` 114.114.114.114 -d your_image若是已有容器,修改宿主机配置后重启 Docker 服务。注意:不要直接覆盖 daemon.json,以免丢失其他配置。
# 1. 备份原有配置
cp /etc/docker/daemon.json /etc/docker/daemon.json.bak
# 2. 编辑文件,确保 json 格式正确,添加 dns 字段
vi /etc/docker/daemon.json
# 3. 重启 Docker 服务
systemctl restart docker为什么会这样
Docker 容器默认会继承宿主机的 DNS 配置,如果宿主机本身 DNS 波动或使用了本地递归服务(如 127.0.0.1),容器内可能无法正确解析。此外,自定义桥接网络需要 iptables 的 MASQUERADE 规则才能访问外网,若规则缺失,不仅域名无法解析,连 IP 也无法 ping 通。
关于容器内 /etc/resolv.conf 中的 127.0.0.11:这是 Docker 守护进程内置的 DNS 服务器,本身是有效地址。如果解析失败,通常是因为 Docker 守护进程自身无法向上游 DNS 发起请求,而不是容器内配置错误。
分步处理
1. 区分故障类型
进入容器内部,先 ping 一个公网 IP(如 8.8.8.8):
docker exec -it <container_id> ping 8.8.8.8如果 IP 能通但域名不通,是纯 DNS 问题;如果 IP 也不通,检查网络模式及 iptables 规则。
2. 检查容器 DNS 配置
查看容器内的 resolv.conf 文件:
docker exec -it <container_id> cat /etc/resolv.conf如果 nameserver 指向宿主机无效 DNS 或解析超时,说明配置存在问题。若显示 127.0.0.11 但无法解析,需检查宿主机 Docker 服务状态。
3. 修正 DNS 配置
推荐在宿主机创建或编辑/etc/docker/daemon.json,写入全局 DNS。请务必先备份并合并原有配置:
{
"dns": ["8.8.8.8", "114.114.114.114"],
"其他原有配置": "保持不变"
}修改后重启 Docker 服务使配置生效,新建容器将自动应用该配置。
4. 检查网络转发规则
如果 ping IP 也丢包,检查宿主机 iptables NAT 表是否有 MASQUERADE 规则:
iptables -t nat -L POSTROUTING -n -v若缺少相关规则,自定义网络有时需要手动补充规则或重启 Docker 服务重置网络。
同时检查网络模式详情:
docker network inspect bridge确认 Options 中是否有 com.docker.network.bridge.enable_icc 等配置影响连通性。
怎么验证是否生效
在新启动的容器中执行解析测试:
docker run `--rm` alpine nslookup www.baidu.com观察返回的 Address 是否为有效 IP,且没有 timeout 错误。同时检查应用日志中是否不再出现 getaddrinfo 相关报错。
常见坑
1. 宿主机 DNS 变动:如果宿主机通过 DHCP 获取 DNS,重启后可能变化,导致容器继承失效地址,建议在 daemon.json 中写死 DNS。
2. 自定义网络隔离:使用 docker network create 创建的桥接网络,若未正确配置网关和 NAT,容器无法出站。
3. 防火墙拦截:主机防火墙或安全组规则可能丢弃 UDP 53 端口流量,导致解析请求无法发出。