3. DNS 解析流程详解:从 Pod 到 CoreDNS 的完整数据流

在 Kubernetes 环境中,Pod 内的 DNS 查询并非直接发往外部 DNS 服务器,而是经过一条精心设计的内部链路。理解这条链路中的每一个节点,是排查 CoreDNS 解析超时故障的基础。本节将拆解从 Pod 发起查询到 CoreDNS 返回响应的完整数据流,并深入解析递归查询与缓存机制。

3.1 从 Pod 到 CoreDNS 的完整数据流

当一个 Pod 中的应用程序尝试解析一个域名(例如 example.com)时,数据包会经历以下五个关键阶段:

  1. Pod 内 resolv.conf 配置:Kubernetes 通过 kubelet 为每个 Pod 注入 /etc/resolv.conf,指定 nameserver 为 ClusterIP 形式的 CoreDNS Service 地址(通常为 10.96.0.10),并设置 search 域(如 default.svc.cluster.local)和 ndots 参数。
  2. Pod 网络命名空间 → 宿主机:Pod 内的 DNS 查询(UDP/TCP 53 端口)通过 veth pair 到达宿主机,再经过 iptables 或 IPVS 规则进行 DNAT(目标网络地址转换),将目标 IP 从 CoreDNS Service IP 转换为后端 CoreDNS Pod IP。
  3. 宿主机 → CoreDNS Pod:数据包通过容器网络接口(CNI)插件(如 Calico、Flannel)路由到 CoreDNS Pod 所在的宿主机,最终进入 CoreDNS 容器的网络命名空间。
  4. CoreDNS 内部处理:CoreDNS 根据配置的插件链(Plugin Chain)处理查询。如果查询域名属于集群域(cluster.local),则直接查询 Kubernetes API Server 返回 Pod/Service 记录;否则进入递归查询流程。
  5. 响应返回:CoreDNS 将解析结果沿原路径返回给 Pod。如果上游 DNS 超时或 CoreDNS 本身负载过高,Pod 将收到 SERVFAIL 或超时错误。
关键指标: 证书轮换场景下,CoreDNS 与 API Server 之间的 TLS 连接可能因证书未更新而中断,导致集群内域名解析失败,但外部域名(需递归查询)可能仍正常。
Pod → CoreDNS 完整数据流 Pod 应用 veth / 宿主机 iptables DNAT CoreDNS Pod ① Pod 内 resolv.conf → ② veth 到宿主机 → ③ iptables DNAT 到 CoreDNS Pod IP ④ CoreDNS 处理(集群内/递归)→ ⑤ 响应原路返回 1. 查询发起 2. 网络转发 3. DNAT 转换 4. 解析 ⚠ 证书轮换故障点 CoreDNS 与 API Server 的 TLS 证书未同步更新 → 步骤 ④ 中集群内域名解析失败 外部域名(需递归)可能正常,造成“部分解析超时”的假象

3.2 递归查询与缓存机制

CoreDNS 在处理 DNS 查询时,根据查询的域名是否属于集群域,采用两种不同的处理路径:

查询类型 目标域名示例 处理路径 缓存策略
集群内查询 my-svc.default.svc.cluster.local CoreDNS → Kubernetes API Server → 返回 Pod/Service IP 默认 30 秒负缓存;记录变更时通过 watch 机制失效
外部递归查询 example.com CoreDNS → 上游 DNS(如 8.8.8.8)→ 根/顶级/权威服务器 默认 30 秒正缓存;上游返回 SOA TTL 决定缓存时长
反向解析(PTR) 10.96.0.1.in-addr.arpa CoreDNS → API Server(集群 IP)或上游 DNS(外部 IP) 与正向查询缓存策略一致
排查要点: 证书轮换故障通常只影响集群内查询路径。如果 nslookup kubernetes.default.svc.cluster.local 超时,但 nslookup baidu.com 正常,则故障点锁定在 CoreDNS 与 API Server 之间的 TLS 连接。

3.3 正向解析与反向解析

