在一次正常运行的 Web 项目中,突然出现了“网站访问变慢、部分资源加载失败”的现象。刚开始以为是后端服务或 CDN 的问题,结果深入排查后发现——是 Docker 容器内无法解析域名

这篇文章就记录一下整个排查过程、问题定位、最终的解决办法,希望对你有帮助。


🧩 问题现象

  • 页面加载缓慢

  • 某些 API 请求和静态资源加载失败

  • 浏览器开发者工具提示:ERR_NAME_NOT_RESOLVEDfetch failed


🔍 排查过程

  1. 查看 Nginx 访问日志

    tail -f /var/log/nginx/access.log
    

    发现某些请求压根没有命中服务。

  2. 查看容器内部运行状态
    进入容器后尝试访问外部服务(比如第三方 API):

    docker exec -it myapp sh
    ping google.com
    

    返回:

    ping: bad address 'google.com'
    
  3. 进一步测试 DNS 解析

    nslookup google.com
    

    报错:

    ;; connection timed out; no servers could be reached
    

    至此可以确认,容器内部无法解析域名,导致依赖外部服务的请求失败,从而拖慢网站加载。


🛠️ 根本原因

Docker 默认会使用宿主机的 DNS 设置生成 /etc/resolv.conf,但某些情况下(比如宿主机网络不稳定、resolv.conf 被意外修改、systemd-resolved 异常),会导致容器内 DNS 异常。


✅ 解决方法:为 Docker daemon 显式设置 DNS

  1. 编辑 Docker 配置文件

    sudo nano /etc/docker/daemon.json
    
  2. 添加 DNS 设置

    {
      "dns": ["8.8.8.8", "1.1.1.1"]
    }
    

    Google 的公共 DNS 和 Cloudflare 的 DNS,稳定可靠。

  3. 重启 Docker 服务

    sudo systemctl restart docker
    
  4. 验证容器 DNS
    进入容器重新测试:

    docker exec -it myapp sh
    ping google.com
    

    这次一切正常!


🧪 小技巧:临时指定容器 DNS(非推荐,但可用于排查)

docker run --rm --dns 8.8.8.8 busybox nslookup google.com

📝 总结

这个问题虽然不常见,但一旦出现,会造成比较隐蔽的故障,比如资源加载失败、接口请求超时,特别是当你依赖第三方服务(如 OAuth、外部 API、图床等)时。

设置 Docker daemon 的 DNS 是一种比较通用且稳定的解决方案,推荐作为日常配置的一部分。


📌 建议:

  • 将 DNS 配置固定写入 /etc/docker/daemon.json

  • 避免容器 DNS 依赖宿主机动态变化

  • 监控异常请求,定期检查容器运行状态


如果你也曾遇到过类似的 DNS 问题,欢迎留言讨论!🧩