我是韩先超,51CTO 学堂 K8s、Python 教学总监、AIOps 实战训练营讲师,云计算架构师,具有 8 年项目实战经验+5 年教学经验,线上学员已达 300w+。

关键词:AIOps、DeepSeek、Prometheus、Zabbix、MCP、RAG、预测扩容

技术栈:DeepSeek+Prometheus/Zabbix/EFK+Jenkins+Kubernetes

适用对象:已经有监控平台,想把大模型接到日常值班里的运维团队

业务上了 Kubernetes 之后,告警越来越多,故障却越来越难查。固定阈值经常白天漏报、夜里误报;半夜出问题还得开机连 VPN。虽然大模型能看日志、写方案,但直接让它改生产,谁都不敢。

图片

我在互联网、政企和研究院做过一批项目,核心做法很简单:原来的 Prometheus、Zabbix、EFK 继续用,大模型只负责分析和给建议,真正改集群、改流水线之前,先模拟执行,再让人点确认。

下面用 10 个能跑起来的小项目说明运维怎么做,并附上关键代码和界面截图。

现在运维到底卡在哪

云原生普及以后,一个故障很少只打一条告警。订单接口变慢,往往会同时冒出 API 延迟、Pod 起不来、缓存命中率下降、支付超时。

值班的人面对几十上百条告警,分不清哪条是根因、哪条是连带出来的。真正严重的问题,反而容易被淹没。

还有几个很常见的麻烦:

  • 查故障要在监控、日志、集群事件之间来回翻,耗时长。
  • 夜里出问题必须坐到电脑前、连上 VPN,才能点 Jenkins、改 K8s。
  • 公司里其实有不少故障手册和历史工单,但通用大模型不知道这些,给出来的命令经常和环境对不上。
  • Kubernetes自带的 HPA 只看当前 CPU,流量突然上来时,新 Pod 还要冷启动几十秒到两分钟,业务已经开始 503 了。

行业里的数字也差不多是这个意思。中国信通院 2024 年调查里,一半以上企业觉得自己到了比较深的智能化阶段,但大模型大多还停在研究了解阶段,真正接到生产里的不多。

PagerDuty 早期做过 AIOps 的用户,告警噪声平均能降大约 87%。说明事能做成,难的是怎么安全地做成。

图片

图 1:企业 AIOps 能力自评分布(数据来源:中国信通院 2024 年调查)

图片

图 2:运维领域用大模型的阶段:大多数还在了解,真正自建的很少

我做这些项目时,遵守这三条规则:

1. 不推倒现有监控。Zabbix、Prometheus、EFK继续采集,大模型接在后面做分析。

2. 大模型负责 “看” 和 “想”,拉数据、调接口、改集群交给程序去做,不要让模型自己拼命令满地跑。

3. 自动修复默认先模拟跑一遍(dry-run)。核心进程不能乱动,改生产必须人点头。

可以这么记:监控负责 “看”,大模型负责 “想”,接口负责 “做”,模拟执行和白名单负责 “把关”。

图片

图 3:以前主要是发现异常;现在要把分析、执行、知识沉淀串起来(根据项目自评)

案例 1:把一堆告警收成几条故障故事

技术栈:DeepSeek+Prometheus+Alertmanager

一个底层故障,监控往往会连锁打出很多条告警。需要工作台先从 Alertmanager 把告警拉下来,去掉重复的,再让大模型做关联:

哪些是源头,哪些是连带的。要求它按固定格式输出,不要写成 “散文”。要写清时间、影响了哪些服务、根因告警是哪条、建议做什么、能不能自动执行。

我们有一次演练,86 条原始告警,降噪和关联之后变成 2 条故障说明、1 个需要人确认的修复动作。

AI给出方案后,先模拟执行,不会直接改生产;人确认了才真正修复。修复完,还能导出 Word,方便复盘。

图片

