在 kind 集群里停掉 CoreDNS 复现集群内域名解析失败,练习分层定位

演练目标

环境准备

安装 Docker、kind 和 kubectl。kind 默认自带 CoreDNS,适合做这个实验。

kind create cluster --name lab-dns
kubectl get nodes
kubectl -n kube-system get deployment,pods -l k8s-app=kube-dns
kubectl run dnslab --image=busybox:1.36 --restart=Never -- sleep 3600
kubectl wait --for=condition=Ready pod/dnslab --timeout=90s
kubectl exec dnslab -- nslookup kubernetes.default

基线解析应成功,并返回 kubernetes.default.svc.cluster.local 对应的 ClusterIP。记下这个结果,便于和故障后对比。

注入故障

把 CoreDNS 副本数缩到 0,模拟 DNS 组件全部不可用:

kubectl -n kube-system scale deployment coredns --replicas=0
kubectl -n kube-system wait --for=delete pod -l k8s-app=kube-dns --timeout=60s
kubectl -n kube-system get pods -l k8s-app=kube-dns

这是实验手段,不是生产修复方式。生产环境应通过滚动更新、NetworkPolicy 或上游 DNS 配置来模拟局部故障,避免集群内所有解析同时中断。

观察现象

kubectl exec dnslab -- cat /etc/resolv.conf
kubectl exec dnslab -- timeout 15 nslookup kubernetes.default
kubectl exec dnslab -- timeout 15 nslookup kubernetes.default.svc.cluster.local
kubectl -n kube-system get svc kube-dns
kubectl -n kube-system get endpoints kube-dns
kubectl get events -n kube-system --sort-by=.lastTimestamp | tail -20

预期 resolv.conf 仍指向 kube-dns 的 ClusterIP,并带有 options ndots:5;nslookup 超时或报 no such host、Temporary failure in name resolution;kube-dns Service 仍然存在,但 Endpoints 为空,因为已经没有 CoreDNS Pod。

判断与定位

  1. 先看 /etc/resolv.conf 中的 nameserver 是否可达。如果所有域名都失败,问题在解析器或 CoreDNS;如果只有某个 Service 失败,检查 Service、Endpoints 和 NetworkPolicy。
  2. 用 FQDN 和短域名分别测试。短域名会按 ndots:5 依次尝试多个 search 域,失败时延迟明显更长,容易误判为“DNS 很慢”。
  3. 看 CoreDNS Pod 是否 Running、Service 是否有 Endpoints、CoreDNS 日志是否报上游超时或插件错误。
  4. 容易误判:Service 域名解析成功不代表服务可用;ClusterIP Service 即使没有后端 Endpoints 也能解析出 IP,连接才会失败。另一个误判是把应用连接超时直接归因于 DNS,实际可能是 NetworkPolicy 或 CNI。
  5. 如果只有新建 Pod 解析失败,检查 dnsPolicy 和 dnsConfig 是否被覆盖。

修复

恢复 CoreDNS 副本并验证解析:

kubectl -n kube-system scale deployment coredns --replicas=2
kubectl -n kube-system rollout status deployment/coredns --timeout=120s
kubectl -n kube-system get pods -l k8s-app=kube-dns
kubectl -n kube-system get endpoints kube-dns
kubectl exec dnslab -- nslookup kubernetes.default

等 Endpoints 中出现 CoreDNS Pod IP 后,解析应恢复。生产环境还要检查 CoreDNS 的副本数、反亲和性、资源限制和上游转发配置,避免单点或上游超时。

清理与回滚

kubectl delete pod dnslab --ignore-not-found
kind delete cluster --name lab-dns

如果演练中断,务必先执行 kubectl -n kube-system scale deployment coredns --replicas=2,恢复集群 DNS 后再删除集群。

复盘

延伸阅读

读完自测

  1. CoreDNS 全部停止后,Pod 的 /etc/resolv.conf 会变成空吗?
  2. Service 域名能解析出 IP,但连接失败,可能是什么原因?
  3. ndots:5 对短域名解析有什么影响?
答案
  1. 不会。resolv.conf 仍指向 kube-dns Service 的 ClusterIP,只是该地址后面没有可用的 CoreDNS 后端。
  2. 可能是 Service 没有 Endpoints、后端 Pod 未就绪、NetworkPolicy 拦截,或服务端口配置错误。
  3. 短域名会先尝试多个 search 域,查询次数增加,失败时延迟更长;使用 FQDN 可以减少无效查询。