K8s DNS解析超时ndots与autopath的连环坑

K8s DNS 解析超时:ndots 与 autopath 的连环坑

1. 问题现象

  • 集群中多个微服务偶发性调用超时,错误日志 i/o timeout / no such host
  • 同一 Pod 内对同域名解析:有时 <1ms 正常,有时卡死 5 秒
  • nslookup 测试:不带域名后缀偶发卡顿,带完整 FQDN 基本正常
  • CoreDNS Pod 的 CPU/内存正常,无 OOM、无重启

2. 排查过程

Step 1 ------ 在问题 Pod 内抓 DNS 包

bash 复制代码
tcpdump -i any port 53 -w /tmp/dns.pcap

发现一次请求同时发出 A + AAAA 查询,且带 .svc.cluster.local 后缀的域名被多次拼接重试。

Step 2 ------ 检查 /etc/resolv.conf

复制代码
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

关键线索:ndots:5 --- 域名中点数 < 5 的,会先逐一拼接 search domain 再查询。

Step 3 ------ 模拟查询过程

应用调用 redis-cache(3个点 < 5),CoreDNS 依次查询:

复制代码
redis-cache.default.svc.cluster.local  → NXDOMAIN
redis-cache.svc.cluster.local          → NXDOMAIN
redis-cache.cluster.local              → NXDOMAIN
redis-cache.                           → 终于成功

每个 NXDOMAIN 等 5 秒超时,3 × 5 = 15 秒

Step 4 ------ 深挖 CoreDNS 配置

启用了 autopath 却没有配置 @kubernetes 策略,导致每次 search domain 拼接都去查一次 Kubernetes API/etcd,高并发下 autopath 内部锁竞争爆炸。

3. 根因

层面 问题
Pod DNS Config ndots:5(Linux默认值)不适合微服务短域名场景
CoreDNS autopath 配置不当,每次search domain拼接都触发K8s API查询
复合效应 ndots放大请求量 × autopath放大单次开销 = 指数级延迟

4. 解决方案

① 调整 ndots(最直接)

yaml 复制代码
# Pod spec 或全局 dnsConfig
dnsConfig:
  options:
    - name: ndots
      value: "2"   # 内部服务通常 ≥ 2段,直接走FQDN

② 应用代码用 FQDN

复制代码
redis-cache.default.svc.cluster.local   # 6个点 > ndots,不拼接

③ CoreDNS ConfigMap 修复 autopath

yaml 复制代码
kubernetes cluster.local in-addr.arpa ip6.arpa {
  pods insecure
  endpoint_pod_names
}

④ 确认 cache TTL 合理

yaml 复制代码
cache 30

5. 复盘总结

  1. ndots:5 是 K8s 微服务场景的隐性性能杀手 --- 大多数内部服务名只有2-3段,默认ndots=5会导致大量无意义的search domain拼接
  2. autopath 不是免费午餐 --- 配置不当会指数级放大DNS查询开销
  3. DNS监控不能只看CoreDNS Pod的资源 --- 要看实际的解析延迟和超时率
  4. 排查DNS问题三件套:抓包 → 查resolv.conf → 模拟查询过程

应用场景:Kubernetes 1.24+,CoreDNS,微服务架构

关键词:K8s DNS、ndots、autopath、CoreDNS、NXDOMAIN、search domain、DNS超时