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

devtools/2025/3/26 4:10:42/

 

引言

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

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

开始

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

某金融系统在混合云架构中部署了多套 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
    • 集群 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)

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

2. searchDomains 的「黑洞陷阱」

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

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

灾难链

  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  }  
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"  
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  
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. DNS 配置的「蝴蝶效应」:一个 ndots 参数足以引发跨集群雪崩,理解 Kubernetes DNS 解析链(递归查询 → searchDomains 追加 → 超时控制)是关键。
  2. 防御性编码原则:在 CI/CD 流水线中集成 DNS 策略校验(如 kube-score 检查 dnsConfig)。
  3. 观测驱动运维:通过指标 coredns_dns_response_rcode_count 定位异常模式,比日志更早发现问题。

“在分布式系统中,DNS 从来不是简单的域名解析,而是连接所有组件的神经系统。”
—— 某跨国企业 SRE 团队故障复盘报告

结语

以上就是我们今天的内容,希望可以帮助到大家,在面试中游刃有余,主动出击。


 

往期回顾

  • • 面试官:你的 preStop 钩子搞垮了集群!——我:这是计划的一部分(笑)
  • • 和面试官聊聊如何零重启修复 K8s 环境中的 Log4j 漏洞?
  • • 救命SOS!内网K8s证书过期,我差点上了公司“耻辱墙”……
  • • 救命!我的 K8s GPU 节点被 AI 训练“吃”崩了!三招让运维和开发握手言和
  • • 在 K8s 跨集群网络出现问题时,你会首先排查哪些常见的网络层问题?如果这些都排除了,你会继续如何深入排查?

http://www.ppmy.cn/devtools/171247.html

相关文章

【Linux文件IO】通过文件IO把bmp图片显示到Linux开发板的实现

通过文件IO把bmp图片显示到Linux开发板的实现 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <errno.h>/* 显示24位的BMP图片特点1:每…

java项目之基于ssm的游戏攻略网站(源码+文档)

项目简介 游戏攻略网站实现了以下功能&#xff1a; 管理员主要负责填充图书和其类别信息&#xff0c;并对已填充的数据进行维护&#xff0c;包括修改与删除&#xff0c;管理员也需要审核老师注册信息&#xff0c;发布公告信息&#xff0c;管理自助租房信息等。 &#x1f495;…

判断是不是完全二叉树(C++)

目录 1 问题描述 1.1 示例1 1.2 示例2 1.3 示例3 2 解题思路 3 代码实现 4 代码解析 4.1 定义队列&#xff0c;初始化根节点 4.2 层序遍历&#xff0c;处理每个节点 4.3 处理空节点 4.4 处理非空节点 5 总结 1 问题描述 给定一个二叉树&#xff0c;确定他是否是一…

学习记录-Ajax-自封装axios函数

目录 自封装axios函数封装axios函数实现步骤1. 准备阶段2. 实现无参get请求3.实现有参get请求4. 实现post请求 完整实例代码 自封装axios函数 封装axios函数实现步骤 1. 准备阶段 理解axios函数的底层原理&#xff0c;包括Promise,XMLHttpRequest等概念 XMLHttpRequest工作…

贪心算法(11)(java)加油站

题目&#xff1a;在一条环路上有n个加油站&#xff0c;其中第i个加油站有汽油 gas[i]升.。 你有一辆油箱容量无限的的汽车&#xff0c;从第i个加油站开往第i1个加油站需要消耗汽油 cost[i]升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 给定…

Spring Security核心源码和功能实现

Spring Security 是一个强大的安全框架,用于保护基于 Spring 的应用程序。它提供了认证、授权、防止常见安全攻击等功能。下面是对 Spring Security 的核心功能和实现的详细分析,并使用 Mermaid 绘制相关流程图。 1. 核心功能 1.1 认证(Authentication) 用户认证:验证用…

【41】单片机编程核心技巧:const 与 code 的存储优化

【41】单片机编程核心技巧&#xff1a;const 与 code 的存储优化 七律 存储优化 常量存储ROM中&#xff0c;const与code异同。 变量常量分两域&#xff0c;RAM省空间有功。 查表阀值一键改&#xff0c;代码优化显神通。 单片机中精设计&#xff0c;资源管理更从容。 摘要 本…

A l密码学(Deepseek)

我&#xff1a;qwertyuiopasdfghjklzxcvbnm deepseek:深度思考中&#xff0e; Okay, lets see. The user input is "qwertyuiopasdfghjklzxcvbnm". At first glance, it looks like a jumbled sequence of letters with some spaces or maybe other characters in …