1. DNS基础回顾:Kubernetes集群中DNS的工作原理、Service与Pod的DNS记录格式

1.1 集群DNS整体架构

Kubernetes 集群内部 DNS 服务(通常由 CoreDNS 实现)是服务发现的核心组件。它监听 kube-dns Service 的 ClusterIP,为集群内的 Pod 和 Service 提供域名解析。其基本工作流程如下:

  1. Pod 发起查询:Pod 内的进程(如 curl、nslookup)向本地 /etc/resolv.conf 中配置的 DNS 服务器(即 kube-dns Service IP)发送 DNS 查询请求。
  2. CoreDNS 接收请求:CoreDNS Pod 监听 UDP/53 和 TCP/53 端口,接收来自集群内任意 Pod 的 DNS 查询。
  3. 插件链处理:CoreDNS 按照 Corefile 配置的插件链(如 kubernetes、forward、cache)依次处理请求。
  4. 返回解析结果:若查询的域名属于集群内部 Service 或 Pod,则直接返回对应的 ClusterIP 或 Pod IP;若为外部域名,则转发至上游 DNS 服务器。
关键点:Pod 的 /etc/resolv.conf 由 kubelet 自动注入,其 nameserver 指向 kube-dns Service 的 ClusterIP(默认 10.96.0.10),search 域包含 <namespace>.svc.cluster.local 等后缀,这是实现短域名访问的基础。
CoreDNS 集群 DNS 查询流程 Pod (客户端) /etc/resolv.conf kube-dns Service ClusterIP: 10.96.0.10 CoreDNS Pod 监听 UDP/TCP 53 插件链处理 kubernetes / forward / cache 上游 DNS 外部域名解析 DNS 查询 负载均衡 外部转发 返回 A/AAAA 记录 Pod 通过 kube-dns Service 访问 CoreDNS,CoreDNS 根据域名类型决定内部解析或外部转发

1.2 Service 的 DNS 记录格式

Kubernetes 为每个 Service 自动创建 DNS 记录,遵循标准的 FQDN(完全限定域名)格式。根据 Service 类型不同,记录内容有所差异:

Service 类型 DNS 记录格式 解析结果 示例
ClusterIP <service>.<namespace>.svc.cluster.local ClusterIP(虚拟 IP) my-svc.default.svc.cluster.local → 10.96.1.5
NodePort <service>.<namespace>.svc.cluster.local ClusterIP(虚拟 IP) nodeport-svc.default.svc.cluster.local → 10.96.1.10
LoadBalancer <service>.<namespace>.svc.cluster.local ClusterIP(虚拟 IP) lb-svc.default.svc.cluster.local → 10.96.1.20
ExternalName <service>.<namespace>.svc.cluster.local CNAME 记录(外部域名) ext-svc.default.svc.cluster.local → CNAME example.com
Headless (ClusterIP=None) <service>.<namespace>.svc.cluster.local Pod IP 列表(A/AAAA 记录) headless-svc.default.svc.cluster.local → 10.1.0.5, 10.1.0.6
重要说明:对于 ClusterIP、NodePort、LoadBalancer 类型的 Service,DNS 查询返回的是 Service 的 ClusterIP,而非后端 Pod IP。只有 Headless Service 会直接返回所有就绪 Pod 的 IP 地址列表,适用于需要直接访问 Pod 的场景(如 StatefulSet)。

1.3 Pod 的 DNS 记录格式

Pod 的 DNS 记录格式与 Service 不同,它基于 Pod IP 地址生成,主要用于 StatefulSet 的有状态应用。Pod 的 DNS 记录分为两种形式:

  • 普通 Pod(非 StatefulSet):默认情况下,普通 Pod 不会自动创建独立的 DNS 记录。但可以通过 hostname 和 subdomain 字段手动配置,格式为 <hostname>.<subdomain>.<namespace>.svc.cluster.local。
  • StatefulSet Pod:每个 Pod 自动获得稳定的 DNS 记录,格式为 <pod-name>.<service-name>.<namespace>.svc.cluster.local,其中 pod-name 为 <statefulset-name>-<ordinal>。