图 4:告警风暴处理工作台:接上 Prometheus 和 Alertmanager,可以先模拟再修复

图片

图 5:一次演练里告警是怎么一层层变少的(示意)

关键代码并不复杂:先把告警收成 JSON,再规定模型必须按这个结构回答。

代码 1:从 Alertmanager 拉告警,并规定大模型怎么回答

import json, requests
from datetime import datetime, timezone


AM = "http://192.168.40.180:30066"


def fetch_alerts():    
  r =   requests.get(f"{AM}/api/v2/alerts", timeout=8)     
  r.raise_for_status()    
 rows = []    
 for a in   r.json():         
     rows.append({             
       "name": a["labels"].get("alertname"),             
       "inst": a["labels"].get("instance"),             
       "sev": a["labels"].get("severity"),             
       "desc":   a["annotations"].get("description", ""),             
       "starts": a.get("startsAt"),        
     })
  return rows


def build_prompt(alerts): 
  return (    
     "你是值班助手。只根据下面的告警做关联,不要编造没有出现的服务。\n"
     "请输出   JSON,字段包括:root_alert(根因)、derived(连带告警)、"
     "action(建议动作)、auto_allowed(能否自动执行,默认 false)。\n"
     f"当前时间:   {datetime.now(timezone.utc).isoformat()}\n"
     f"告警列表:   {json.dumps(alerts, ensure_ascii=False)}"
  )

案例 2:用说话的方式做运维,夜里也能在手机上处理

纯敲命令对很多人并不友好,夜里出问题还得开电脑。我做了两套对话运维:一套是网页,一套是微信。

网页这套用 MCP 协议把 Jenkins 的能力收成几个固定工具,比如 “列出任务”“触发构建”。

人用中文说一句,模型只能调用这些工具,不能自己去拼 Jenkins 的网址。查状态可以很快返回;真要构建,必须再确认一次。

图片

图 6:对话运维台:用自然语言列出 Jenkins 任务,并解释当前为什么是 “已中止”

微信这套把同样的能力接到聊天窗口。手机发一句 “看看构建日志” 或 “重新跑一下这条流水线”,就能拿到结果,也能看出卡在人工审批的节点。

夜里不用再抱着笔记本连 VPN。聊天记录本身就是操作日志,方便事后核对。

代码 2:把 Jenkins 操作收成带确认开关的工具,查询和变更分开

# 模型只能调用下面这些工具,不能自己发明接口
tools = [    
  {         
      "name": "jenkins_list_jobs",         
      "description": "列出 Jenkins 任务和当前构建状态",         
      "input_schema": {"type": "object",   "properties": {}}    
  },    
  {         
      "name": "jenkins_build",         
      "description": "触发一次构建。生产任务必须确认后才能真正执行",         
      "input_schema": {             
         "type": "object",             
         "required": ["job", "confirm"],             
         "properties": {                 
            "job": {"type": "string"},                 
            "confirm": {"type": "boolean"},                 
             "dry_run": {"type": "boolean",   "default": True}            
      }        
   }    
 }
]


def jenkins_build(job, confirm, dry_run=True):    
  if dry_run   or not confirm:        
     return   {"accepted": False, "preview": f"将构建 {job},等待确认"}    
     return   client.build_job(job)

案例 3:老监控 Zabbix 也能接上大模型

很多企业还在用 Zabbix,不可能为了 AI 把监控推倒重来。

我用 Python 做了个内网桌面工具,通过 Zabbix 接口拉取最近一天、七天、一个月的数据和告警,找出 CPU、内存占用高的进程,交给 DeepSeek 写根因和修复建议。

自动重启只对白名单生效,比如 Nginx、业务 Java。sshd、systemd 这类系统进程一律不许动。工具跑在内网,监控数据不会传到外面。

图片

图 7:内网桌面工具:从 Zabbix 拉数据,大模型出报告,重启受白名单限制

静态阈值还有一个老问题:白天业务高峰容易漏报,夜里负载很低又容易误报。