正向解析(A/AAAA 记录)将域名映射到 IP 地址,是 Pod 间通信和对外访问的基础。在 Kubernetes 中,正向解析的典型流程如下:

  • Pod 查询 my-svc → 自动追加 search 域 → 构造 FQDN my-svc.default.svc.cluster.local
  • CoreDNS 的 kubernetes 插件匹配 cluster.local 域 → 查询 API Server → 返回 Service ClusterIP 或 Endpoint IP 列表
  • 如果查询外部域名,forward 插件将请求转发到上游 DNS 服务器

反向解析(PTR 记录)将 IP 地址映射回域名,常用于日志审计和网络诊断。Kubernetes 中反向解析的注意事项:

  • Pod IP 的反向解析:CoreDNS 默认不自动生成 Pod IP 的 PTR 记录,需要手动配置 hosts 插件或依赖外部 DNS
  • Service ClusterIP 的反向解析:CoreDNS 的 kubernetes 插件支持为 Service IP 生成 PTR 记录,格式为 10.96.0.1.in-addr.arpa
  • 证书轮换场景下,如果 API Server 不可达,反向解析同样会失败
正向解析 vs 反向解析流程 正向解析(A/AAAA) 域名 → IP API Server 查询 示例:my-svc → 10.96.0.50 缓存:默认 30s,watch 实时失效 反向解析(PTR) IP → 域名 in-addr.arpa 查询 示例:10.96.0.1 → kubernetes.default.svc 注意:Pod IP 默认无 PTR 记录 证书轮换对两类解析的影响 • 正向解析:集群内域名(如 Service 名)解析失败,外部域名(如 baidu.com)正常 • 反向解析:Service ClusterIP 的 PTR 查询失败,Pod IP 反向解析原本就不可用 • 排查命令:dig @10.96.0.10 kubernetes.default.svc.cluster.local vs dig @10.96.0.10 baidu.com

3.4 缓存机制与超时场景

CoreDNS 的缓存机制直接影响故障恢复时间。理解缓存行为,有助于判断证书轮换后解析何时恢复正常:

缓存类型 默认时长 证书轮换影响 手动清除方法
正缓存(成功记录) 上游 TTL(通常 30~300s) 旧证书失效后,缓存中的记录仍可用,直到 TTL 过期 kubectl exec -n kube-system deploy/coredns -- curl -X POST http://localhost:8080/cache/flush
负缓存(NXDOMAIN/SERVFAIL) 30s(可配置) 证书轮换期间产生的 SERVFAIL 会被缓存,导致恢复后仍短暂不可用 同上,或等待缓存自然过期
API Server 连接缓存 连接池复用 证书轮换后,旧连接被重置,新连接使用新证书建立 重启 CoreDNS Pod 强制重建连接
重要: 证书轮换后,即使 CoreDNS 重新加载了新证书,之前缓存的 SERVFAIL 记录仍会导致后续查询失败,直到缓存过期。这是“证书已更新但解析仍超时”的常见原因。建议在证书轮换后主动刷新 CoreDNS 缓存。

3.5 数据流中的关键超时点

从 Pod 到 CoreDNS 的完整数据流中,存在多个可能引发超时的环节。以下表格列出了证书轮换场景下最可能出问题的节点:

阶段 超时原因 典型超时时间 排查方法
Pod → CoreDNS Service iptables DNAT 规则错误或 Service 后端不可用 2s(内核 conntrack 超时) iptables -t nat -L -n | grep 10.96.0.10
CoreDNS → API Server TLS 证书验证失败(证书轮换未同步) 30s(TCP 连接超时) CoreDNS 日志中搜索 x509: certificate has expired
CoreDNS → 上游 DNS 上游 DNS 不可达或防火墙拦截 5s(forward 插件默认超时) dig @8.8.8.8 baidu.com 从 CoreDNS Pod 测试
响应返回 Pod 网络路径拥塞或 Pod 侧 conntrack 表满 取决于网络配置 tcpdump -i any port 53 抓包分析

在证书轮换故障场景中,CoreDNS → API Server 阶段的 TLS 握手失败是最常见的根因。该阶段的超时时间长达 30 秒,会导致 Pod 端应用程序出现明显的延迟或超时错误。