Kubernetes DNS解析失败怎么排查:CoreDNS、Service与网络路径

应用访问 Service 超时、域名 NXDOMAIN 或 Pod 内解析偶发失败时,问题可能在 CoreDNS,也可能在 Service、网络策略或节点路径。本文给出 Kubernetes DNS解析失败的分层排查流程。

本文定位与适用场景

  • 面向 Kubernetes 集群内 Service DNS、CoreDNS 和 Pod 解析问题排查。
  • 适用于 Pod 内访问服务失败、跨命名空间域名错误、外部域名解析异常等场景。
  • 不覆盖所有 CNI 细节,但会说明网络策略、iptables/ipvs 和节点路径的排查入口。

1. 先确认现象:解析失败还是连接失败

很多“DNS 问题”其实是服务连接失败。建议先区分四类现象:

现象 典型报错 更可能的方向
域名不存在 NXDOMAINno such host 域名拼写、命名空间、Service 不存在
DNS 服务异常 SERVFAIL、查询超时 CoreDNS、kube-dns Service、网络路径
解析成功但访问失败 能解析 IP,但 curl 超时 Endpoint、Pod 后端、NetworkPolicy、应用端口
偶发慢或失败 部分 Pod 失败、重试后成功 CoreDNS 容量、节点网络、conntrack、上游 DNS

表格之后的第一步是做最小化复现:在同命名空间启动一个临时 Pod,用相同域名、相同端口、相同命名空间路径测试,避免把应用自身 DNS 缓存或 SDK 行为误认为集群问题。

Kubernetes DNS解析失败排查路径图

图 1:DNS 域名不存在、解析超时、连接失败和偶发异常的排查分流。

2. Kubernetes DNS解析失败的查询链路

一个 Pod 访问 my-svc.my-ns.svc.cluster.local 时,典型链路如下:

  1. 应用调用系统解析库,读取 Pod 内 /etc/resolv.conf
  2. 查询请求发往 nameserver,通常是 kube-dns Service 的 ClusterIP。
  3. kube-proxy 或数据面规则把请求转发到 CoreDNS Pod。
  4. CoreDNS 根据 Kubernetes 插件查询 Service、EndpointSlice 等对象。
  5. 如果是外部域名,CoreDNS 再转发到上游 DNS。
  6. 应用拿到 IP 后,才进入后续 TCP/HTTP 连接阶段。

因此,Kubernetes DNS解析失败要同时看控制面对象、DNS 服务、节点转发和应用侧配置。只重启 CoreDNS 可能临时缓解,但如果根因是 Endpoint 为空或 NetworkPolicy 拦截,问题会再次出现。

CoreDNS Service与网络解析链路分层图

图 2:Pod 到 kube-dns Service、CoreDNS、Kubernetes API 和上游 DNS 的查询路径。

3. 用调试 Pod 复现:把应用问题和集群问题分开

建议先创建一个临时调试 Pod。不同镜像内置工具不同,可以按环境选择 busybox、dnsutils 或网络诊断镜像。

kubectl run dns-debug -n default --rm -it --restart=Never 
  --image=busybox:1.36 -- sh

在 Pod 内执行:

cat /etc/resolv.conf
nslookup kubernetes.default.svc.cluster.local
nslookup my-service.my-namespace.svc.cluster.local
wget -S -O- http://my-service.my-namespace.svc.cluster.local:8080

如果 kubernetes.default.svc.cluster.local 无法解析,优先排查 CoreDNS 或集群 DNS 路径。如果它可以解析,而业务 Service 不能解析,则优先看 Service 名称、命名空间和对象是否存在。

更进一步,可以在不同节点上运行调试 Pod:

kubectl get pod dns-debug -o wide
kubectl run dns-debug-node2 -n default --rm -it --restart=Never 
  --image=busybox:1.36 
  --overrides='{"spec":{"nodeSelector":{"kubernetes.io/hostname":"node-2"}}}' -- sh

如果只有某个节点上的 Pod 解析失败,问题更可能在节点本地网络、kube-proxy、CNI、conntrack 或节点到 CoreDNS 的路径。

4. 检查 CoreDNS:状态、日志、配置和容量

4.1 检查 CoreDNS Pod 与 kube-dns Service

kubectl -n kube-system get deploy coredns
kubectl -n kube-system get pods -l k8s-app=kube-dns -o wide
kubectl -n kube-system get svc kube-dns -o wide
kubectl -n kube-system get endpoints kube-dns

