1. DNS基础回顾:Kubernetes集群中DNS的工作原理、Service与Pod的DNS记录格式
1.1 集群DNS整体架构
Kubernetes 集群内部 DNS 服务(通常由 CoreDNS 实现)是服务发现的核心组件。它监听 kube-dns Service 的 ClusterIP,为集群内的 Pod 和 Service 提供域名解析。其基本工作流程如下:
- Pod 发起查询:Pod 内的进程(如 curl、nslookup)向本地
/etc/resolv.conf中配置的 DNS 服务器(即kube-dnsService IP)发送 DNS 查询请求。 - CoreDNS 接收请求:CoreDNS Pod 监听 UDP/53 和 TCP/53 端口,接收来自集群内任意 Pod 的 DNS 查询。
- 插件链处理:CoreDNS 按照 Corefile 配置的插件链(如
kubernetes、forward、cache)依次处理请求。 - 返回解析结果:若查询的域名属于集群内部 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 等后缀,这是实现短域名访问的基础。
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 会依次拼接搜索域进行尝试:
my-svc.<namespace>.svc.cluster.local→ 命中,返回 ClusterIPmy-svc.svc.cluster.local→ 若第一步未命中,继续尝试my-svc.cluster.local→ 若前两步未命中,继续尝试my-svc(无后缀)→ 若以上均未命中,作为外部域名转发
性能提示:
ndots:5 表示当域名中点的数量小于 5 时,优先尝试拼接搜索域。这会导致短域名查询产生额外的 DNS 请求(最多 4 次尝试),但提高了跨 Namespace 访问的灵活性。对于高并发场景,建议使用完整 FQDN(如 my-svc.default.svc.cluster.local)以减少查询次数。
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 性能劣化。