容器 DNS 解析机制

容器 DNS 解析机制

容器 DNS 的工作原理

当 Docker 容器启动时,默认使用宿主机的 DNS 配置进行域名解析。但 Docker 也有自己的一套 DNS 管理机制。

Docker 容器的 DNS 解析流程:

  1. 容器内的进程发起域名解析请求(如 nslookup 或程序内 DNS 查询)
  2. 请求发送到容器内的 DNS 解析器(由 /etc/resolv.conf 配置)
  3. 解析器将请求转发到配置的 nameserver
  4. Docker 内置的 DNS 服务器(127.0.0.11)处理请求
  5. 如果是 Docker 网络内的容器名或服务名,直接返回对应 IP
  6. 否则转发到宿主机的上游 DNS 服务器

默认 DNS 配置

每个容器启动时都会生成 /etc/resolv.conf,内容通常如下:

nameserver 127.0.0.11
options ndots:0

127.0.0.11 是 Docker 内嵌的 DNS 解析器,运行在容器的网络命名空间内。

自定义 DNS 配置

通过 docker run 参数

# 指定 DNS 服务器
docker run --dns 8.8.8.8 --dns 114.114.114.114 nginx

# 指定搜索域
docker run --dns-search example.com nginx

# 设置 DNS 选项
docker run --dns-opt "ndots:2" nginx

# 使用宿主机 DNS 配置
docker run --dns=host nginx

通过 docker-compose

services:
  web:
    image: nginx
    dns:
      - 8.8.8.8
      - 114.114.114.114
    dns_search:
      - example.com
    dns_opt:
      - "ndots:2"

注意:dns=host 在 Compose 文件中使用方式为:

services:
  web:
    image: nginx
    dns:
      - "host"

容器域名解析的三种场景

场景一:容器访问互联网

通过 127.0.0.11 转发到宿主机的 DNS 服务器(如 /etc/resolv.conf 中配置的 8.8.8.8、114.114.114.114 等)。

场景二:容器访问同一 Docker 网络中的其他容器

在自定义网络(user-defined bridge)中,Docker 内嵌 DNS 支持容器名解析:

docker network create my-net
docker run --name web --network my-net -d nginx
docker run --name app --network my-net -d alpine ping web

app 容器可以通过容器名 web 直接访问 nginx 服务。

场景三:容器访问宿主机服务

使用 host.docker.internal(Linux 需额外配置)或直接访问宿主机 IP。

DNS 相关的常见问题与排查

容器内 DNS 解析失败

# 检查容器内的 resolv.conf
docker exec container_name cat /etc/resolv.conf

# 测试 DNS 解析
docker exec container_name nslookup google.com

# 使用 dig 工具查细节
docker exec container_name dig google.com

DNS 解析超时

如果宿主机 DNS 配置不当,可能导致容器内 DNS 查询超时。常见原因:

  • NDOTS 配置不当,导致过多的 DNS 搜索域尝试
  • DNS 服务器地址不可达
  • 防火墙阻止了 UDP 53 端口

高级配置

跳脱 DNS(dnsmasq)

在复杂网络中,可以搭配 dnsmasq 作为容器的 DNS 缓存和转发代理:

docker run -d --name dnsmasq --cap-add=NET_ADMIN \
  -p 53:53/udp andyshinn/dnsmasq

自定义 DNS 搜索域

当需要自动补全域名时设置搜索域:

docker run --dns-search prod.example.com \
  --dns-search example.com nginx

这样访问 app 时,会依次尝试 app.prod.example.comapp.example.comapp

总结

  • Docker 使用 127.0.0.11 作为内嵌 DNS 解析器
  • 自定义网络(非 bridge)支持容器名自动解析
  • 可通过 --dns--dns-search--dns-opt 自定义 DNS 配置
  • dns=host 可让容器直接使用宿主机 DNS 配置
  • 排查 DNS 问题时,先检查 /etc/resolv.conf 和网络连通性
© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容