Grafana cluster变量出现Kafka垃圾值的排查与清理

Grafana cluster变量出现Kafka垃圾值的排查与清理

记录时间:2026-08-08
环境:RKE 信创 ARM64 / kube-prometheus-stack / Prometheus 2.52 / VictoriaMetrics 集群 / Grafana

一、问题现象

Grafana 的 cluster 模板变量(Query type 为 Label values,查询 label_values(cluster))Preview 里冒出来 4 个值:

clusterA-prod-xc
clusterB-prod-xc
clusterA-kafka-cluster
{{ $labels.kafka_cluster }}

后两个明显是垃圾值。cluster 变量本应只包含真实集群标识(clusterA-prod-xcclusterB-prod-xc),而且更诡异的是,在本地 Prometheus 里直接查这两个值,根本找不到对应序列。

二、排查过程

2.1 起因:对比 node-exporter 覆盖时发现

起因是某次对比核实 node-exporter 监控覆盖时,顺带看了下 cluster 变量,结果发现 Preview 里多了一堆垃圾值。

2.2 搜索 cluster 标签来源

全仓库搜 cluster 相关赋值,命中两处关键配置:

位置 内容 作用
clusterA-prod-xc-kube-prometheus-stack/values.yaml:165-166 externalLabels: cluster: "clusterA-prod-xc" clusterA(集群A)外部标签
clusterB-prod-xc-kube-prometheus-stack/values.yaml:163-164 externalLabels: cluster: "clusterB-prod-xc" clusterB(集群B)外部标签
rules/kafka/kafka-rules.yaml 18 处 cluster: "{{ $labels.kafka_cluster }}" Kafka 告警规则 labels

外部标签 cluster 只有两个合法值(clusterA / clusterB),而 kafka_cluster 标签来自两个 Kafka ServiceMonitor 的 relabeling:

  • kafka/helm/prod/kafka4.0/kafka-exporter-servicemonitor.yaml:73-74kafka_cluster: clusterA-kafka-cluster
  • clusterB-prod-xc-kube-prometheus-stack/other/kafka/kafka-sm.yaml:33kafka_cluster: clusterB-kafka-ingest

2.3 最初的误判

最开始我直接怀疑是 kafka-rules.yaml 里那 18 处 cluster: "{{ $labels.kafka_cluster }}" 干的好事。但转念一想不对:这是告警规则输出给 Alertmanager 的标签,跟 Grafana 的 label_values 查询能有什么关系?不能想当然,得从机制上确认它到底影不影响。

2.4 核实机制:ALERTS 序列写入 TSDB

查 Prometheus 官方文档确认:告警处于 pending/firing 时,Prometheus 会生成名为 ALERTS 的合成时间序列并写入 TSDB,该序列的标签集包含规则 LABELS 子句定义的所有标签(不只是 alertname/alertstate)。

也就是说,告警规则的 labels 不只是发给 Alertmanager,同时会落进 TSDB 的 ALERTS 序列;label_values(cluster) 扫的是全序列,自然把它们收进来。

2.5 关键转折:Grafana 数据源其实是 VictoriaMetrics