关注点包括:

  • CoreDNS Pod 是否 Running,重启次数是否持续增加。
  • kube-dns Service ClusterIP 是否与 Pod 内 nameserver 一致。
  • kube-dns Endpoints 是否指向健康的 CoreDNS Pod。
  • CoreDNS 是否被调度到异常节点或资源紧张节点。

4.2 查看 CoreDNS 日志

kubectl -n kube-system logs deploy/coredns --tail=200

常见线索包括:

plugin/errors: 2 example.com. A: read udp ... i/o timeout
SERVFAIL
no route to host

如果日志显示访问上游 DNS 超时,集群内 Service DNS 可能正常,但外部域名转发失败。此时要检查 CoreDNS ConfigMap 中的 forward 配置、节点 DNS、网络出口和防火墙策略。

4.3 查看 CoreDNS 配置

kubectl -n kube-system get configmap coredns -o yaml

典型 Corefile 片段如下:

.:53 {
    errors
    health {
       lameduck 5s
    }
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
       pods insecure
       fallthrough in-addr.arpa ip6.arpa
       ttl 30
    }
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}

如果修改过 Corefile,建议重点检查 kubernetesforwardloopcache 等插件顺序和配置。生产环境不建议在没有回滚配置的情况下直接编辑 CoreDNS ConfigMap。

5. 检查 Service 与 Endpoint:名字对了不代表后端存在

5.1 确认 Service 名称和命名空间

Kubernetes Service DNS 常见格式包括:

<service>.<namespace>.svc.cluster.local
<service>.<namespace>.svc
<service>

短名称 <service> 只在同命名空间内更可靠。跨命名空间访问建议使用完整名称,减少 search domain 带来的误判。

检查对象:

kubectl get svc -n my-namespace my-service -o wide
kubectl get endpoints -n my-namespace my-service -o wide
kubectl get endpointslice -n my-namespace -l kubernetes.io/service-name=my-service

5.2 Endpoint 为空时 DNS 可能仍能解析

对于普通 ClusterIP Service,即使 Endpoint 为空,DNS 仍可能返回 Service ClusterIP;但访问该 IP 会失败。Headless Service 的行为不同,它通常直接返回后端 Pod IP,因此 Endpoint 为空时更容易表现为解析不到预期记录。

Service 类型 DNS 返回 Endpoint 为空时的常见表现
ClusterIP Service ClusterIP 能解析但访问失败或超时
Headless Service Pod IP 列表 记录为空或客户端拿不到后端
ExternalName CNAME 依赖外部域名解析和上游 DNS

表格之后要继续检查 selector 是否匹配 Pod:

kubectl get svc -n my-namespace my-service -o yaml
kubectl get pods -n my-namespace --show-labels

如果 Service selector 与 Pod label 不匹配,修复 Service 或 Deployment 标签比重启 CoreDNS 更有效。

6. 检查 Pod DNS 配置与网络路径

6.1 查看 Pod resolv.conf 与 dnsPolicy

kubectl get pod my-pod -n my-namespace -o yaml | grep -E "dnsPolicy|dnsConfig" -A10
kubectl exec -n my-namespace my-pod -- cat /etc/resolv.conf

常见 dnsPolicy 包括:

  • ClusterFirst:默认策略,优先使用集群 DNS。
  • Default:继承节点 DNS 配置,可能无法解析集群 Service。
  • ClusterFirstWithHostNet:适用于 hostNetwork Pod 仍需使用集群 DNS 的场景。
  • None:完全自定义 DNS 配置,需要谨慎确认 nameserver 和 search。

如果 Pod 使用 hostNetwork: true 且没有设置合适的 dnsPolicy,可能出现服务域名解析失败。

6.2 检查 NetworkPolicy 是否拦截 DNS

如果命名空间启用了默认拒绝出站策略,需要允许到 kube-dns 的 UDP/TCP 53。示例方向如下:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: my-namespace
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53

不同 CNI 对 namespaceSelector、默认策略和 DNS 放行的实现细节可能不同,落地前应在非生产命名空间验证。

6.3 检查节点到 kube-dns ClusterIP 的路径

从节点角度看,DNS 请求会经过 kube-proxy 或 CNI 数据面规则。排查入口包括:

