3. DNS 解析流程详解:从 Pod 到 CoreDNS 的完整数据流
在 Kubernetes 环境中,Pod 内的 DNS 查询并非直接发往外部 DNS 服务器,而是经过一条精心设计的内部链路。理解这条链路中的每一个节点,是排查 CoreDNS 解析超时故障的基础。本节将拆解从 Pod 发起查询到 CoreDNS 返回响应的完整数据流,并深入解析递归查询与缓存机制。
3.1 从 Pod 到 CoreDNS 的完整数据流
当一个 Pod 中的应用程序尝试解析一个域名(例如 example.com)时,数据包会经历以下五个关键阶段:
- Pod 内 resolv.conf 配置:Kubernetes 通过
kubelet为每个 Pod 注入/etc/resolv.conf,指定 nameserver 为 ClusterIP 形式的 CoreDNS Service 地址(通常为10.96.0.10),并设置search域(如default.svc.cluster.local)和ndots参数。 - Pod 网络命名空间 → 宿主机:Pod 内的 DNS 查询(UDP/TCP 53 端口)通过 veth pair 到达宿主机,再经过 iptables 或 IPVS 规则进行 DNAT(目标网络地址转换),将目标 IP 从 CoreDNS Service IP 转换为后端 CoreDNS Pod IP。
- 宿主机 → CoreDNS Pod:数据包通过容器网络接口(CNI)插件(如 Calico、Flannel)路由到 CoreDNS Pod 所在的宿主机,最终进入 CoreDNS 容器的网络命名空间。
- CoreDNS 内部处理:CoreDNS 根据配置的插件链(Plugin Chain)处理查询。如果查询域名属于集群域(
cluster.local),则直接查询 Kubernetes API Server 返回 Pod/Service 记录;否则进入递归查询流程。 - 响应返回:CoreDNS 将解析结果沿原路径返回给 Pod。如果上游 DNS 超时或 CoreDNS 本身负载过高,Pod 将收到 SERVFAIL 或超时错误。
关键指标: 证书轮换场景下,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 域 → 构造 FQDNmy-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 不可达,反向解析同样会失败
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 端应用程序出现明显的延迟或超时错误。