我用脚本定期看机器 CPU 的实际水平,算出一个动态阈值,再通过 Zabbix 接口改触发器。

同时设一个最低门槛,比如不低于 45%,避免夜里被一点点抖动打穿。内存、磁盘、网络也可以用同一套办法。

代码 3:用 Zabbix 接口改告警阈值,并用黑白名单限制自动重启

import requests


ZBX =   "http://192.168.40.160/zabbix/api_jsonrpc.php"
TOKEN = "********"
SAFE_RESTART = {"nginx", "java",   "python", "dotnet"}   # 允许自动重启
HARD_DENY = {"sshd", "systemd",   "dockerd", "kubelet"}   # 绝对不能动


def zbx(method, params):    
  payload =   {"jsonrpc": "2.0", "method": method,   "params": params, "id": 1, "auth": TOKEN}    
  return   requests.post(ZBX, jsnotallow=payload, timeout=12).json()["result"]


def patch_cpu_trigger(p95_cpu, floor=45):    
  # 动态阈值:业务分位往上留一点余量,同时不低于兜底值    
  threshold =   max(int(p95_cpu + 8), floor)    
   expr =   f"last(/{{HOST:cpu.util}})>={threshold}"    
   return   zbx("trigger.update", {"triggerid": "12045",   "expression": expr})


def may_restart(proc_name: str) -> bool:    
  name =   proc_name.lower()    
  if any(d in   name for d in HARD_DENY):        
     return   False    
  return   any(s in name for s in SAFE_RESTART)

案例 4:Prometheus 动态告警,以及提前扩容

Prometheus 这边,静态 80% 一样不好用。

我用 Python 拉历史曲线,用 Prophet 学习白天高峰、夜里低谷的规律,生成两套阈值,再改 rules.yml 让规则生效。

图片

图 8:一天里的 CPU:固定 80% 和跟着业务走的阈值,差在哪(示意)

弹性伸缩是另一个痛点。原生 HPA 看到 CPU 高了才开始加副本,新 Pod 还要启动一段时间,流量高峰时很容易 503。

我们的做法是:持续采集 CPU、内存、QPS、延迟,让大模型估计未来 10 分钟、30 分钟、60 分钟大概要多少副本,赶在流量上来之前先加好。

预测结果不会直接覆盖人工定的上下限。节假日、发版、演练的时候,模型只给建议,不当真控制器。还要做防抖,不然预测一晃,集群就会来回扩缩。

图片

图 9:流量突然上来时:等 CPU 升高再扩容,和提前加好副本,结果差很多(示意)

代码 4:用 Prophet 算动态阈值;扩容默认先模拟,确认后再改副本数

from prophet import Prophet
import pandas as pd
from kubernetes import client, config


def fit_threshold(ts: pd.DataFrame) ->   pd.DataFrame:  
  m =   Prophet(daily_seasnotallow=True, weekly_seasnotallow=True)     
    m.fit(ts.rename(columns={"t": "ds",   "cpu": "y"}))  
  future =   m.make_future_dataframe(periods=96, freq="15min")
  fcst =   m.predict(future)
   fcst["thr"] = (fcst["yhat"] + 12).clip(lower=45,   upper=92)  
  return   fcst[["ds", "yhat", "thr"]]


def recommend_replicas(pred_qps, qps_per_pod=80,   lo=3, hi=20): 
  want =   int(pred_qps / qps_per_pod) + 2 #多留 2 个,给冷启动留时间    
  return   max(lo, min(hi, want))


def apply_scale(ns, name, replicas, dry_run=True):
  config.load_kube_config() 
  apps =   client.AppsV1Api()
  body =   {"spec": {"replicas": replicas}}  
  if dry_run:  
     return   apps.patch_namespaced_deployment(name, ns, body, dry_run="All")
     return   apps.patch_namespaced_deployment(name, ns, body)