Pod 类型 DNS 记录格式 解析结果 示例
普通 Pod(手动配置) <hostname>.<subdomain>.<ns>.svc.cluster.local Pod IP web-0.web-svc.default.svc.cluster.local → 10.1.0.5
StatefulSet Pod <pod-name>.<svc-name>.<ns>.svc.cluster.local Pod IP nginx-0.nginx-svc.default.svc.cluster.local → 10.1.0.10
StatefulSet Pod(SRV 记录) _<port>._<proto>.<svc-name>.<ns>.svc.cluster.local Pod 端口与 IP _http._tcp.nginx-svc.default.svc.cluster.local → SRV 0 50 80 nginx-0.nginx-svc...
常见误区:很多运维人员误以为所有 Pod 都会自动获得 DNS 记录。实际上,只有 StatefulSet 的 Pod 或手动配置了 hostname/subdomain 的 Pod 才有独立的 DNS 记录。普通 Deployment 的 Pod 只能通过 Service 域名间接访问。

1.4 DNS 搜索域与短域名解析

Kubernetes 通过 Pod 的 /etc/resolv.conf 中的 search 域实现短域名解析,极大简化了集群内的服务访问。默认的搜索域配置如下:

nameserver 10.96.0.10
search <namespace>.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

当 Pod 内使用短域名(如 my-svc)发起 DNS 查询时,CoreDNS 会依次拼接搜索域进行尝试:

  1. my-svc.<namespace>.svc.cluster.local → 命中,返回 ClusterIP
  2. my-svc.svc.cluster.local → 若第一步未命中,继续尝试
  3. my-svc.cluster.local → 若前两步未命中,继续尝试
  4. my-svc(无后缀)→ 若以上均未命中,作为外部域名转发
性能提示:ndots:5 表示当域名中点的数量小于 5 时,优先尝试拼接搜索域。这会导致短域名查询产生额外的 DNS 请求(最多 4 次尝试),但提高了跨 Namespace 访问的灵活性。对于高并发场景,建议使用完整 FQDN(如 my-svc.default.svc.cluster.local)以减少查询次数。
短域名解析流程(搜索域拼接) 查询 "my-svc" 尝试 my-svc.<ns>.svc.cluster.local 尝试 my-svc.svc.cluster.local 尝试 my-svc.cluster.local 转发至上游 DNS 命中 → 返回 ClusterIP 命中即返回 搜索域按优先级依次尝试,命中后立即返回,不再继续后续查询

1.5 DNS 策略与 Pod 配置

Kubernetes 支持多种 DNS 策略,通过 Pod 的 dnsPolicy 字段控制。不同策略决定了 Pod 如何继承或覆盖集群默认的 DNS 配置:

DNS 策略 行为描述 适用场景
ClusterFirst 默认策略。优先使用集群 DNS(CoreDNS),外部域名转发至上游 DNS 绝大多数业务 Pod
Default 继承节点宿主机的 /etc/resolv.conf,不使用集群 DNS 需要直接使用宿主机 DNS 配置的场景
None 忽略集群和宿主机 DNS,完全由 dnsConfig 自定义 特殊网络需求,如自定义 DNS 服务器
ClusterFirstWithHostNet Pod 使用宿主机网络(hostNetwork: true)时,仍使用集群 DNS hostNetwork 模式下的 Pod(如网络插件 DaemonSet)
排查要点:当 Pod 无法解析 Service 域名时,首先检查 dnsPolicy 是否为 ClusterFirst。若为 Default 或 None,Pod 将无法使用集群 DNS 解析内部域名。同时,检查 /etc/resolv.conf 中的 nameserver 是否指向正确的 kube-dns Service IP。

1.6 常见 DNS 故障模式预览

理解 DNS 工作原理后,常见的故障模式可以归纳为以下几类,后续章节将逐一深入排查:

  • CoreDNS Pod 异常:Pod 处于 CrashLoopBackOff、Pending 或 OOMKilled 状态,导致 DNS 服务不可用。
  • 亲和性调度问题:CoreDNS Pod 被调度到同一节点,或节点资源不足导致性能瓶颈。
  • 网络策略阻断:NetworkPolicy 阻止了 Pod 与 CoreDNS 之间的 UDP/53 通信。
  • 缓存污染:CoreDNS 缓存了过期或错误的 DNS 记录,导致解析结果异常。
  • 上游 DNS 不可达:外部域名解析失败,影响依赖外部服务的应用。
最佳实践:在生产环境中,建议将 CoreDNS 部署为至少 2 个副本,并配置 Pod 反亲和性(PodAntiAffinity)确保副本分布在不同节点。同时,开启 CoreDNS 的 prometheus 插件,通过指标监控提前发现 DNS 性能劣化。