Skip to content

02. 通知适配器:cloudevents 到飞书卡片

AI 诊断出来了,怎么"好看地"送到人面前?这篇讲通知管道最后一公里的设计: 协议转换、双格式解析、中文兜底翻译、互动卡片渲染。 完整技术细节见 K8sGPT 飞书适配器详解

1. 为什么必须有适配器

  • K8sGPT sink 只支持 slack / mattermost / cloudevents没有飞书
  • 飞书机器人只认自家协议,直连 sink webhook 返回 {"code":19002,"msg":"params error, msg_type need"}
  • Alertmanager webhook 的通用 JSON 同理

适配器 = HTTP 收包 → 解析 → 润色/翻译 → 组装飞书消息 → 转发。 实现选型:python 标准库单文件(http.server + urllib,零三方依赖), 镜像 50MB,资源 10m/32Mi——通知链路越简单越可靠,不引入 web 框架。

2. 解析层:按真实载荷写,不按想象写

operator sink 实际发送(v0.2.x 实测,源码 pkg/sinks/cloudevents.go):

json
{
  "type": "com.github.k8sgpt-ai.k8sgpt-operator.sinks.cloudevents",
  "data": {
    "text": ">*[k8sgpt] K8sGPT analysis of the Pod mysql/mysql-primary-0*",
    "attachments": [{"type": "mrkdwn", "title": "Report",
      "text": "Error: MySQL容器因内存不足被系统强制终止(OOMKilled)。\nSolution: 1. ..."}]
  }
}

设计要点:

  • 双格式兼容:优先识别 {text, attachments}(真实格式),兜底按 Result CR(data.spec)解析, 防 operator 后续版本改行为
  • 资源标识在 data.text 自然语言句式里,正则提取 analysis of the <Kind> <ns/name>
  • 解析失败不吞错:原始报文截断塞进卡片发出——消息永不为空,永远可追溯

3. 中文兜底翻译

CR 里 language: 简体中文 能解决 90%,但 anonymize 打码内容偶尔诱导模型输出英文。 适配器做最后一道保险:

报告主体无中文字符(正则 [一-鿿] 不匹配)
  → 复用 k8sgpt-backend 的 Key 调 AI 翻译(保留 Error:/Solution: 格式与命令)
  → 翻译失败 → 静默降级发原文

原则:可达性 > 美观性,任何一步失败都降级而不是丢消息。

4. 渲染层:飞书互动卡片

纯文本 msg_type: text 升级为 msg_type: interactive 卡片:

链路卡片设计
K8sGPT 诊断红色标题栏 🔍 + 资源类型/名称双栏 + ❌问题/🛠修复建议 markdown(命令等宽)+ 巡检说明注释
Alertmanager 告警触发🔥红头/恢复✅绿头 + 级别/状态/命名空间/时间四栏 + 摘要详情 + 分组统计注释;单卡最多 5 条折叠

排版技巧:Error:/Solution:/错误:/建议: 前缀正则替换为加粗图标小节, AI 输出格式天然规整,润色成本低。

5. 最佳实践清单

  1. 转换层极简:无框架、无状态、单副本,丢了由上游重试兜底
  2. 消息永不为空:解析失败发原文、翻译失败发原文
  3. 按真实载荷写解析,上线前用真实事件端到端验证(删一条 Result 等下轮即可)
  4. 留日志:recv 摘要 + 下游响应是排障第一现场(飞书错误码 19002/19056/19024)
  5. 敏感信息全入 Secret,AI Key 用 optional: true 引用——缺失时降级而非起不来
  6. 限流意识:飞书机器人 100 条/分钟;K8sGPT 靠 10m 间隔 + 结果去重天然限流, Alertmanager 靠分组 + repeat_interval
  7. operator 升级后回归验证 sink payload 结构(内部实现细节,跨版本可能变)

6. 一次真实通知的完整旅程

15:00  K8sGPT 分析服务器发现 mysql-primary-0 OOM
15:00  qwen-plus 返回中文报告 → Result CR 落盘
15:00  operator sink POST cloudevents → 适配器 recv 791B
15:00  报告含中文 → 跳过翻译 → 组装卡片 → POST 飞书
15:00  飞书 resp {"code":0} → 群里出现红色诊断卡片
全程 < 3 秒(AI 分析耗时不计)