K8s 跨集群通信的“量子纠缠”:当 DNS 黑洞吞没你的服务请求

云计算 云原生
一个 ​​ndots​​ 参数足以引发跨集群雪崩,理解 Kubernetes DNS 解析链(递归查询 → searchDomains 追加 → 超时控制)是关键。

引言

对于这种案例,你们的处理思路是怎么样的呢,是否真正的处理过,如果遇到,你们应该怎么处理。

我想大多数人都没有遇到过。

开始

一、现象:跨集群通信的神秘失效

某金融系统在混合云架构中部署了多套 Kubernetes 集群,用于实现跨地域容灾。某次业务切换演练时,发现跨集群服务发现完全失效,具体表现为:

1. 服务发现中断:

# 在故障 Pod 中测试解析  
kubectl exec -it frontend-pod -- nslookup backend-service.cluster-b.svc.cluster.local  
;; Got SERVFAIL reply from 10.96.0.10, trying next server  
;; connection timed out; no servers could be reached
  • 1.
  • 2.
  • 3.
  • 4.

• 集群 A 的 Pod 无法通过 service-name.cluster-b.svc.cluster.local 访问集群 B 的服务

• nslookup 返回 **SERVFAIL** 错误,但 CoreDNS 日志无任何异常记录

2. 核心指标异常:

• Prometheus 监控显示 coredns_dns_request_count_total{rcode="SERVFAIL"} 激增

• 服务网格流量统计中,跨集群请求失败率高达 92%

二、根因分析:DNS 配置的「死亡组合」

1. ndots:5 的「量子纠缠」

问题本质:

Kubernetes 默认在 Pod 的 /etc/resolv.conf 中设置 options ndots:5。该配置要求:

• 当查询的域名包含 少于 5 个点 时,DNS 客户端会尝试追加所有 searchDomains

• 对于跨集群服务域名 backend-service.cluster-b.svc.cluster.local(4 个点),触发以下查询链:

# 实际查询顺序(伪代码)
for domain in searchDomains:
    query = "backend-service.cluster-b.svc.cluster.local.{domain}"
    send_to_dns_server(query)
  • 1.
  • 2.
  • 3.
  • 4.

致命冲突:私有 DNS 服务器(如 AD DNS)无法处理这种带冗余后缀的查询,直接返回 SERVFAIL。

2. searchDomains 的「黑洞陷阱」

问题本质:/etc/resolv.conf 中残留无效的 searchDomains,例如:

search default.svc.cluster.local svc.cluster.local cluster.local corp.legacy.com # 已废弃的域
  • 1.

灾难链:

1. 客户端先尝试查询 backend-service.cluster-b.svc.cluster.local.default.svc.cluster.local

2. 私有 DNS 无法解析,耗时 5 秒(默认超时)

3. 继续尝试下一个后缀,最终耗尽查询时间

三、解决方案:四步破解 DNS 黑洞

1. 动态调整 ndots 配置

通过 ConfigMap 覆盖默认 DNS 策略:

# coredns-configmap.yaml  
apiVersion: v1  
kind: ConfigMap  
metadata:  
  name: coredns-custom  
  namespace: kube-system  
data:  
  Corefile: |  
    cluster.local:53 {  
      errors  
      health  
      ready  
      kubernetes cluster.local in-addr.arpa ip6.arpa {  
        pods insecure  
        fallthrough in-addr.arpa ip6.arpa  
      }  
      # 关键:调整 ndots 为 3  
      template IN A {  
        match "^([^\.]+)\.([^\.]+)\.svc\.cluster\.local$"  
        answer "{{ .Name }}.{{ .Match.2 }}.svc.cluster.local 5 IN A $SERVICE_IP"  
        fallthrough  
      }  
      forward . /etc/resolv.conf {  
        policy sequential  
        prefer_udp  
      }  
      cache 30  
      reload 15s  
      # 强制 ndots=3  
      loop  
      reload  
      loadbalance  
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.

2. 清理无效 searchDomains

在 Pod 模板中注入 DNS 配置:

# deployment-patch.yaml  
spec:  
  template:  
    spec:  
      dnsConfig:  
        searches:  # 仅保留有效域  
        - cluster-b.svc.cluster.local  
        - svc.cluster.local  
        - cluster.local  
        options:  
        - name: ndots  
          value: "3"
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

3. DNS 查询链路验证

使用 netshoot 镜像进行全链路测试:

# 启动诊断容器  
kubectl run dns-debug --image=nicolaka/netshoot --rm -it --restart=Never -- /bin/sh  

# 分步测试解析  
dig +trace backend-service.cluster-b.svc.cluster.local  
nslookup -debug backend-service.cluster-b.svc.cluster.local  
# 检查实际查询顺序  
cat /etc/resolv.conf
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

4. 防御体系构建

层级

工具/策略

防护能力

配置校验

OpenPolicyAgent (OPA)

拦截无效 searchDomains

监控预警

Prometheus + CoreDNS 指标

实时检测 SERVFAIL 率

混沌测试

Chaos Mesh 注入 DNS 延迟

提前发现链路脆弱点

四、核心命令速查表

# 1. 查看 Pod 的 DNS 配置  
kubectl exec <pod-name> -- cat /etc/resolv.conf  

# 2. 强制刷新 CoreDNS 缓存  
kubectl delete pod -n kube-system -l k8s-app=kube-dns  

# 3. 抓取跨集群 DNS 包  
kubectl debug <pod-name> -it --image=nicolaka/netshoot -- tcpdump -i any -nn port 53  

# 4. 生成 DNS 查询拓扑图  
kubectl get svc -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.clusterIP}{"\n"}{end}' > dns-map.txt
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

五、经验总结

1. DNS 配置的「蝴蝶效应」:一个 ndots 参数足以引发跨集群雪崩,理解 Kubernetes DNS 解析链(递归查询 → searchDomains 追加 → 超时控制)是关键。

2. 防御性编码原则:在 CI/CD 流水线中集成 DNS 策略校验(如 kube-score 检查 dnsConfig)。

3. 观测驱动运维:通过指标 coredns_dns_response_rcode_count 定位异常模式,比日志更早发现问题。

责任编辑:武晓燕 来源: 云原生运维圈
相关推荐

2023-09-08 08:09:12

k8sservice服务

2023-11-07 08:23:05

2022-08-29 10:08:50

跨集群

2016-04-01 09:33:56

阿里云量子计算

2021-11-04 07:49:58

K8SStatefulSetMySQL

2021-08-31 09:55:57

服务开发K8S

2023-03-05 21:50:46

K8s集群容量

2023-09-03 23:58:23

k8s集群容量

2022-12-27 14:18:45

K8S命令

2023-11-06 07:16:22

WasmK8s模块

2023-11-24 08:00:42

量子纠缠屏幕坐标系

2023-08-03 08:36:30

Service服务架构

2021-04-22 09:46:35

K8SCluster Aut集群

2024-08-30 09:21:28

2022-04-22 13:32:01

K8s容器引擎架构

2024-05-27 00:00:10

KubernetesK8s云原生

2022-12-28 10:52:34

Etcd备份

2025-03-19 08:01:10

Kubernetes集群源码

2023-09-07 08:58:36

K8s多集群

2024-01-26 14:35:03

鉴权K8sNode
点赞
收藏

51CTO技术栈公众号