qnt0

容器里 DNS 不生效的几个原因

2026-09-18

容器里 curl 一个域名超时,但宿主机上正常,ping IP 也通。遇到不止一次了,记一下。

先看 resolv.conf 指向谁

cat /etc/resolv.conf

如果是这一行:

nameserver 127.0.0.53

那就是 systemd-resolved 的 stub listener。这个地址只存在于宿主机的网络命名空间里,容器里根本没有它。

Docker 默认会把宿主机的 /etc/resolv.conf 拷进容器,所以宿主机一旦用 systemd-resolved,容器就必然指着 127.0.0.53,然后解析超时。

解法一:给容器显式指定

docker run --dns 223.5.5.5 ...

或者全局配在 /etc/docker/daemon.json:

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

另一个坑:ndots

Kubernetes 里默认是 ndots:5。意思是任何不带点的域名,都会先拼上五轮 search 域后缀去查,五轮都失败了才查原始域名。

options ndots:5

访问外部域名时,多出来的这几轮查询会明显拖慢首次连接,尤其是 UDP 53 被限速的环境。把 pod 的 dnsConfig.options 改成 ndots:2 就够了。

排查顺序

  1. cat /etc/resolv.conf,确认指向的地址在容器里可达
  2. dig @223.5.5.5 example.com,确认是解析问题还是网络问题
  3. dig +trace example.com,看断在哪一层
  4. 还不清楚就抓包:tcpdump -i any port 53 -nn

大部分所谓的"DNS 问题",最后都是配置文件指错了地址。真正的递归解析故障反而少见。