prometheus Evaluating rule failed 问题
问题概述
在 Rancher Monitoring 中看到 PrometheusRuleFailures 告警:
1 | PrometheusRuleFailures -> rule_group=/etc/prometheus/rules/prometheus-rancher-monitoring-prometheus-rulefiles-0/cattle-monitoring-system-rancher-monitoring-kube-apiserver-availability.rules-xxx.yaml;kube-apiserver-availability.rules |
Prometheus 日志中有如下报错,可以看到 recording rule 计算失败:
1 | ts=2025-08-19T01:16:36.927Z caller=group.go:462 level=warn name=code_verb:apiserver_request_total:increase30d index=0 component="rule manager" file=/etc/prometheus/rules/prometheus-rancher-monitoring-prometheus-rulefiles-0/cattle-monitoring-system-rancher-monitoring-kube-apiserver-availability.rules-xxx.yaml group=kube-apiserver-availability.rules msg="Evaluating rule failed" rule="record: code_verb:apiserver_request_total:increase30d\nexpr: avg_over_time(code_verb:apiserver_request_total:increase1h[30d]) * 24 * 30\nlabels:\n alert_source: oks-rancher-alert\n environment: example\n" err="vector contains metrics with the same labelset after applying rule labels" |
排查过程
- 确认对应规则是否存在:
1 | - interval: 3m |
- 检查 helm Chart 的 values 里的
additionalRuleLabels配置:
1 | additionalRuleLabels: |
- 检查历史时序的 label 结构,通过 Prometheus API 检查 30 天内的历史时序,看是否同时存在带
alert_source/environment和不带这些 label 的历史指标。
1 | curl -G 'http://<prometheus-address>:8081/api/v1/series?' \ |
结果中可以看到两类指标:
1 | { |
1 | { |
当 recording rule 再为第二类指标添加固定的 alert_source 和 environment label 后,两类指标会变成完全相同的 labelset,从而触发 Prometheus 的规则计算错误。
问题原因
通过 .Values.defaultRules.additionalRuleLabels 给默认规则追加了固定 label:
1 | alert_source: oks-rancher-alert |
在 30 天窗口内,Prometheus 中同时存在新旧两种 label 策略生成的 code_verb:apiserver_request_total:increase1h 历史时序。recording rule 再套用固定 label 后,产生了多个完全相同 labelset 的时间序列,违反 Prometheus 每个唯一 labelset 只能对应一个时间序列的要求,所以规则计算失败。
这个问题大概率和 Monitoring 规则被重新部署或修改过有关,导致 Prometheus 中保留了旧 label 策略下产生的历史时序。
解决方法
由于已经存在冲突,需要手动清理遗留在 Prometheus TSDB 中的历史时序。清理方法如下:
- 编辑 Apps Monitoring -> Edit Yaml,在如下位置添加参数,开启 Prometheus Admin API:
1 | prometheus: |
该参数将会为 Prometheus 开启 api,等待 Prometheus 重新启动。
- 接着执行如下命令进行清理:
1 | curl -v -X POST 'http://<prometheus-address>:8081/api/v1/admin/tsdb/delete_series' \ |
这里需要注意,delete_series 会删除所有匹配 code_verb:apiserver_request_total:increase1h 的时序,执行前需要确认影响范围。然后观察一下是否恢复正常。