dns-ndots

Kubernetes Pod 内解析外部域名偶尔慢几秒,dig 却很快,CoreDNS 查询量异常高。

现象

应用解析 api.example.com 这类外部域名时延迟 2–10 秒,偶发超时;Pod 内 dig 看起来正常。CoreDNS QPS 和 NXDOMAIN 数量偏高,查询日志里能看到大量带 search 后缀的无效域名。

快速定位

先读 Pod 的 resolv.conf,确认 ndots 和 search 列表:

kubectl exec -it <pod> -- cat /etc/resolv.conf
kubectl get pod <pod> -o jsonpath='{.spec.dnsConfig}'

再用真正走 getaddrinfo 的方式计时,而不是只用 dig(镜像内需有对应工具):

kubectl exec -it <pod> -- sh -c 'time getent hosts api.example.com'
kubectl exec -it <pod> -- python3 -c 'import socket, time; t = time.time(); print(socket.getaddrinfo("api.example.com", 443)); print("elapsed", time.time() - t)'
kubectl exec -it <pod> -- strace -f -e trace=network getent hosts api.example.com

观察 CoreDNS 查询类型和延迟:

kubectl -n kube-system port-forward svc/kube-dns 9153:9153
curl -s http://127.0.0.1:9153/metrics | grep -E 'coredns_dns_(requests_total|responses_total|request_duration_seconds)'
kubectl -n kube-system logs -l k8s-app=kube-dns --tail=200 | grep api.example.com

易误判:dig api.example.com 默认不按 /etc/resolv.conf 的 search/ndots 走 getaddrinfo 路径(除非加 +search),所以 dig 快不代表应用快;必须在 Pod 内用 getent hosts 或 getaddrinfo 复现。另一个坑:把 ndots 改得过小(如 0/1)会让带点但非 FQDN 的名字先按绝对域名解析失败,影响集群内多级域名,需按 Pod 灰度验证。

常见根因

  1. 默认 ndots:5:外部域名点数少于 5,先被拼上各 search 域查询多次,全部 NXDOMAIN 后才查绝对域名。
  2. search 列表含不可达或慢域,或条目过多(glibc 上限 6 个、总长 256 字节),触发超时重试。
  3. CoreDNS 过载或上游 DNS 慢,查询延迟与 SERVFAIL 增加。
  4. UDP 53 丢包或 conntrack 表压力,解析器按 timeout 重试,表现为固定几秒延迟。
  5. A 与 AAAA 并行查询遇到 IPv6 黑洞,getaddrinfo 等到超时才返回。
  6. 不同运行时解析行为不同:Go 纯 resolver 遵循 resolv.conf,Java/Node 有各自缓存策略。
  7. hostNetwork 或 dnsPolicy: Default 的 Pod 使用节点 DNS,没有集群 search/ndots 行为。
  8. NetworkPolicy 拦截 UDP/TCP 53,或负缓存缺失导致重复查询放大。

修复

相关命令

读完自测

  1. 为什么 dig 很快但应用解析仍然慢?
  2. ndots:5 具体会让 api.example.com 产生哪些查询?
  3. 把 ndots 调小有什么风险?
答案
  1. dig 默认不走 search/ndots 的 getaddrinfo 路径;应用侧会先尝试多个 search 后缀,失败后才查绝对域名。
  2. 依次查询 api.example.com.<ns>.svc.cluster.local、api.example.com.svc.cluster.local、api.example.com.cluster.local,最后才查 api.example.com.。
  3. 带点的非 FQDN 名字会先按绝对域名解析,可能破坏集群内多级域名或短名解析,需要按 Pod 灰度验证。