K8s 排障经常需要在 describe、logs、events 和 node 之间来回切换。这个项目将重复的信息收集与初步判断做成小工具,同时验证 AI 在运维诊断中适合承担哪些工作、不适合越过哪些边界。
READING NOTES
本文要点
- 第一版只处理五类常见故障,不追求万能
- 采集和规则判断必须确定,模型只负责整理和补充推理
- 所有结论引用证据,工具默认没有集群写权限
01|先缩小第一版目标
如果目标是“输入任何问题都能诊断”,项目范围会迅速失控。第一版限定为 Pod Pending、CrashLoopBackOff、ImagePullBackOff、探针失败和 Node NotReady。输入 namespace 与 Pod 名称,输出 Markdown 报告。
这个范围虽然不大,但覆盖 Kubernetes API、异常处理、日志解析、规则匹配、模型调用和报告生成,足以形成一个完整的 AI Ops 最小可用项目。
02|项目目录怎么拆
项目没有一开始就引入复杂框架。先让每个模块只做一件事,命令行跑通后,再考虑 Web 页面。当前目录结构如下:
k8s-doctor/
├── app.py # 命令行入口
├── collectors/
│ ├── pod.py # Pod 状态与容器退出原因
│ ├── events.py # Event 时间线
│ ├── logs.py # 当前与上一次容器日志
│ └── node.py # 节点条件、污点与资源
├── rules/
│ ├── scheduler.py # Pending / 调度失败
│ ├── image.py # 镜像拉取失败
│ └── restart.py # 重启与退出码
├── llm/
│ └── analyzer.py # 组织上下文并调用模型
├── reports/
│ └── markdown.py # 生成报告
└── tests/
└── fixtures/ # 脱敏后的故障样本03|先把证据采对
采集层使用 Kubernetes Python Client,不直接解析 kubectl 的终端文本。API 返回对象更适合后续结构化处理。下面是一个精简后的 Pod 采集函数:
from kubernetes import client, config
def collect_pod(namespace: str, name: str) -> dict:
config.load_kube_config()
core = client.CoreV1Api()
pod = core.read_namespaced_pod(name=name, namespace=namespace)
containers = []
for status in pod.status.container_statuses or []:
waiting = status.state.waiting
terminated = status.last_state.terminated
containers.append({
"name": status.name,
"ready": status.ready,
"restart_count": status.restart_count,
"waiting_reason": waiting.reason if waiting else None,
"last_exit_code": terminated.exit_code if terminated else None,
})
return {
"namespace": namespace,
"name": name,
"phase": pod.status.phase,
"node": pod.spec.node_name,
"conditions": [
{"type": item.type, "status": item.status, "reason": item.reason}
for item in pod.status.conditions or []
],
"containers": containers,
}FIELD NOTE这里最容易踩的坑是字段可能为空。Event、container_statuses、last_state 都不能假设一定存在,否则工具诊断故障 Pod 时自己先报错。
04|事件要按时间线整理
K8s Event 会重复聚合,同一个原因可能只有一条记录但 count 很高。应保留 reason、message、count、firstTimestamp 和 lastTimestamp,并按最后发生时间排序。模型不需要全部日志,只需要与故障窗口有关的证据。
def normalize_events(items) -> list[dict]:
events = []
for item in items:
events.append({
"reason": item.reason,
"message": item.message,
"count": item.count or 1,
"first_seen": str(item.first_timestamp or ""),
"last_seen": str(item.last_timestamp or item.event_time or ""),
})
return sorted(events, key=lambda x: x["last_seen"])
05|规则层先处理确定的问题
镜像不存在、PVC 未绑定、节点资源不足,这些信息在 Event 中已经很明确,没有必要每次都调用模型。每条规则设置 ID、严重度、命中证据和建议,后续报告可以直接引用。
def check_pending(evidence: dict) -> list[dict]:
findings = []
text = "\n".join(e["message"] for e in evidence["events"])
rules = [
("P001", "Insufficient cpu", "节点可分配 CPU 不足"),
("P002", "Insufficient memory", "节点可分配内存不足"),
("P003", "unbound immediate PersistentVolumeClaims", "PVC 尚未绑定"),
("P004", "had taint", "Pod 未容忍节点污点"),
]
for rule_id, keyword, conclusion in rules:
if keyword.lower() in text.lower():
findings.append({
"rule_id": rule_id,
"conclusion": conclusion,
"evidence": keyword,
"risk": "medium",
})
return findings06|什么时候才调用模型
规则运行后,将 Pod 摘要、最近事件、关键日志、节点状态和命中的规则组合成证据包。模型必须按固定 JSON 结构返回结论、证据 ID、建议、风险和验证方法。证据不足时,应返回需要补充什么,不能编造命令。
SYSTEM_PROMPT = """
你是 Kubernetes 运维分析助手。
只能根据 evidence 回答,不要补造集群事实。
每条结论必须引用 evidence_id。
不要执行变更,只给检查或候选修复步骤。
证据不足时,把 status 设为 need_more_evidence。
"""
payload = {
"symptom": "Pod 一直处于 Pending",
"evidence": evidence_items,
"rule_findings": findings,
"output_schema": {
"status": "diagnosed | need_more_evidence",
"conclusion": "string",
"evidence_ids": ["E01"],
"steps": ["string"],
"risk": "low | medium | high",
"verify": ["string"],
},
}07|一份报告长什么样
报告首页只放现象、最可能原因、证据和下一步。原始 JSON 与完整日志放附件。命令默认只读;涉及 rollout restart、修改资源、删除 Pod 或调整节点时,只生成候选动作并明确需要人工审批。
- 现象:default/api-7d9xx Pending 12 分钟。
- 结论:没有节点满足内存请求,置信度高。
- 证据:E03 调度事件包含 Insufficient memory,重复 18 次。
- 建议:核对 requests 是否合理,再检查节点可分配内存与扩容计划。
- 验证:Pod 成功调度且 Ready,相关 Event 不再新增。
08|目前还没解决的问题
这个工具目前适合做故障信息收集和第一轮判断,还不能替代有经验的 K8s 工程师。跨 namespace 的调用链、CNI/CNI 插件问题、存储后端问题,需要接 Prometheus、日志平台和更多组件信息。
下一步优先完善测试样本。每修复一个真实问题,就把脱敏后的证据包和正确结论放入 fixtures,避免以后修改规则时破坏已经能够诊断的问题。
FIELD NOTE这个项目最有价值的部分,不是做出一个“AI 页面”,而是将依赖经验的排障顺序转化为可检查的数据结构和代码。
SOURCES / 资料核对
相关官方资料
产品功能会随版本和授权变化。下面列出撰写时核对的资料, 实际交付仍以项目版本的兼容矩阵和正式文档为准。