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. 复盘总结
- ndots:5 是 K8s 微服务场景的隐性性能杀手 --- 大多数内部服务名只有2-3段,默认ndots=5会导致大量无意义的search domain拼接
- autopath 不是免费午餐 --- 配置不当会指数级放大DNS查询开销
- DNS监控不能只看CoreDNS Pod的资源 --- 要看实际的解析延迟和超时率
- 排查DNS问题三件套:抓包 → 查resolv.conf → 模拟查询过程
应用场景:Kubernetes 1.24+,CoreDNS,微服务架构
关键词:K8s DNS、ndots、autopath、CoreDNS、NXDOMAIN、search domain、DNS超时