Docker 容器内 DNS 解析失败报错 server misbehaving 怎么办?

文章导读
遇到容器内 DNS 报错 server misbehaving,最推荐的处理方向是修改 Docker 守护进程配置或针对单个容器指定 DNS,适用于大多数基于 Linux 主机的生产环境。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

遇到容器内 DNS 报错 server misbehaving,最推荐的处理方向是修改 Docker 守护进程配置或针对单个容器指定 DNS,适用于大多数基于 Linux 主机的生产环境。

先说结论:这通常是主机 DNS 配置与 Docker 网络模式冲突导致的。生产环境建议优先采用单容器指定 DNS 方案,避免重启 Docker 服务影响业务。

  • 先确认:检查主机/etc/resolv.conf 是否指向本地回环地址
  • 先处理:优先尝试 docker run `--dns` 或 compose 配置,全局配置需重启服务
  • 再验证:进入容器执行 nslookup 确认解析恢复

命令速用版

# 临时测试启动容器(修复参数格式)
docker run `--dns` 223.5.5.5 `--dns` 114.114.114.114 -it alpine nslookup www.baidu.com

# 永久配置 Docker 守护进程(需重启服务,生产慎用)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<'EOF'
{
  "dns": ["223.5.5.5", "114.114.114.114"]
}
EOF
sudo systemctl restart docker

为什么会这样

Docker 容器默认会使用内置的 DNS 服务器(IP 通常是 127.0.0.11),它会转发请求到主机的 DNS 配置。如果主机使用了 systemd-resolved 等服务,/etc/resolv.conf 可能指向 127.0.0.53 或 127.0.0.1。容器网络隔离导致它无法访问主机的本地回环地址,从而引发解析超时或 server misbehaving 错误。

分步处理

第一步:检查主机 DNS 配置
在主机终端执行 cat /etc/resolv.conf。如果 nameserver 显示的是 127.0.0.1 或 127.0.0.53,说明主机使用了本地 DNS 代理服务,容器可能无法连通。

第二步:选择修复方案

Docker 容器内 DNS 解析失败报错 server misbehaving 怎么办?

方案 A:单容器指定 DNS(推荐,无需重启)

适用于新启动容器或可重建的容器,不影响其他业务。

Docker 命令:
docker run `--dns` 223.5.5.5 `--name` my-app image:tag

Docker Compose:
在 docker-compose.yml 中添加 dns 配置:

Docker 容器内 DNS 解析失败报错 server misbehaving 怎么办?
services:
  web:
    image: nginx
    dns:
      - 223.5.5.5
      - 114.114.114.114

方案 B:全局配置 Docker 守护进程(需重启)

适用于所有容器均需修改 DNS 的场景,但会导致业务中断。

编辑/etc/docker/daemon.json 文件。如果文件不存在则新建。添加"dns"字段,填入公共 DNS 地址。配置修改后需要重启守护进程才能生效。执行 sudo systemctl restart docker。注意:这会重启所有容器,业务高峰期需谨慎,建议先在测试环境验证。

怎么验证是否生效

启动一个新容器或在现有容器内执行以下命令:
cat /etc/resolv.conf 查看 nameserver 是否已变为配置的 DNS。
nslookup www.docker.comping -c 4 www.docker.com 观察是否能正常返回 IP 且无超时。

常见坑

  1. 主机网络重启后,/etc/resolv.conf 可能被还原,导致问题复现,建议在 daemon.json 中固化 DNS。
  2. 使用 host 网络模式的容器不受 daemon.json 影响,需单独处理。
  3. 某些企业内部 DNS 有 ACL 限制,公共 DNS 可能无法解析内网域名,需混合配置或使用 search 域。
  4. 国内环境使用 8.8.8.8 可能不稳定或被污染,建议优先使用 223.5.5.5 或 114.114.114.114。
  5. 修改 daemon.json 后必须重启 Docker 服务,无法通过 reload 生效。

参考来源

  • Docker Documentation, Configure DNS, https://docs.docker.com/config/containers/container-networking/#dns-services
  • Ubuntu Server Guide, systemd-resolved, https://ubuntu.com/server/docs/service-domain-name-service