Prometheus Relabeling 完全指南
Relabeling 是 Prometheus 最强大也最难懂的功能:在抓取前重写目标标签。keep/drop/labelmap/hashmod 各 action 用法、metric_relabel 与 relabel 的区别、实战配置示例。
Relabeling 是 Prometheus 在抓取目标之前对标签进行增删改的机制:筛选要抓的目标、规范标签命名、丢弃高基数指标、按标签分片……它是控制采集行为与基数的核心开关,也是公认的"配置两小时、报错一整天"的重灾区。这篇把它讲明白。
两个容易混淆的配置项
| 配置 | 作用时机 | 操作对象 |
|---|---|---|
relabel_configs |
抓取前 | 目标(target)的标签:决定抓谁、怎么改标签 |
metric_relabel_configs |
抓取后、入库前 | 指标(metric)的标签:决定存哪些指标 |
理解这个区别,80% 的困惑就消失了。
内部标签:以 __ 开头的隐藏维度
服务发现会给每个目标生成一批 __ 前缀的内部标签,relabeling 的主要原料:
__address__:目标地址(如10.0.0.5:9100)__scheme__、__metrics_path__:协议与指标路径__meta_kubernetes_pod_name、__meta_kubernetes_namespace……:K8s 服务发现注入的元信息__name__:指标名(仅metric_relabel_configs阶段可用)
配置结构逐个拆解
relabel_configs:
- source_labels: [__meta_kubernetes_namespace] # 从哪些标签取值
separator: ';' # 多标签拼接符(默认 ;)
regex: 'production|staging' # 对拼接值匹配的正则(默认全匹配锚定)
replacement: '$1' # replace 时的替换模板
target_label: env # 写入哪个标签
action: keep # 动作
七个 action 逐个讲
keep / drop:目标筛选
# 只抓 production 命名空间
- source_labels: [__meta_kubernetes_namespace]
regex: production
action: keep
keep = 不匹配就丢弃;drop = 匹配就丢弃。
replace:改写标签值
# 把 pod 名提取成 instance 标签
- source_labels: [__meta_kubernetes_pod_name]
target_label: instance
regex: '(.*)' # 可省略,默认 (.*)
replacement: '$1'
action: replace # 默认值,可省
labelkeep / labeldrop:按名字整批处理标签
# 丢弃所有 __meta_kubernetes_pod_label_ 开头的标签
- regex: '__meta_kubernetes_pod_label_(.+)'
action: labeldrop
labelmap:批量改名
# 把 __meta_kubernetes_pod_label_app 映射成 app
- regex: '__meta_kubernetes_pod_label_(.+)'
replacement: '$1'
action: labelmap
K8s 监控里把 pod 标签转成指标标签的标准操作。
hashmod:分片(水平扩容)
# 按地址哈希分片:shard 1/2
- source_labels: [__address__]
modulus: 2
target_label: __tmp_hash
action: hashmod
- source_labels: [__tmp_hash]
regex: '0'
action: keep
多副本 Prometheus 各抓一半目标的基础机制(Agent 模式分片也是这个原理)。
keepequal / dropequal、uppercase / lowercase
比较少用:比较两个标签值是否相等决定取舍;大小写转换。
实战配方
K8s 里只抓带注解的 Pod:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
regex: 'true'
action: keep
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __address__]
regex: '(\d+);([^:]+)(:\d+)?'
replacement: '$2:$1'
target_label: __address__
丢弃高基数指标:
metric_relabel_configs:
- source_labels: [__name__]
regex: 'go_gc_.*'
action: drop
调试方法
- Prometheus UI 的 Status → Service Discovery 页面能看到每个目标 relabel 前后的标签——排查"为什么这个目标没被抓"的第一现场;
- 改动后先看这里再去看 Graph。
观测云对照
观测云 DataKit 的标签治理提供了更直观的路径:通过 Pipeline 在入库前对指标/日志做标签的增删改,语法比 relabeling 直白,且支持在线调试;已有的 Prometheus relabel 配置资产可以平滑迁移,数据采集层一次配置全局生效。
常见问题(FAQ)
Q:改完 relabel_configs 没生效?
A:三查:配置真的 reload 了吗(/-/reload 或重启)?Service Discovery 页面里目标标签变了吗?你的正则是不是忘了全匹配锚定(Prometheus 的 regex 默认 ^(?:...)$)?
Q:正则里的 $1 没被替换?
A:replacement 用 $1 引用捕获组;如果你的值里有 $,写成 $$ 转义。
Q:relabel 会影响历史数据吗?
A:不会。relabeling 只作用于之后抓取的数据,已入库的序列保持原样——这也是标签治理要趁早的原因。