本地 Prometheus 查不到,是因为 Grafana 连的根本不是它。证据有三:

  1. values.yaml:174-177:Prometheus remoteWritehttp://prod.vm.example.com/insert/0/prometheus/(VictoriaMetrics)
  2. values.yaml:595-599:Grafana hostAliases 专门为 prod.vm.example.com 写了解析(指向 10.x.x.x
  3. Preview 里同时有 clusterA-prod-xcclusterB-prod-xc:只有 VM 汇总了两套 Prometheus 的 remoteWrite 数据,才会同时出现两个集群的 cluster 值;本地 Prometheus 只有 clusterA 一个

Grafana 数据源是在 UI 手动配置的(values.yaml:684-685datasources.enabled: false,数据源存 MySQL),仓库里看不到,但 VM 域名写进 hostAliases 已经足以说明指向。

2.6 在 VM 中验证,确认根因

直接在 VM 里查 ALERTS 序列,结果证实了上面的判断:

表 1:cluster=clusterA-kafka-cluster 的 ALERTS

alertname alertstate kafka_cluster cluster
KafkaController频繁切换 pending clusterA-kafka-cluster clusterA-kafka-cluster
KafkaBroker不可用 pending clusterA-kafka-cluster clusterA-kafka-cluster
KafkaISR持续收缩 firing clusterA-kafka-cluster clusterA-kafka-cluster

这些告警的 expr 结果序列kafka_cluster 标签,模板 {{ $labels.kafka_cluster }} 渲染成功,得到实际值 clusterA-kafka-cluster

表 2:cluster={{ $labels.kafka_cluster }} 字面量的 ALERTS

alertname alertstate kafka_cluster cluster
KafkaController数量异常 pending (空) {{ $labels.kafka_cluster }}
Kafka集群节点存活数告警 pending (空) {{ $labels.kafka_cluster }}

这两条告警的 expr 是 sum by(systemName) (...) 聚合查询,聚合后 kafka_cluster 标签被丢弃,模板没有可引用的标签值,字面量 {{ $labels.kafka_cluster }} 原样进了 ALERTS 序列的 cluster 标签。

三、根因分析

根因链条如下:

kafka-rules.yaml 告警规则 labels 写 cluster: "{{ $labels.kafka_cluster }}"
  ↓ 告警 pending/firing
Prometheus 生成 ALERTS 合成序列写入 TSDB(带渲染后的 cluster 标签)
  ↓ remoteWrite 全部写入
VictoriaMetrics(prod.vm.example.com)
  ↓ Grafana label_values(cluster) 扫描全序列
cluster 变量出现 clusterA-kafka-cluster / {{ $labels.kafka_cluster }} 两个垃圾值

另外两个现象的解释:

  1. 为什么会有两种垃圾值形态:取决于告警 expr 是否保留 kafka_cluster 标签。保留则渲染成实际值;被 sum by(systemName) 等聚合丢弃则保留字面量。
  2. 为什么 externalLabels 没兜底:externalLabels 本会把 cluster: "clusterA-prod-xc" 加到 ALERTS 序列上,但规则 labels 的 cluster 优先级更高,把 externalLabels 覆盖掉了。这可以从 ALERTS 序列同时存在 prometheusprometheus_replica(externalLabels 加进来的)而 cluster 却是 kafka 值看出来。

四、解决方案

确认根因后,删除 rules/kafka/kafka-rules.yaml 中全部 18 处 cluster: "{{ $labels.kafka_cluster }}" 行。

cd k8s部署yaml/prometheus/kube-prometheus-stack/clusterA-prod-xc-kube-prometheus-stack
# 删除 rules/kafka/kafka-rules.yaml 中 18 处 cluster: "{{ $labels.kafka_cluster }}"

选择删除而不是改成固定值,原因:删掉后 ALERTS 序列的 cluster 自动回落到 externalLabels 的 clusterA-prod-xc,cluster 变量只剩两个真实集群值,最干净;要是改成 clusterA-kafka-cluster 固定值,变量里还是会残留一个 kafka 集群维度值。

五、验证

5.1 文件层面

# 确认无残留模板
grep -n 'cluster:.*kafka_cluster\|cluster:.*{{\$' rules/kafka/kafka-rules.yaml
# 无输出

# YAML 结构校验(18 条告警规则均无 cluster 标签)
python3 -c "import yaml; d=yaml.safe_load(open('rules/kafka/kafka-rules.yaml')); print(len(d['spec']['groups']))"

文件内 cluster 关键字仅剩 expr 表达式中的 kafka_cluster(聚合运算用的原始指标标签),与告警 labels 无关。

5.2 机制层面

  • annotations(summary/description)里引用的标签是 $labels.systemName$labels.instance$labels.topic$labels.persistentvolumeclaim$value 等,无一处引用 $labels.cluster,删除不影响告警文案渲染。
  • Alertmanager 配置(values.yaml 396-589 行)的路由 matchers、group_by、inhibit_rules 分别依赖 alertname/app/severity/service/instance/alertCategory无一处依赖 cluster,删除不影响告警分发与抑制。

5.3 生产环境验证

  • kubectl apply -f 该 PrometheusRule(或 helm upgrade)使其生效
  • 生效后 VM 里旧的 ALERTS 序列随时间过期消失
  • 最终确认:Grafana cluster 变量刷新后只剩 clusterA-prod-xc / clusterB-prod-xcclusterA-kafka-cluster{{ $labels.kafka_cluster }} 两个垃圾值都没了,闭环。

结论(2026-08-11 生产验证):cluster 变量回归两个真实集群值,根因链条与修复方案完全闭环。

六、注意事项

  • 告警规则的 labels 不只是告警通知标签,会落进 TSDB 的 ALERTS 序列,从而影响 label_values 类全序列扫描查询。
  • Grafana 变量”Preview 有值但数据源里找不到”时,先确认 Grafana 数据源指向。跨集群 remoteWrite 汇总场景下,数据源通常是 VictoriaMetrics 而非本地 Prometheus。
  • 外部标签(externalLabels)会被规则 labels 覆盖,排查 cluster 类标签时两个来源都要看。
  • sum by(...) 等聚合查询会丢弃未列入 by 的标签;模板引用被丢弃的标签时,结果是空值或字面量,容易因此出错。
  • PrometheusAlert 微信模板由外部服务(prometheus-alert-center)渲染,若其模板引用了 cluster 标签,Kafka 告警推送中该字段会变空,需到 PrometheusAlert 服务端模板确认。

七、参考资料

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