遇到 Service 域名解析失败,先不要急着改 Service 或 Deployment。这类问题通常与 DNS 配置有关,但具体错在哪一层,需要按顺序确认。下面是我在处理类似故障时常用的排查路径。
先确认现象
当 Kubernetes Pod 无法解析集群内部 Service 域名时,最直接的判断依据是进入 Pod 查看 /etc/resolv.conf。如果该文件中的 nameserver 指向的 IP 不是集群 DNS 服务的 ClusterIP(通常是 kube-system 命名空间下 kube-dns 服务的 ClusterIP),或者 search 域中没有包含正确的集群域名后缀(如 default.svc.cluster.local),基本可以确认是 DNS 配置错误。此时应检查 kubelet 的 --cluster-dns 参数是否与 kube-dns 服务地址一致,以及 Pod 是否受到 dnsPolicy 字段的影响。例如,当 Pod 的 dnsPolicy 设置为 Default 时,它会继承…
如果宿主机上的 /etc/resolv.conf 指向的是外部 DNS,那么 Pod 里的解析请求就会绕过 kube-dns,自然访问不了集群内部域名。所以看到 dnsPolicy: Default 时要格外留意。也可以先用 kubectl get svc -n kube-system kube-dns 查看真实 ClusterIP 是多少,然后和 Pod 内的 nameserver 对比。
容易误判的地方
一个容易被忽略的坑是 Pod 使用了 hostNetwork 模式,但未设置 dnsPolicy 为 ClusterFirstWithHostNet。在 hostNetwork 模式下,Pod 默认使用宿主机 /etc/resolv.conf,而宿主机通常只配置外部 DNS,并不会包含集群内的 search 域和 kube-dns 地址,因此 Pod 无法解析集群内部 Service 域名。解决方法是显式设置 dnsPolicy: ClusterFirstWithHostNet,这样系统会使用集群 DNS 配置,同时保留宿主机网络能力。另一个常见坑是 CoreDNS 的 ConfigMap 被误修改,比如删除了 kubernetes 插件或把 forward 目标指向了不可达的 DNS 服务器,这会导致即使 P…
即使 Pod 的 dnsPolicy 没有问题,解析请求也会被错误转发或丢弃。所以检查 CoreDNS 配置时,要留意最近是否有人修改过。遇到 hostNetwork 的 Pod,很多人会以为是 CoreDNS 出问题,但其实是网络模式改变了 DNS 来源。排查时不能只看 Pod 端,还要看 CoreDNS 本身的配置。
建议的处理顺序
对于因 DNS 配置错误导致 Service 域名无法解析的情况,建议先核对集群 DNS 服务状态。执行 kubectl get svc -n kube-system 确认 kube-dns 服务是否存在且 ClusterIP 已分配,再执行 kubectl get pods -n kube-system -l k8s-app=kube-dns 检查 CoreDNS Pod 是否处于 Running 状态。若服务或 Pod 异常,可考虑重启 CoreDNS 或检查其资源限制。同时,使用 kubectl describe configmap coredns -n kube-system 查看 CoreDNS 的 Corefile 配置,确认其中是否包含 kubernetes 插件,以及插件中的 clusterDo…
clusterDo 后面跟的通常是 clusterDomain,这个值需要和集群初始化时保持一致。如果这里写错了,解析也会失败。这个顺序的核心是先用 kubectl 确认服务端状态,再检查客户端配置,最后看解析插件。如果 kube-dns 服务不存在,CoreDNS Pod 也不会被正常负载均衡,但有时服务存在而 Endpoints 为空,需要进一步看 kube-proxy 是否正常。CoreDNS Pod 处于 Running 状态并不代表它能把请求转发给 Kubernetes API,所以还需要看一下它的日志。
验证方法
在 Pod 内部进行解析测试时,建议按层级逐步排查。先执行 nslookup kubernetes.default.svc.cluster.local 检测完整域名,再尝试 nslookup kubernetes.default,最后直接 nslookup kubernetes。如果完整域名解析成功而短名称失败,问题大概率出在 search 域配置上;如果所有名称都解析失败,则需要检查 DNS 服务连通性。此时可以在同一命名空间下临时运行一个纯 busybox 或 alpine 容器,使用相同 dnsPolicy 进行对比测试,以区分是 Pod 配置问题还是集群 DNS 故障。另外,也可以通过 kubectl run --rm -it --image busybox test -- /bin/sh 进入临时容器…
进入临时容器后,继续执行 nslookup kubernetes.default,就能看到它使用的是哪个 DNS 服务器。同时在另一个终端观察 CoreDNS 日志,看是否有来自目标 Pod 的查询请求。如果没有收到请求,说明流量没到 CoreDNS,问题可能出在 kube-proxy 或网络策略上;如果收到请求但没有应答,则要检查 CoreDNS 的上游 DNS 或 kubernetes 插件状态。
回滚和风险
修改 CoreDNS 配置时需特别注意风险边界。CoreDNS 是集群内所有 Pod 解析 Service 域名的核心依赖,若其 ConfigMap 配置错误,例如在 kubernetes 插件中误改了 clusterDomain 或 fallthrough 规则,可能导致集群内全部 DNS 解析失败。建议修改前先备份当前配置,并在测试环境验证。同时,重新创建 CoreDNS Pod 会短暂中断 DNS 服务,对于关键业务应选择业务低峰期操作。此外,如果集群使用了网络策略(NetworkPolicy),某些策略可能会阻止 Pod 访问 kube-dns 服务的 53 端口,这种情况下即使配置正确也无法解析,需要检查网络策略是否放行了这类流量。
如果确认是 CoreDNS 配置被改坏,可以先用 kubectl get configmap coredns -n kube-system -o yaml 备份当前配置,然后 kubectl edit 修复。修复后需要滚动重启 CoreDNS Pod,例如 kubectl rollout restart -n kube-system deployment/coredns。重启会造成短暂 DNS 中断,建议在窗口时间操作。如果集群使用 NetworkPolicy,还要检查是否明确放行了 Pod 到 kube-dns 的 UDP/TCP 53 端口,否则配置正确也可能解析不了。