kubectl -n kube-system get pods -l k8s-app=kube-proxy -o wide
kubectl -n kube-system logs -l k8s-app=kube-proxy --tail=100
kubectl get nodes -o wide

如果集群使用 iptables 模式,可以在节点上查看相关规则;如果使用 ipvs、eBPF 或特定 CNI,需要使用对应工具。不要在生产节点上随意清空 iptables、重启网络服务或删除 CNI 状态目录,除非已有明确回滚方案。

7. 修复与预防:从止血到长期治理

修复动作要按风险从低到高排序:

  1. 修正 Service 名称、命名空间或 selector。
  2. 调整 NetworkPolicy,明确放行 DNS 到 kube-dns。
  3. 修复 Pod dnsPolicy 或 dnsConfig。
  4. 回滚错误的 CoreDNS ConfigMap 变更。
  5. 扩容 CoreDNS 副本或调整资源请求。
  6. 排查节点 kube-proxy、CNI 或 conntrack 问题。

Kubernetes DNS解析失败修复优先级矩阵

图 3:DNS 修复优先级应先处理对象配置、DNS 放行和 Pod 策略,再进入 CoreDNS 容量与节点数据面排查。

长期治理建议:

  • 为 CoreDNS 配置合理副本数、资源请求和反亲和策略。
  • 监控 CoreDNS QPS、错误率、延迟和重启次数。
  • 对关键命名空间保留 DNS egress 放行基线。
  • 发布 Service 时同时检查 selector 与 EndpointSlice。
  • 在应用健康检查中区分 DNS 解析失败和服务连接失败。
  • 记录常见域名格式,减少跨命名空间短名称误用。

小结

Kubernetes DNS解析失败的排查顺序建议保持稳定:先区分解析失败和连接失败,再用调试 Pod 复现,随后检查 CoreDNS、Service/Endpoint、Pod DNS 配置、NetworkPolicy 和节点路径。这样可以避免把所有问题都归因于 CoreDNS,也能减少不必要的重启和高风险网络操作。

真正可靠的 DNS 治理,不只是故障时能查命令,还包括 CoreDNS 监控、Service 发布校验、网络策略基线和跨命名空间访问规范。

常见问题

1. Kubernetes DNS解析失败时要不要先重启 CoreDNS?

不建议把重启 CoreDNS 作为第一步。若 CoreDNS Pod 卡死或配置 reload 异常,重启可能短暂恢复;但如果根因是 Service 不存在、Endpoint 为空、NetworkPolicy 拦截或节点路径异常,重启只能掩盖问题。建议先用调试 Pod 和 CoreDNS 日志确认方向。

2. Pod 能解析 kubernetes.default,但解析业务 Service 失败怎么办?

这通常说明集群 DNS 基础链路可用,问题更可能在业务 Service 名称、命名空间、Headless Service、EndpointSlice 或 selector。建议检查 kubectl get svc/endpoints/endpointslice,并使用完整域名 <service>.<namespace>.svc.cluster.local 测试。

3. 为什么 DNS 解析成功但应用访问 Service 仍然超时?

DNS 只负责把域名解析为 IP。解析成功后,访问还会经过 Service 转发、Endpoint 后端、网络策略、应用监听端口和容器健康状态。此时应继续检查 Endpoint 是否为空、Pod 是否 Ready、目标端口是否正确,以及 NetworkPolicy 是否允许流量。

4. hostNetwork Pod 解析 Service 域名失败怎么处理?

hostNetwork Pod 默认 DNS 行为可能与普通 Pod 不同。如果它需要解析集群 Service,通常要检查是否设置了合适的 dnsPolicy,例如 ClusterFirstWithHostNet。同时确认 Pod 内 /etc/resolv.conf 是否指向集群 DNS,而不是只使用节点 DNS。

5. CoreDNS 外部域名解析失败,但 Service 域名正常是什么原因?

这种情况常见于 CoreDNS 到上游 DNS 的转发路径异常,例如 Corefile 中 forward 指向的上游不可达、节点 DNS 配置错误、出口网络受限或防火墙拦截。可以查看 CoreDNS 日志中的 timeout、SERVFAIL 和上游地址,再从节点网络与出口策略继续排查。

官方参考资料

原创声明:CNBPA云原生社区原创技术内容。转载请注明出处:https://www.cloudnative-tech.com/p/8837/
(0)
上一篇 2026年5月7日 下午2:46
下一篇 2026年4月15日 下午3:55

相关推荐