容器里 DNS 不生效的几个原因
容器里 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 就够了。
排查顺序
cat /etc/resolv.conf,确认指向的地址在容器里可达dig @223.5.5.5 example.com,确认是解析问题还是网络问题dig +trace example.com,看断在哪一层- 还不清楚就抓包:
tcpdump -i any port 53 -nn
大部分所谓的"DNS 问题",最后都是配置文件指错了地址。真正的递归解析故障反而少见。