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. 确认对应规则是否存在:
1
2
3
4
5
6
7
8
- interval: 3m
name: kube-apiserver-availability.rules
rules:
- expr: avg_over_time(code_verb:apiserver_request_total:increase1h[30d]) * 24 * 30
labels:
alert_source: oks-rancher-alert
environment: example
record: code_verb:apiserver_request_total:increase30d
  1. 检查 helm Chart 的 values 里的 additionalRuleLabels 配置:
1
2
3
additionalRuleLabels:
alert_source: "oks-rancher-alert"
environment: "example"
  1. 检查历史时序的 label 结构,通过 Prometheus API 检查 30 天内的历史时序,看是否同时存在带 alert_source/environment 和不带这些 label 的历史指标。
1
2
3
4
curl -G 'http://<prometheus-address>:8081/api/v1/series?' \
--data-urlencode 'match[]=code_verb:apiserver_request_total:increase1h' \
--data-urlencode 'start='$(date -d "30 days ago" +%s) \
--data-urlencode 'end='$(date +%s)

结果中可以看到两类指标:

1
2
3
4
5
6
7
{
"__name__": "code_verb:apiserver_request_total:increase1h",
"alert_source": "oks-rancher-alert",
"code": "200",
"environment": "example",
"verb": "DELETE"
}
1
2
3
4
5
{
"__name__": "code_verb:apiserver_request_total:increase1h",
"code": "200",
"verb": "DELETE"
}

当 recording rule 再为第二类指标添加固定的 alert_sourceenvironment label 后,两类指标会变成完全相同的 labelset,从而触发 Prometheus 的规则计算错误。

问题原因

通过 .Values.defaultRules.additionalRuleLabels 给默认规则追加了固定 label:

1
2
alert_source: oks-rancher-alert
environment: example

在 30 天窗口内,Prometheus 中同时存在新旧两种 label 策略生成的 code_verb:apiserver_request_total:increase1h 历史时序。recording rule 再套用固定 label 后,产生了多个完全相同 labelset 的时间序列,违反 Prometheus 每个唯一 labelset 只能对应一个时间序列的要求,所以规则计算失败。

这个问题大概率和 Monitoring 规则被重新部署或修改过有关,导致 Prometheus 中保留了旧 label 策略下产生的历史时序。

解决方法

由于已经存在冲突,需要手动清理遗留在 Prometheus TSDB 中的历史时序。清理方法如下:

  1. 编辑 Apps Monitoring -> Edit Yaml,在如下位置添加参数,开启 Prometheus Admin API:
1
2
3
4
prometheus:
prometheusSpec:
additionalArgs:
- name: web.enable-admin-api

该参数将会为 Prometheus 开启 api,等待 Prometheus 重新启动。

  1. 接着执行如下命令进行清理:
1
2
3
4
curl -v -X POST 'http://<prometheus-address>:8081/api/v1/admin/tsdb/delete_series' \
-d 'match[]=code_verb:apiserver_request_total:increase1h'

curl -X POST 'http://<prometheus-address>:8081/api/v1/admin/tsdb/clean_tombstones'

这里需要注意,delete_series 会删除所有匹配 code_verb:apiserver_request_total:increase1h 的时序,执行前需要确认影响范围。然后观察一下是否恢复正常。