案例 5:从海量日志里找出隐患,再用自己的知识库来回答

有些问题监控还没告警,日志里已经出现了,比如权限不足、要伸缩的 Deployment 其实不存在。人工在日志里捞,效率很低。

这个平台对接 Elasticsearch,用历史日志先画出 “正常长什么样”,再找出明显偏离的片段,交给大模型判断风险等级、影响范围、根因和应急步骤,报告可以导出 Word 或 PDF。

经验:统计和基线负责把可疑日志找出来,大模型只解释这些片段。让模型直接读几百万行,又贵又慢,还容易被同一段报错刷屏带偏。

图片

图 10:日志异常检测:找出 kube-state-metrics 权限不够,HPA 其实已经看不全集群

通用大模型还有幻觉问题,给的排障步骤经常和公司环境不一致。我们把故障手册、SOP、真实案例做成向量库。

遇到问题,先检索内部文档,再让模型整理成能复制执行的命令。如果知识库里没有对应内容,必须写明 “知识库没覆盖到,以下只是推测”,不能装得很确定。

在这个基础上,还有一个一键诊断工具:自动采集 Pod 状态、容器日志、集群事件,结合内部规范,直接出一份诊断报告,少翻很多页面。

图片

图 11:K8s 诊断工具:采集节点资源后,按公司内部规范给出扩容建议

代码 5:先用检索找出可疑日志和相关文档,再让大模型解释,并带上出处

from elasticsearch import Elasticsearch
from pathlib import Path


es =   Elasticsearch("http://192.168.40.180:30920")


def recall_anomalies(index="logstash-*",   minutes=60, size=50):
  q = {    
     "query": {         
       "bool": {            
         "must": [{"range": {"@timestamp":   {"gte": f"now-{minutes}m"}}}],            
         "should": [                
            {"match": {"message": "forbidden"}},
            {"match": {"message":   "CrashLoopBackOff"}},
            {"match": {"message":   "ImagePullBackOff"}},
         ],
         "minimum_should_match": 1,
       }
     },
      "size": size
   }
   hits =   es.search(index=index, body=q)["hits"]["hits"]
   return   [h["_source"].get("message", "") for h in hits]


def rag_answer(query, store, llm): 
  docs =   store.similarity_search(query, k=4)
  cites =   [Path(d.metadata["source"]).name for d in docs] 
  prompt = (        
     "只根据下面这些内部文档回答。每条建议后面写上文档名。"
     "如果文档盖不住这个问题,请明确写:知识库未覆盖。\n"
     f"文档:   {chr(10).join(d.page_content for d in docs)}\n"
     f"现场情况:   {query}"
  )
    return   {"answer": llm.chat(prompt), "citations": cites}

案例 6:用中文管理 K8s,也能快速做出运维小工具

kubectl 命令不好记。我用 Streamlit 做了个内网网页,输入中文,比如 “查看kube-system 命名空间的 Pod”,先转成固定格式的 JSON,再去调集群接口。

人不用背命令,但每一次操作在系统里都是一次说得清的 API 调用,方便审计。

图片

图 12:用中文查 Pod:先变成 JSON 指令,再列出 Running 的容器

另外还用 AI 辅助,很快搭了两个网页。一个是内网对话助手,可以说 “帮我给Nginx 加限流”,直接生成带注释的配置、Dockerfile、YAML 或脚本。

另一个是轻量的集群管理台,大约半小时做出能用的版本,网页上就能管理命名空间、工作负载和 Pod,不必完全依赖官方 Dashboard,数据也留在内网。

图片

图 13:内网对话助手:用一句话生成 Nginx 限流配置,并附说明

图片

图 14:轻量 K8s 管理台:在网页上查看、扩容、重启、删除工作负载

代码 6:中文先转成白名单里的动作;改副本、删 Pod 默认先模拟

