问题出现得很突然,日志倒是留得挺全。Kubernetes 里的 Java 服务调第三方接口,一天有几十次耗时突然多五秒,抓包看到解析一个带点的域名时连着发了四五个查询才拿到正确记录,换成 IP 直连就完全正常。
刚开始盯着「两个 DNS 服务器里有一台已经不可用,要等五秒超时才切到下一台」,折腾了半个多小时,排掉了。
把日志和配置对完,能解释这个现象的基本就这几处。resolv.conf 里 ndots 设成 5,名字里的点数不够就先拼搜索域挨个试。另一种情况是search 域写了三个,每个都要等前一个返回 NXDOMAIN 才继续下一个。
另外,应用没做解析缓存,每次新建连接都重走一遍完整的搜索流程。
上来先看当前的搜索域和 ndots
cat /etc/resolv.conf
手工验证一次解析走了几轮
dig +search api.example.com +noall +answer +stats
然后抓包确认是哪台 DNS 没回包
tcpdump -i any -nn port 53 -c 40
末了把 ndots 调到 1 并缩短超时
sed -i 's/options ndots:5/options ndots:1 timeout:2/' /etc/resolv.conf
别只看报错消失,验证要多做一步。同一个域名的解析耗时稳定在二十毫秒以内,抓包里一次查询就能拿到应答,接口那种偶发的五秒毛刺消失。
ndots 调小之后短名字不会再自动补成 svc.cluster.local,得改成带结尾点的全限定名;Kubernetes 里这个值由 dnsConfig 控制,直接改容器内文件下次重建就没了。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。
