Kubernetes生产运维07:CoreDNS解析慢或解析失败,怎么顺着ndots和搜索域找到真因 Kubernetes生产运维07CoreDNS解析慢或解析失败怎么顺着ndots和搜索域找到真因写在前面DNS一出问题很多人的第一反应是CoreDNS是不是挂了然后去重启CoreDNS。但DNS故障的表现有三种根因完全不同解析失败根本查不到、解析慢能查到但耗时长、解析到错误地址查到了但指向不对。CoreDNS本身异常只是其中一种可能。更常见的是客户端把短名字发出去因为ndots和搜索域机制被放大成多次查询跨命名空间名字写错上游DNS转发超时或者缓存了旧记录。因此DNS排查要沿着这条链路逐段确认访问报错疑似DNS → 先区分是解析失败、解析慢还是解析到错误地址 → 看Pod的resolv.confnameserver、search和ndots → 判断是名字写法问题还是CoreDNS或上游问题 → 查CoreDNS Pod、日志、配置和上游转发 → 针对性修复并验证 → 补DNS监控与域名规范本文按照Kubernetes官方机制和命令参考整理。由于当前没有连接可验证的实验集群命令没有在统一版本的真实集群完整执行案例和终端输出均为C级生产化重建不是生产原始记录。不同Kubernetes版本、DNS实现、CNI和云厂商可能改变字段、配置和行为执行前应以目标集群的实际状态为准。一、先理解Pod是怎么解析域名的1.1 resolv.conf决定查询怎么展开kubelet为每个Pod配置/etc/resolv.conf。默认ClusterFirst策略下典型内容是nameserver 10.96.0.10 search namespace.svc.cluster.local svc.cluster.local cluster.local options ndots:5三部分含义nameserver集群DNS的ClusterIP通常指向CoreDNS的Servicesearch搜索域列表用于把短名字补全成完整域名options ndots:5当查询名字中的点数少于5个时先依次拼接搜索域尝试1.2 ndots:5为什么会把一次查询放大成多次这是DNS问题里最容易被忽略、又最常见的性能陷阱。规则是如果要查询的名字包含的点数小于ndots值默认5解析器会先把名字依次拼上每个搜索域尝试都失败后才把它当作绝对域名直接查。举例Pod在test命名空间里查询外部域名api.example.com2个点小于5api.example.com.test.svc.cluster.local → 查询1NXDOMAIN api.example.com.svc.cluster.local → 查询2NXDOMAIN api.example.com.cluster.local → 查询3NXDOMAIN api.example.com → 查询4才成功一次外部域名解析变成了4次查询前3次都是无用的NXDOMAIN。在高频调用下这会显著增加DNS延迟和CoreDNS负载表现为解析慢而不是解析失败。避免放大的方法给外部域名加结尾的点写成FQDN例如api.example.com.解析器就不再拼搜索域直接查询。1.3 集群内名字的正确写法集群内访问Service的短名字利用搜索域是合理的同命名空间直接用service跨命名空间用service.namespace完整形式service.namespace.svc.cluster.local一个高频错误是跨命名空间只写了service。因为搜索域第一条是本命名空间短名字会先在本命名空间找找不到就沿搜索域继续最终可能NXDOMAIN或找错对象。跨命名空间必须带上命名空间。1.4 ClusterFirst与上游转发默认dnsPolicy: ClusterFirst下不匹配集群域后缀的查询如www.example.com会被CoreDNS转发到上游DNS。所以外部域名解析不了可能不是CoreDNS本身而是它到上游的转发链路有问题。dnsPolicy和dnsConfig可以调整这套行为例如None加自定义dnsConfig完全自定义nameserver、search和options。二、DNS排查决策树疑似DNS问题 │ ├─ 先区分症状 │ ├─ 解析失败NXDOMAIN/SERVFAIL → 查名字写法、CoreDNS、上游 │ ├─ 解析慢 → 查ndots放大、CoreDNS负载、上游延迟 │ └─ 解析到错误地址 → 查缓存、重名Service、自定义hosts │ ├─ 看客户端Pod的resolv.conf │ ├─ nameserver是否指向集群DNS │ ├─ search和ndots是否异常 │ └─ 名字是短名还是FQDN │ ├─ 在Pod内实测解析 │ ├─ 集群内名字能否解析 │ ├─ 外部名字能否解析 │ └─ 直接查FQDN是否更快或成功 │ ├─ 查CoreDNS │ ├─ CoreDNS Pod是否Running且就绪 │ ├─ CoreDNS日志有无错误或上游超时 │ └─ Corefile转发和缓存配置 │ ├─ 针对性修复并验证 │ └─ 补DNS监控与域名规范先确认集群DNS组件在跑kubectl get pods-nkube-system-lk8s-appkube-dns-owide kubectl get svc-nkube-system-lk8s-appkube-dnsCoreDNS通常用k8s-appkube-dns这个标签Service名一般是kube-dns历史兼容命名。三、取证从Pod内看起3.1 看客户端Pod的resolv.confNSnamespacePODpod-namekubectlexec$POD-n$NS--cat/etc/resolv.conf关注nameserver是否是集群DNS的ClusterIPsearch域是否符合预期ndots值默认5如果Pod用了dnsPolicy: None或自定义dnsConfig这里可能和默认完全不同要结合Pod spec看。3.2 在Pod内实测解析排障时用带工具的临时容器而不是假设业务容器里有dig或nslookupkubectl run dnsutils--rm-it--restartNever-n$NS\--imageapproved-dns-utils-image--\sh-cnslookup kubernetes.default; echo ---; nslookup target-name这条命令会临时创建一个调试Pod属于主动操作需使用经审批的镜像并在完成后自动清理。判断kubernetes.default能解析说明集群内DNS链路基本正常目标名字解析失败重点看是名字写法还是特定记录问题加结尾点直接查FQDN明显更快或成功说明是ndots放大或搜索域问题3.3 区分三种症状# 在临时Pod内对比短名和FQDN的解析nslookuporders.other-ns# 短名跨命名空间nslookuporders.other-ns.svc.cluster.localnslookupapi.example.com# 外部短名会被搜索域放大nslookupapi.example.com.# 外部FQDN结尾点直接查短名失败但FQDN成功 → 名字写法或搜索域问题都能解析但外部短名明显慢 → ndots放大解析成功但地址不对 → 缓存或重名问题3.4 边界业务容器可能没有DNS工具不要假设有dig优先用带工具的临时Pod临时Pod属于主动操作需经审批镜像和清理不同DNS实现和版本的日志格式可能不同四、查CoreDNS本身只有在Pod内确认不是名字写法问题后才深入CoreDNS。4.1 CoreDNS状态与日志kubectl get pods-nkube-system-lk8s-appkube-dns-owide kubectl logs-nkube-system-lk8s-appkube-dns--tail100关注日志里是否有上游超时、SERVFAIL、插件错误或大量NXDOMAIN。多个CoreDNS副本时要看全部。4.2 Corefile配置kubectl get configmap coredns-nkube-system-oyaml关注forward插件指向的上游DNS地址是否可达cache的TTL设置kubernetes插件的集群域配置是否有自定义的stub domain或rewrite4.3 常见CoreDNS侧问题现象更可能的原因优先检查外部域名全部解析失败forward上游不可达Corefile forward地址、上游连通性间歇SERVFAIL上游超时或CoreDNS过载CoreDNS负载、副本数、上游延迟集群内解析也失败CoreDNS未就绪或kubernetes插件异常CoreDNS Pod状态、RBAC、日志解析慢但最终成功ndots放大或缓存未命中客户端ndots、cache配置解析到旧地址缓存TTL或负缓存cache TTL、记录变更时间CoreDNS正常拒绝不存在的记录NXDOMAIN本身不是故障要结合客户端名字写法一起判断。五、C级生产化重建案例外部接口调用突然变慢5.1 先说明哪些是真的哪些是重建的下面不是作者声称亲历的生产事故而是根据Kubernetes DNS、ndots和搜索域机制构造的生产化重建用于展示从解析慢走到可验证根因的取证过程。内容证据属性resolv.conf、ndots、搜索域和CoreDNS转发的机制Kubernetes官方机制外部接口调用变慢、DNS查询次数放大机制一致的重建场景Namespace、资源名、域名、延迟数值和终端输出为讲解构造的说明性信息代码使用外部短域名未写成FQDN模拟根因不是作者生产记录修正单一变量后验证解析变快受控验证设计不声称已在当前集群执行所有输出按真实对象关系编排但没有连接实际集群采集读者不能把下面的时间、数值或输出引用为真实事故数据。5.2 现场卡片一个服务频繁调用外部第三方接口最近调用整体变慢。业务功能正常、没有报错只是延迟升高。团队最初怀疑第三方接口变慢或网络抖动。重建的相对时间线相对时间观察或动作当时能够得出的结论T00监控显示外部调用延迟升高只能确认延迟上升原因未知T03怀疑第三方接口或网络待验证假设T06在Pod内实测发现DNS解析耗时占大头排查转向DNS而非第三方T09对比短名与FQDNFQDN明显更快指向ndots放大T12查resolv.conf确认ndots:5代码用了短域名得到可验证的主假设T验证让解析走FQDN或调整ndots观察是否变快单变量验证相对时间只表示排查顺序不代表真实数值。5.3 先在Pod内确认是DNS而不是第三方NSexample-prodPODpayment-gateway-abcde kubectlexec$POD-n$NS--cat/etc/resolv.conf机制一致的说明性输出nameserver 10.96.0.10 search example-prod.svc.cluster.local svc.cluster.local cluster.local options ndots:5ndots是默认的5搜索域是标准的三条。业务代码调用的外部域名是api.thirdparty.com2个点小于5。5.4 对比短名与FQDN的解析用带工具的临时Pod实测kubectl run dnsutils--rm-it--restartNever-n$NS\--imageapproved-dns-utils-image--\sh-ctime nslookup api.thirdparty.com; echo ; time nslookup api.thirdparty.com.机制一致的说明性输出api.thirdparty.com 前3次拼搜索域均NXDOMAIN第4次才成功 real 0m0.42s api.thirdparty.com. 直接查询一次成功 real 0m0.06s对比说明短名解析明显更慢因为先拼了3次搜索域都NXDOMAIN带结尾点的FQDN直接查询快很多。这支持ndots放大是延迟来源。5.5 用CoreDNS日志侧证kubectl logs-nkube-system-lk8s-appkube-dns--tail50|grepthirdparty机制一致的说明性输出api.thirdparty.com.example-prod.svc.cluster.local. NXDOMAIN api.thirdparty.com.svc.cluster.local. NXDOMAIN api.thirdparty.com.cluster.local. NXDOMAIN api.thirdparty.com. NOERRORCoreDNS日志清楚显示同一次业务调用触发了4条查询前3条是搜索域拼出来的无用NXDOMAIN。这与Pod内实测一致。5.6 确认根因来源# 确认业务代码或配置里用的是短域名而非FQDNkubectl get configmap payment-config-n$NS-oyaml|grep-ithirdpartygitgrep-napi.thirdparty.com-- config/机制一致的说明性差异THIRDPARTY_ENDPOINT: https://api.thirdparty.com/v1配置里用的是不带结尾点的短域名,证据链resolv.conf ndots:5搜索域三条 外部域名只有2个点触发搜索域放大 Pod内实测短名比FQDN慢数倍 CoreDNS日志每次调用有3条无用NXDOMAIN加1条成功 配置使用不带结尾点的外部短域名 强烈支持ndots放大导致外部解析变慢这仍是主假设验证前不写成根因已闭环。5.7 止损与单变量验证这类问题不需要重启CoreDNS改动点在客户端的名字写法或DNS配置。可选的单变量修正把外部域名写成FQDN结尾加点最精准、影响最小或给该Pod设置dnsConfig把ndots调小但影响该Pod所有解析范围更大优先选影响最小的FQDN方案。只改这一处不同时动CoreDNS、副本和缓存# 配置中把外部域名写成FQDN末尾加点env:-name:THIRDPARTY_ENDPOINTvalue:https://api.thirdparty.com./v1验证并保存修复后证据kubectl rollout status deployment/payment-gateway-n$NS--timeout5m kubectl run dnsutils--rm-it--restartNever-n$NS\--imageapproved-dns-utils-image--\sh-ctime nslookup api.thirdparty.com.kubectl logs-nkube-system-lk8s-appkube-dns--tail20|grepthirdparty机制一致的说明性输出deployment payment-gateway successfully rolled out api.thirdparty.com. 直接查询一次成功 real 0m0.06s CoreDNS日志中不再出现拼搜索域的NXDOMAIN这些输出分别证明不同范围的事实输出能够支持不能单独证明rollout成功Deployment滚动完成所有调用路径都改到FQDNFQDN解析一步成功该域名不再被搜索域放大第三方接口本身一定快CoreDNS无多余NXDOMAIN放大问题在该域名上消除其他短域名也已修正5.8 根因闭环条件修正版与问题版只有域名写法这一项主要差异。修正后同一域名解析从多次查询变为一次。CoreDNS日志不再出现该域名的搜索域NXDOMAIN。外部调用延迟中DNS部分下降。观察窗口内延迟稳定没有反复。如果改成FQDN后解析仍慢就要停止把ndots当作唯一原因转查CoreDNS负载、上游延迟和网络。六、修复方案要分六层层次本文场景中的动作关键边界应急止损对高频外部域名改用FQDN缓解放大确认改动范围避免漏改其他调用点现场取证保存resolv.conf、Pod内解析对比、CoreDNS日志和配置临时Pod属主动操作需经审批镜像根因验证只改域名写法或单个Pod的ndots并观察不同时改CoreDNS、副本和缓存永久修复在源配置统一外部域名写法或按需调整dnsConfig全局改ndots影响面大需评估监控预防监控DNS查询速率、NXDOMAIN比例和解析延迟区分正常查询和搜索域放大运行治理域名写法规范、CoreDNS容量与缓存、NodeLocal DNS评估大规模集群考虑本地DNS缓存不要一遇到DNS慢就重启CoreDNS。ndots放大和名字写法问题重启CoreDNS无效盲目全局调小ndots可能影响集群内短名解析属于大范围变更要谨慎评估。七、可直接使用的只读DNS采集脚本脚本只读取配置和日志不重启CoreDNS、不改Corefile、不改客户端配置。连通性测试需另用临时Pod属主动操作。#!/usr/bin/env bashset-uset-opipefailNS${1:?用法:$0 namespace pod-name}POD${2:?用法:$0 namespace pod-name}STAMP$(date%Y%m%d-%H%M%S)OUTdns-evidence-${NS}-${POD}-${STAMP}mkdir-p$OUTumask077capture(){localfile$1shiftprintf采集 %s\n$fileif!$$OUT/$file2$OUT/$file.err;thenprintf失败: %s查看 %s.err\n$file$file2fi}capture context.txt kubectl config current-context capture version.txt kubectl version capture resolv-conf.txt kubectlexec$POD-n$NS--cat/etc/resolv.conf capture pod-dns-spec.txt kubectl get pod$POD-n$NS\-ojsonpath{dnsPolicy}{.spec.dnsPolicy}{\ndnsConfig}{.spec.dnsConfig}{\n}capture coredns-pods.txt kubectl get pods-nkube-system\-lk8s-appkube-dns-owide capture coredns-svc.txt kubectl get svc-nkube-system-lk8s-appkube-dns capture coredns-logs.txt kubectl logs-nkube-system\-lk8s-appkube-dns--tail200capture corefile.yaml kubectl get configmap coredns-nkube-system-oyamlprintf采集完成: %s\n$OUTprintf解析实测请另用带DNS工具的临时Pod属主动操作\nprintf分享前请检查域名、地址和配置引用中的敏感信息\n使用方式bashcollect-dns-evidence.shnamespacepod-name脚本边界业务容器需有cat读取resolv.conf解析实测需另用带工具的临时PodCoreDNS标签在个别发行版可能不同需按实际调整脚本用于保存首轮现场不能替代按症状选择下一步八、监控、缓存与治理8.1 监控什么DNS查询速率和每Pod查询数NXDOMAIN比例异常升高常意味搜索域放大CoreDNS解析延迟和错误率CoreDNS CPU、内存和限流丢弃上游DNS转发延迟和超时告警不能只看CoreDNS是否Running。ndots放大、上游慢和缓存问题都可能在CoreDNS正常时发生。8.2 域名与配置规范高频外部域名统一写成FQDN避免搜索域放大跨命名空间访问必须带命名空间需要时按Pod用dnsConfig调整ndots评估影响范围后再全局改大规模集群评估NodeLocal DNSCache降低CoreDNS压力和延迟8.3 CoreDNS容量与缓存根据查询量配置CoreDNS副本和资源合理设置cache TTL平衡新鲜度和命中率关注上游DNS的可靠性和延迟CoreDNS配置变更走灰度和验证避免全集群解析中断九、常见误区误区1DNS一慢就重启CoreDNSndots放大和名字写法问题重启无效先在Pod内定位症状。误区2忽略ndots:5的放大效应外部短域名会被拼搜索域多次查询是解析慢的常见原因。误区3跨命名空间只写Service短名短名先在本命名空间找跨命名空间必须带命名空间。误区4假设业务容器里有dig或nslookup很多镜像没有DNS工具应用带工具的临时Pod实测。误区5把NXDOMAIN都当成故障CoreDNS拒绝不存在的记录是正常的要结合名字写法判断。误区6解析慢却不看是否是上游外部域名解析走上游转发慢可能在上游而非CoreDNS本身。误区7全局调小ndots不评估影响全局改ndots会影响集群内短名解析属大范围变更。误区8解析到旧地址不查缓存记录变更后旧地址可能来自缓存TTL或负缓存。十、面试怎么说60秒版本DNS问题我不会先重启CoreDNS。先区分是解析失败、解析慢还是解析到错误地址。然后进Pod看resolv.conf的nameserver、search和ndots用带工具的临时Pod实测解析。解析慢很常见的原因是ndots:5把外部短域名拼搜索域放大成多次查询对比FQDN会明显更快。集群内跨命名空间要带命名空间。确认不是名字写法后才查CoreDNS状态、日志和上游转发。修复优先改域名写法这种最小变更最后补DNS延迟和NXDOMAIN监控。3分钟场景版本假设外部接口调用变慢但不报错。我先怀疑是不是第三方或网络但在Pod内实测发现DNS解析占了大头。看resolv.conf是默认的ndots:5和三条搜索域业务用的外部域名只有两个点。我用带工具的临时Pod对比短名和带结尾点的FQDNFQDN明显快很多。再看CoreDNS日志同一次调用有3条拼搜索域的NXDOMAIN加1条成功确认是ndots放大。回到配置发现用的是不带结尾点的短域名。我只把这个域名改成FQDN不动CoreDNS和ndots全局配置改完解析从多次变一次CoreDNS不再出现无用NXDOMAIN外部调用延迟下降。这样我能区分是客户端域名写法问题而不是CoreDNS故障也不会用重启CoreDNS这种无关动作去掩盖。十一、延伸问答1. ndots:5到底是什么意思查询名字点数小于5时先依次拼搜索域尝试都失败才当绝对域名直接查。外部短域名因此被放大成多次查询。2. 怎么快速判断是不是ndots放大在Pod内对比短名和带结尾点的FQDN解析耗时FQDN明显更快就是放大。3. 跨命名空间访问为什么失败短名先在本命名空间解析跨命名空间要写service.namespace或完整FQDN。4. 解析慢一定是CoreDNS的问题吗不一定。ndots放大在客户端外部域名慢可能在上游转发都不是CoreDNS本身故障。5. 为什么用临时Pod而不是业务容器实测很多业务镜像没有dig或nslookup用带工具的临时Pod更可靠但属主动操作。6. 全局调小ndots可行吗可行但影响大会改变集群内短名解析行为属大范围变更需充分评估或改用按Pod的dnsConfig。7. 解析到旧地址怎么办检查cache TTL和负缓存以及记录变更时间必要时等待TTL过期或调整缓存策略。8. NodeLocal DNSCache有什么用在每个节点本地缓存DNS减少对CoreDNS的查询和网络往返降低延迟适合大规模或高频解析集群。小结DNS故障分解析失败、解析慢、解析到错误地址三种根因不同。resolv.conf的search和ndots决定短名字怎么展开。ndots:5会把外部短域名放大成多次查询是解析慢的常见原因。外部高频域名写成FQDN加结尾点可避免放大。跨命名空间访问必须带命名空间。先在Pod内定位症状确认不是名字写法后再查CoreDNS和上游。修复优先最小变更不盲目重启CoreDNS或全局改ndots。长期治理覆盖域名规范、CoreDNS容量缓存、NodeLocal DNS和DNS监控。下一篇预告下一篇进入Ingress 404与502。我们会沿着路由、Service、Endpoint、证书、超时和控制器日志区分路由不匹配、后端无实例和后端超时并整理一份七层流量排查图。参考资料Kubernetes官方文档DNS for Services and PodsKubernetes官方文档Customizing DNS ServiceKubernetes官方文档Debugging DNS ResolutionKubernetes官方文档Using NodeLocal DNSCache in Kubernetes ClustersKubernetes官方文档Autoscale the DNS Service in a ClusterKubernetes官方文档ServiceKubernetes官方文档Using CoreDNS for Service DiscoveryKubernetes官方文档Debug ServicesCoreDNS官方文档Kubernetes DNS-Based Service Discovery规范