CoreDNS上游UDP读超时说明转发链路异常,需分层排查:先验证内外域名解析差异锁定范围,再通过节点/容器内直连测试上游可达性,检查forward配置合法性,确认health状态,并排除NodeLocal DNSCache或conntrack溢出干扰。

当业务Pod中nslookup命令偶发返回readudp 10.1.2.3:44211->10.0.0.2:53: i/o timeout,说明CoreDNS在转发外部域名请求时,无法在2秒内从上游DNS服务器收到UDP响应,必须立即分层隔离是上游网络问题、CoreDNS自身负载异常,还是集群数据面转发链路中断。
确认超时是否只影响外部域名
进入任意异常Pod执行:
nslookup kubernetes.default.svc.cluster.local
nslookup google.com
若前者稳定成功、后者间歇失败,则问题锁定在CoreDNS的上游转发环节,而非内部服务发现或Corefile语法错误;若两者均失败,优先检查CoreDNS Pod状态与Service Endpoint绑定。
验证CoreDNS上游连通性是否真实中断
方法一:在CoreDNS Pod所在节点上直连上游DNS
先获取一个CoreDNS Pod所在节点IP:kubectl get pod -n kube-system -l k8s-app=kube-dns -o wide
登录该节点,执行:nc -vzu 8.8.8.8 53(UDP端口探测)
若连接被拒绝或超时,说明节点出站策略阻断了UDP 53——公有云环境常见于未放行VPC DNS地址(如AWS的169.254.169.253、Azure的168.63.129.16)或安全组限制。
方法二:在CoreDNS容器内测试上游可达性
临时进入CoreDNS容器:kubectl exec -it -n kube-system <coredns-pod-name> -- sh
安装dig:apk add bind-tools(Alpine镜像)或apt-get update && apt-get install -y dnsutils(Debian系)
执行:dig @8.8.8.8 google.com +short
【若此命令也超时,说明CoreDNS容器网络栈无法触达上游DNS,此时无需再查Corefile配置】
检查CoreDNS配置中forward插件是否启用且指向有效地址
第一步:提取当前Corefile内容
kubectl get cm coredns -n kube-system -o yaml | grep "corefile:" -A 20
第二步:定位forward行,确认其后至少跟一个可路由的DNS地址
典型合法配置:forward . 169.254.169.253 8.8.8.8;非法配置包括:forward . 127.0.0.1(宿主机loopback在容器内不可达)、forward . (空参数)、forward . 10.96.0.10(指向自身造成死循环)
第三步:检查是否启用了health插件并监听localhost:8080,用curl http://localhost:8080/health确认CoreDNS进程存活且未因OOM被kill。
排除NodeLocal DNSCache干扰
若集群已部署NodeLocal DNSCache,它会劫持Pod的/etc/resolv.conf,将nameserver设为169.254.20.10。此时i/o timeout实际发生在NodeLocal组件与CoreDNS之间。
执行:kubectl get daemonset -n kube-system node-local-dns
若存在,进入业务Pod检查cat /etc/resolv.conf,若nameserver为169.254.20.10,则需排查NodeLocal DNSCache Pod日志:kubectl logs -n kube-system -l k8s-app=node-local-dns --tail=50
重点查找upstream timeout或no upstream available字样——这表示NodeLocal未能将请求正确转发至CoreDNS。
强制绕过Service VIP直连CoreDNS Pod IP测试
① 获取一个健康CoreDNS Pod的IP:kubectl get pod -n kube-system -l k8s-app=kube-dns -o jsonpath='{.items[0].status.podIP}'
② 在业务Pod中执行:nslookup google.com <coredns-pod-ip>
③ 对比结果:若直连成功但通过10.96.0.10失败,则问题不在CoreDNS本身,而在kube-proxy规则、conntrack表溢出或NetworkPolicy拦截。
此时运行:kubectl get nodes -o wide → 登录对应节点 → 执行:sudo conntrack -L | grep :53 | wc -l,若数值接近65536,即触发Linux conntrack上限,需调大net.netfilter.nf_conntrack_max。


















