基于GenAI和RAG的Kubernetes智能排障平台设计与实践

发布时间:2026/10/3 9:06:45
基于GenAI和RAG的Kubernetes智能排障平台设计与实践 凌晨两点半手机告警把我们组的值班群炸醒。监控面板上整整一屏的红色Prometheus 的告警规则里堆着十来个 firing最显眼的一条是 kube-apiserver 探针失败后面的日志只有一句孤零零的报错the api server is not healthy after 4m0.00747357s。我第一反应是打开 Grafana 看 apiserver 的延迟和错误码然后又跳到 Kibana 翻 kube-system 的日志再切到终端用 kubectl get nodes 挨个看状态最后还得翻前天谁合进了什么配置变更。等我把“大概是被某个控制器打爆了”这个结论拼出来的时候已经过去快一个小时。这种事在 K8s 生产环境里太常见了手动排障的每一分钟都在烧钱也在烧人。后来我们团队决定认真做一件事把生成式 AI 引到 K8s 运维链路里从“人看告警、人查日志、人猜结论”变成“机器先做一轮诊断、人通过对话确认和推进”。这套平台跑起来之后同一类 API server 不健康的故障我们可以在五分钟内拿到候选根因和处置建议。这篇东西不是产品宣传而是我们踩坑、拆解、取舍后的完整记录给同样被 K8s 排障折磨的运维、SRE、平台工程师一个可参考的落地路径。1. 传统 K8s 排障为什么慢从“告警隧道”到“日志大海捞针”先说清楚我们当初要解决的真实痛点。K8s 的生产故障从来不是“单个组件坏了”这么简单它更像连锁反应某个节点负载异常会触发 Pod 驱逐Pod 驱逐又导致 Redis 集群失去多数派Redis 不可用进一步拖垮业务接口监控告警像雪崩一样涌过来。手动排障的最大问题不是不懂命令而是信息获取路径太长我们得在十几个系统之间来回跳才能拼出完整现场。1.1 我经历过的最典型的 K8s 生产故障那次 Redis 集群故障就很典型。业务监控先报了“缓存命中率骤降”紧接着是“订单服务超时”然后才是 K8s 层面的“Pod 频繁重启”。三个告警来自三个不同系统业务监控在 SkyWalkingK8s 事件在 Control Plane 的 audit log 里节点负载在 Prometheus。我当时的排查顺序是看缓存监控确认 Redis 确实有节点失联用kubectl get pods -n redis -o wide看哪些副本在重启发现 3 节点 Redis 集群只剩 2 个 Ready查看 Redis Pod 的 Previous Container 日志看到# Server started和# Cluster state changed这种无关痛痒的标准输出真正有用的 OOM 或磁盘满信息反而被日志淹没了再看节点监控发现其中一台节点的 /var/lib/docker 分区使用率 98%才定位到根因。算一下时间Redis 的定位花了两小时但真正“动手修”只用了三分钟——清掉孤儿镜像、腾出空间、Pod 恢复。大多数 K8s 故障都是这种“诊断十分钟、修复三秒钟”的形态所以提升诊断效率才是值钱的事。1.2 手动排障步骤拆解拿到告警后的前 30 分钟把手动排障的流程拆开看前 30 分钟基本固定是这样的套路确认告警真实性先刷新监控看看是一次性抖动还是持续故障这一步经常被忽略因为很多告警是 Flapping抖动状态等你切过去它自己恢复了。圈定故障半径用kubectl get events --all-namespaces扫一遍全局事件看有没有明显的 FailedScheduling、BackOff、Unhealthy 之类的异常事件这一步非常粗但能快速判断是个别节点还是全局性故障。看核心链路状态apiserver 是否健康、etcd 是否健康、kubelet 是否还在上报节点心跳。这属于“怀疑基础设施”因为如果 Control Plane 有问题下面排查全是白费力气。翻关键服务日志根据服务名去 Kibana 或 Loki 里过滤error级别日志有时候还要查 Previous 日志因为重启后的容器日志会丢失现场。看资源水位CPU、内存、磁盘、网络尤其注意磁盘 IO 和 inode 使用率这两个经常是隐形杀手。关联变更记录最后还得看最近有没有发布新版本、调整过配置、扩缩过容很多问题其实是某个人改坏了什么东西。这些问题链路每一步都要去不同的平台操作而且每一步依赖前一步的“人的判断”。新手根本不知道先后顺序老师傅则是脑子里有经验但说不清是怎么得出的——这种隐性知识恰恰是后面做 GenAI 平台时最难复制的东西。1.3 手动排障的瓶颈信息分散与认知断层真正让我下定决心做平台化改造的是看到了两个无法靠“加人”解决的瓶颈。第一个瓶颈是信息分散导致的上下文缺失。告警是一条链但工具是孤岛。K8s 事件、Prometheus 指标、应用日志、链路追踪、CMDB 里的 Pod 归属关系这些信息在人工排查时是割裂的。我们曾经遇到过kubectl describe pod里明明显示Liveness probe failed但是应用日志里完全没报错因为真正原因是节点上的 conntrack 表满了长连接建立失败而 conntrack 的问题在/var/log/messages里。这种跨层级的关联单靠人眼去翻效率极低。第二个瓶颈是认知断层导致的经验失传。团队里最会排障的老 SRE 一旦休假大家就只能退回“重启大法”。不是大家不努力而是故障模式太多了镜像拉取失败可能是网络、可能是凭证过期、可能是 Docker 镜像仓库限流Pod Pending 可能是资源不足、可能是污点、可能是调度器 bug。每一种模式的排查路径都不一样没有系统性的沉淀经验就只能留在个人脑子里。GenAI 平台的一个潜在价值就是把这些排障路径结构化、可复用让整个团队的诊断能力拉平到接近老师傅的水平。2. 平台定位与整体架构不是“聊天机器人”而是“诊断工作台”刚开始我们差点把产品做歪——很多人一听“对话诊断”第一反应是“做一个像 ChatGPT 一样的东西大家去问它”。但实际跑下来你会发现纯问答形态根本无法接进真实的运维流程。我们最后的定位是这是一个带有诊断能力的“工作台”对话只是交互入口背后是完整的数据管道、工具链和知识库。2.1 我们想解决的问题边界必须承认GenAI 不是万能的尤其在 K8s 这种强逻辑、强状态、强上下文的环境里我们不能让模型凭空产生答案。所以一开始就给平台划了边界能解决基于已有监控、日志、事件、配置数据快速给出候选根因解释现象之间的关联建议可执行但需要人工确认的排查命令沉淀排障经验。不解决自动擅自修改集群配置、自动扩容缩容、自动重启服务——这些动作需要人工审批而且在当前阶段平台的定位是“提高人的判断速度”不是替代人做决策。这个边界非常重要。它决定了我们在数据接入上必须做得足够扎实而不是把希望全押在模型推理上。2.2 总体架构数据接入层、索引层、知识层、Agent 编排层、交互层我们最终落地的架构分成了五层每层职责单一方便独立扩容和维护层级职责核心组件数据接入层从 K8s API Server、Prometheus、日志平台、操作审计等来源采集原始数据kube-state-metrics、Prometheus Remote Write、Filebeat、Audit Log Webhook索引与关联层对数据做清洗、归一化、标签关联构建时间线上的“故障现场”OpenSearch、Prometheus TSDB、关系图谱知识层存放文档、历史故障记录、runbook、变更后的经验总结供模型检索向量数据库 文档切分 知识索引Agent 编排层接收对话意图调用工具获取实时数据把上下文喂给大模型推理出结论自研 Orchestrator Function Calling LLM Gateway交互层对话界面、诊断报告、确认按钮、执行记录Web 前端、钉钉/飞书机器人其中最关键的设计决策是把“实时数据获取”和“模型推理”解耦。模型不能直接从集群里抓数据它只能通过 Agent 编排层调用我们封装好的工具比如kubectl_get_pods、promql_query、get_events、get_node_info。这样模型的输出可追踪、可审计避免模型产生不存在的 Pod 或指标——它必须基于真实数据说话。2.3 为什么选择 RAG 而非直接用大模型裸答这个被问了很多次我直接说结论生产级诊断不能接受模型“凭印象”回答。如果直接用大模型裸答它会把一些常见的 K8s 错误模式背出来比如“API server 不健康可能是 etcd 慢”但这个回答没有结合你集群当前的 etcd 延迟、没有结合最近的配置变更价值非常有限。RAG检索增强生成解决的是“把知识变成上下文”的问题。我们的知识库里存了三大类东西官方文档和原理知识K8s 调度原理、etcd 工作机制、CSI 插件常见问题等这部分帮模型建立基础认知团队历史故障记录每次故障复盘后我们会整理成结构化文档包括现象、排查链路、根因、修复动作这些是模型“借鉴经验”的材料Runbook 和操作手册类似“如何安全驱逐节点”“如何扩 etcd 磁盘”这种操作步骤模型检索到之后可以直接生成分步指南。RAG 的检索质量决定了诊断质量。我们的做法是把每个历史故障文档切分成若干 chunk每一块带上时间戳、集群版本、故障域标签查询时先用当前故障的粗粒度特征告警类型、受影响资源、命名空间做召回再交给模型综合推理。这套组合下来模型的回答不再是教科书式背书而是“结合当前现场和历史经验的判断”。3. 核心数据资产管理打通监控、日志、事件与资源拓扑数据层是整个平台的底层底座。这里有个反直觉的经验我们花在模型上的精力远不如花在数据清洗上的精力。没有干净、关联、实时的数据再强的模型也是“巧妇难为无米之炊”。3.1 四类数据源的正确接入方式K8s 排障需要的数据基本是四类监控指标、日志、事件、资源状态。每一类接入时都有坑我逐个说。监控指标最标准的方式是用 Prometheus kube-state-metrics node_exporter重要的是设置好采集周期和保留策略。诊断平台要能查“过去 5 分钟的 apiserver 请求延迟 P99”这就要求指标在 TSDB 里至少保留 15 天以上我们最终把 Prometheus 的存储扩展到了 30 天。另外必须把 PromQL 查询能力封装成工具接口大模型才能实时取数。类似sum(rate(apiserver_request_total{code~5..}[5m]))这种查询有时候模型生成的表达式会漏掉标签或写错聚合方式所以我们做了一个 PromQL 模板库让模型优先调用模板而不是自由生成。日志日志是排障信息量最大的来源但也是最难治理的。K8s 容器日志默认是不落盘的如果用 JSON 格式输出字段名可能千奇百怪。我们的做法是统一接入 Loki 或 OpenSearch按 namespace/pod/container 建立索引同时把标准输出日志和容器崩溃前的 Previous 日志分开存储。这样排查异常重启时可以直接让模型调用get_previous_logs工具拿到上一版容器的错误栈而不必在界面里手动切换。事件K8s 事件是宝藏但很容易被忽略。重点要关注Warning级别的事件比如BackOff、FailedScheduling、Evicted、Unhealthy。我们通过kubectl get events --all-namespaces采集后写入索引层再转成结构化的 JSON字段包括事件类型、涉及对象、reason、message、时间戳。部分事件还会带上“关联对象的状态变化”这个信息对模型判断根因非常有用。资源状态除了指标和日志还需要实时的资源清单。我们每天定时把节点、命名空间、Deployment、StatefulSet、Pod 的 spec 和 status 同步到平台侧的数据湖。诊断时如果模型想知道“某 Pod 的 resource requests 是多少”可以直接查这份快照而不必每次实时调用 API Server既快又省。3.2 kube-state-metrics 与资源拓扑的构建光有数据源还不够关键是建立关联关系。我们做了个轻量级资源拓扑图类似 CMDB 的作用但更偏动态关系。例如一个 Redis 集群的三个 Pod分别跑在 node-01、node-02、node-03 上每个节点又关联着若干系统组件node-02 上还有 kube-proxy、日志采集器、CSI 插件等。当一个节点异常受影响的不只是 Redis而是所有落在该节点的负载。平台拓扑层要能回答这类问题“哪些 Pod 共享同一个节点” “这个节点的宿主机有什么硬件或内核状态”我们基于 kube-state-metrics 暴露的标签和 OwnerReference定期重建资源关系图谱存成图数据模型。诊断时 Agent 拿到一个对象名可以快速向上查“它属于哪个 StatefulSet”“它调度到哪个节点”“它对应的 PVC 底层存储卷状态”不用模型去猜。3.3 把 Bash/Kubectl 变成“可执行函数”这一步是平台最具工程价值的部分。K8s 排障中很多动作是高频的我们把它封装成一个个可被模型调用的函数例如get_pod_info(namespace, pod)返回 Pod 状态、容器状态、重启次数、节点、IP、QoS 等级get_node_conditions(node)返回节点 Ready、MemoryPressure、DiskPressure、PIDPressure 等状态get_events(namespace, resource_type)返回最近 1 小时的相关事件promql_query(expr, duration)执行 PromQL 并返回时序数据get_deployment_rollout_history(deployment)返回最近几次发布的变更记录get_recent_logs(namespace, pod, container, lines)返回最近 N 行日志支持过滤关键字。封装函数的时候有两条铁律。第一条是所有命令必须基于只读原则写操作单独拆出来走人工审批通道。第二条是输出必须限长比如日志只取最后 200 行PromQL 结果返回聚合后的 JSON避免上下文过长导致模型“遗忘”。做完这层Agent 编排层就能像人类一样“先查事件、再看日志、然后看指标、最后综合判断”整个推理链条每一步都有实据。4. 对话诊断的关键链路外部化推理、工具调用与人工确认平台能不能真正省时间,就看推理链路设计得对不对。我们的经验是不要让模型在一个巨大的 prompt 里完成所有推理而是让它分步走每一步都能被人工查看和介入。这样既利用了 GenAI 的综合判断力又保留了人对关键决策的控制权。4.1 一次真实场景复盘API server 不健康告警用开头提到的那条告警来完整走一遍诊断链路。用户值班运维在对话界面粘贴了报错kube-apiserver is not healthy after 4m0.00747357s并附上“集群心跳丢失部分用户访问异常”。平台的处理流程是这样的意图识别Orchestrator 识别出这是“API Server 健康诊断”请求进入对应诊断模板数据采集自动并行调用多个函数——查 apiserver Pod 状态、查 etcd 集群健康、查最近 1 小时 apiserver 错误码统计、查控制面节点的 load 和磁盘上下文组装把工具返回的实时数据加上从知识库检索到的“API server 不健康常见原因”etcd 慢、证书过期、CPU 饥饿、并发过高、网络分区等一起拼成“诊断现场”模型推理大模型基于这些信息生成带概率原因的结论每条结论后面都附上“支持证据”和“待验证项”人工确认推送诊断报告到值班群同时列出建议执行的下一步动作比如“检查 etcd leader 切换次数”“重启 kube-apiserver 实例需审批”。那次实际走下来模型给出的首要候选是“etcd fsync 延迟升高导致 API Server 健康检查超时”证据链是etcd 的backend commit延迟从 5ms 飙到 300ms同时 etcd 所在节点磁盘 IO 使用率 95%。第二条候选是“kube-apiserver 所在节点 CPU 被组调度任务占满”因为节点 load 5 分钟均值达到了 18。这两条建议我们手动kubectl top nodes和对 etcd 做etcdctl endpoint health验证后确认了前者。整个流程从提交告警到拿到诊断报告用了不到 4 分钟比人工翻日志快了十倍不止。4.2 大模型如何利用知识库实时数据生成候选根因这一节是我觉得最值得分享的核心设计。很多人以为“让模型生成一个原因”就够了但实际上生产环境故障往往是多种原因交织的。我们让模型输出的是一个候选根因列表每个根因都带三个字段原因描述例如“etcd 磁盘 IO 延迟升高导致心跳超时”证据模型在实时数据中看到的支持点比如“etcd fsync 延迟 300ms”“磁盘 IO util 95%”验证方法告诉值班人员接下来应该执行什么命令或看什么指标来确认。这样做的价值在于模型不一定每一步都对但它的候选和建议能极大压缩排查范围。即使第一条候选不是根因值班人员顺着“验证方法”去查第二条也比从头看日志高效。对于生成候选根因的 prompt我们也做了大量调优。一开始我们喂的信息太少模型只会说“可能网络有问题”“建议重启”后来逐步加入了知识库检索结果和工具返回的原始数据模型回答才具备了针对性。另外我们给模型做了“限轮次”设计一次对话最多执行 5 次工具调用防止模型陷入无意义的循环查询。如果 5 次之内仍没收敛就要求值班人员介入而不是让模型一直“试”。4.3 安全护栏诊断指令自动审批与最小权限执行GenAI 平台能不能上生产环境关键看安全边界。我们做了三层护栏工具权限最小化模型能调用的函数全部是只读操作写操作例如kubectl drain、kubectl delete pod、kubectl scale都以“建议”的形式输出不直接执行。需要执行时由人工在界面上点击“应用”并二次输入操作原因前端再调用一个独立的执行模块这个模块有单独的 RBAC并记录完整审计日志。上下文隔离模型的 Prompt 中只包含与当前故障相关的命名空间和资源数据同时开启日志脱敏用户密码、Token 等敏感字段不会进入模型上下文。敏感行为关键词识别如果模型输出内容包含“删除”“驱逐”“清理”“关闭”等危险动词系统会在界面上弹出红色确认框并且这类操作必须由具备 cluster-admin 权限的人审批。这三层护栏让我们敢把诊断报告直接推给一线值班同学。他们看到建议后可以放心地去执行验证命令不会因为害怕模型乱操作而不敢用。5. 部署与调优中遇到的坑以及我的取舍最后写一些部署和调优的真实体会。这个平台从原型到上生产我们踩了很多坑挑几个最有代表性的讲讲。5.1 模型选型与 K8s 上运行 LLM 的资源成本模型选型不能只看效果还要看你们的算力预算。我们初期试过两套方案一套是直接调用云端大模型 API另一套是在自建 GPU 节点上部署开源模型。调用 API 的方式省心但有两类问题一是数据出域集群的监控指标和日志经过脱敏后仍然让人不放心合规团队审了很久二是网络延迟和限流排障高峰时大家都在调用API 响应慢会让值班人员失去耐心。自建 GPU 节点跑开源模型例如 Llama 系列、Qwen 系列的话成本和运维压力都不小。一个 7B 参数模型做推理大概需要 16GB 显存我们考虑到并发请求最多 4 个最后采购了 2 张 24GB 显存的卡配合 vLLM 做推理服务基本能稳定支撑。我们的经验是先不要追求最大的模型而是在“能跑起来的模型”里选推理效果最好的那个。比如在工具调用这一类任务上不少 13B 级别的开源模型已经够用。不要看到 benchmark 就上头上了生产你才会发现响应速度和稳定性往往更重要。5.2 索引和缓存设计让诊断速度不再是瓶颈刚开始我们没做缓存每次诊断都实时查询、实时推理结果一个诊断要三四十秒很影响体验。后来优化分了两步。第一步是指标缓存。对于近 10 分钟内的告警平台会自动把相关指标快照缓存到内部存储后续再遇到类似诊断就不用重复请求 Prometheus。第二步是诊断结果缓存如果同一类告警在 30 分钟内再次发生平台会直接返回上一次的诊断报告只标注“这是重复告警详见历史报告”。这两步把 80% 的重复诊断从三四十秒降到了 3 秒内。同时我们优化了知识库检索的召回速度。向量检索之前用的 HNSW 索引但文档量上来之后每次召回要 60~100ms虽然不致命但我们还是加了粗排层先用告警类型和资源标签做一次布尔过滤再在过滤后的小集合里做向量检索。效果很明显召回质量不但没降还因为“范围更聚焦”而变得更准了。5.3 从“事后诊断”到“主动巡检”GenAI 的下一步现在这套平台已经稳定运行了三个多月但它还只是“事后诊断”。我个人的下一步方向是想把它从“接告警”升级成“主动巡检”——每天固定时间生成集群健康巡检报告让大模型基于指标趋势标记出可能恶化的项。比如它发现某个节点的磁盘使用率一周内从 60% 涨到 85%就会提前生成一条警告并附上清理建议。这本质上是把“排障经验”用在“隐患发现”上价值更大。另外我也在试着把“对话诊断”扩展成“协同会话”。比如多个值班同学可以同时在一个诊断会话里提问模型能记住上下文还能把某个人贴的一段日志纳入后续推理依据。这个功能做出来之后排障会从“一个人孤军奋战”变成“一个团队共享同一份智能”。但这些都是长期规划了目前最让我欣慰的还是从手动翻日志到对话拿结论这个过程真正跑通了而且每天都有新故障在“喂养”知识库让系统越用越聪明。在做这个平台的整个过程中我个人最大的收获其实是重新理解了运维这个职业。GenAI 不会取代运维但它确实能替我们承担掉那些机械、重复、需要跨系统拼凑信息的脏活。过去我们花一小时在告警、日志、监控之间反复横跳现在这一个小时被压缩成了五分钟的人机协作——人负责判断和决策模型负责检索和归纳。这种工作方式改变之后团队里的新同学也能像老 SRE 一样接到一条陌生告警时不慌不乱、有理有据地说出下一步该做什么。我想这就是智能运维平台最大的价值所在。