ALLOWED = {("get", "pod"),   ("get", "deploy"), ("scale",   "deploy")}
NEED_CONFIRM = {("scale",   "deploy"), ("delete", "pod")}


def parse_nl(text: str) -> dict:
    # 示例:把「查看   kube-system 的 Pod」转成结构化指令
    return   {"action": "get", "resource": "pod",   "namespace": "kube-system"}


def execute(cmd: dict, dry_run=True):
    key =   (cmd["action"], cmd["resource"])
    if key not   in ALLOWED:
        raise   PermissionError(f"不允许的操作: {key}")
    if key in   NEED_CONFIRM and dry_run:
        return   {"ok": True, "mode": "模拟执行", "cmd":   cmd}
    if   cmd["action"] == "get" and cmd["resource"] ==   "pod":
        return   v1.list_namespaced_pod(cmd["namespace"])
    raise   RuntimeError("尚未实现")

表 1:10 个项目一览

项目

解决什么问题

怎么做

安全上怎么卡

告警关联

告警太多,找不到根因

降噪+大模型整理

先模拟,再导出报告

网页对话运维

命令不好记

中文调用 Jenkins

查询放开,变更要确认

微信运维

夜里必须开电脑

手机发一句话处理

聊天记录当审计

Zabbix 分析

老监控用不上 AI

拉数据让模型写报告

进程黑白名单、内网部署

动态阈值

高峰漏报、低谷误报

按实际负载改触发器

设置最低阈值

Prometheus 预测

规则写死 80%

按白天/夜里两套规则

发版窗口先冻结

预测扩容

来不及扩,出现 503

提前 10/30/60 分钟加副本

先模拟,再卡上下限

日志检测

问题藏在日志里

先找出异常,再让模型解释

输出标准报告

私有知识库

通用模型会胡说

先查公司文档再回答

查不到就明说

中文管集群

kubectl 门槛高

中文转成固定 JSON

只允许白名单操作

图片

图 15:和传统监控相比,这套做法在关联分析和自动修复上更完整(自评)

落地时,踩过的坑

  • 不要太相信大模型的输出。自动修复最怕误操作。我几乎每个项目都加了模拟执行、黑白名单和操作日志。方案先给人看,人点了再执行。
  • 大模型适合读日志、做判断、写步骤,不适合自己去采集指标、调接口。采集和变更用普通程序来做,更稳。
  • 能复用现成监控就复用。很多单位已经有 Zabbix 或 Prometheus,在上面接一层 AI,比换一套平台容易推动。
  • 演示和生产差很远。演示可以全自动,生产还要考虑登录权限、内网隔离、超时重试、审计。我这些原型都优先保证数据留在内网。
  • 知识库质量决定回答质量。文档又旧又乱,模型再强也写不出靠谱方案。

另外,Zabbix 的 history 和 trend 不要混用:短时间看明细,长时间看趋势,弄反了模型会以为 “一直很平稳”。

表 2:哪些能自动、哪些必须人来点,建议写进规范

级别

典型操作

能不能自动

至少要有什么

只读

查询、写报告、整理告警

可以自动

登录校验、脱敏、留日志

可改、可回退

加副本、重跑流水线、重启白名单进程

先模拟,人确认后再做

白名单、回滚办法、超时

风险大

删资源、改生产配置、关节点

默认不做,只给方案

两人确认、变更窗口

小结

以前做 AIOps,多半是用统计和固定规则找异常,看起来热闹,值班时往往用不上。

有了 DeepSeek 这类大模型,分析和写方案容易多了,但真正能用的关键还不在模型本身,而在后半段:建议出来之后,怎么安全地执行、怎么留下记录、怎么把经验写回知识库。

大模型不是来替代运维的。它是把人从刷告警、翻日志、反复写脚本里解放出来,把时间留给架构和难啃的故障。

上面这 10 个小项目都可以拿去改,接到自己环境里。监控继续用现在的,分析用大模型,改生产之前先模拟、再确认。这样做就比较踏实!