Prometheus 标签体系与 Relabel 重写机制实战指南

目录


1. Prometheus 标签体系核心概念

1.1 标签的作用

Prometheus 将监控数据建模为时间序列,每一条时间序列由「指标名称 + 一组唯一键值对标签」唯一标识。标签是 Prometheus 数据维度的核心载体,核心作用如下:

  • 区分不同监控实例、环境、业务、机房等维度数据

  • 支持 PromQL 灵活过滤、分组、聚合、告警筛选

  • 为 Grafana 面板、告警路由、数据分层提供维度支撑

常见核心维度标签:job(任务名)、instance(实例地址)、environment(环境)、team(归属团队)。

1.2 标签完整分类

Prometheus 标签按来源、生命周期、用途分为四大类,覆盖服务发现、抓取、存储全流程:

标签类型 核心说明 典型示例
目标标签 服务发现/静态配置生成,可通过 relabel 修改,作用于采集目标 jobinstance__scheme__
指标标签 Exporter/业务程序原生携带,属于指标自身维度 cpu=idledevice=eth0
内部临时标签 双下划线前缀,仅 Relabel 阶段可用,不持久化存储 __address____meta_consul_*
自定义业务标签 运维手动定义,用于企业维度标准化管理 env=prodteam=opsos=ubuntu2204

1.3 内部标签(__ 前缀)

内部标签是 Prometheus 在服务发现和抓取过程中自动生成的临时标签,不会持久化到 TSDB。它们提供了关于目标的原始元数据,供 relabel 使用。常见的内部标签:

内部标签 含义
__address__ 目标的主机:端口地址
__scheme__ 抓取协议(http/https)
__metrics_path__ 指标路径(默认 /metrics
__param_<name> URL 查询参数
__meta_<discovery>_<key> 服务发现产生的元数据标签,如 Consul 的 __meta_consul_service

image

1.4 标签两种表现形式

  • 私有临时标签(__前缀)

系统内置元数据标签,仅用于 Relabel 处理阶段,不对外展示、不持久化,用于提取目标属性、实现动态治理。

  • 公有普通标签

最终存入时序数据库的标签,用于数据查询、聚合、告警,支持自定义新增、修改、删除,是业务监控的核心维度。

1.5 Prometheus 数据处理全流程

Prometheus 标签处理分为两个核心阶段,严格区分执行时机,是 Relabel 不生效问题的核心排查依据:

  1. 服务发现:静态/动态(Consul/K8s)发现所有监控 Target

  2. 加载内置标签:自动生成__scheme____address____metrics_path__ 等内部标签

  3. target 级别重写:执行 relabel_configs,修改/过滤采集目标与标签

  4. 发起指标抓取:向目标拉取 metrics 数据

  5. metric 级别重写:执行 metric_relabel_configs,过滤/修改指标数据

  6. 持久化存储:合法时序数据存入 TSDB


2. Relabeling 机制概述

2.1 什么是 Relabeling

Relabeling 是在 Prometheus 抓取目标之前或之后,对标签进行重写、过滤、修改的机制。它基于源标签值和正则表达式,按规则动态生成或删除标签,从而实现目标的选择、标签的标准化和数据的预处理。

2.2 应用时机

  • 抓取前(target relabeling):在 Prometheus 实际发起 HTTP 请求抓取指标之前,对目标标签进行重写。主要用于过滤目标修改抓取地址添加或修改标签

  • 抓取后(metric relabeling):在样本数据抓取完成后、存储前,对每个样本的标签进行重写。主要用于删除高基数标签标准化标签成本控制

2.3 两大配置位置与区别

配置项 执行阶段 操作对象 核心用途
relabel_configs 采集前 监控 Target(实例) 过滤坏实例、标准化实例标签、修改采集地址
metric_relabel_configs 采集后、入库前 Metric 指标数据 丢弃无用指标、清理敏感标签、优化存储

两者语法相同


3. Relabel 配置语法详解

3.1 基本字段

一条 relabel 规则由以下字段组成:

# 完整通用模板
- source_labels: []      # 源标签列表,读取用于匹配/拼接
  separator: ";"        # 多标签拼接分隔符,默认分号
  regex: "(.*)"         # 正则匹配规则,默认匹配全部内容
  target_label: ""      # 目标标签名,用于写入新标签
  replacement: "$1"     # 替换内容,默认捕获组全部值
  action: replace       # 执行动作,默认替换
  modulus: 0            # 仅 hashmod 动作生效

3.2 动作类型

动作 功能 主要字段
replace replacement 替换正则匹配到的内容,并设置到 target_label source_labels, regex, target_label, replacement
keep 仅保留匹配正则的目标 source_labels, regex
drop 丢弃整个采集目标 (target) source_labels, regex
labelmap 对匹配正则的所有标签名进行映射,生成新标签 regex, replacement
labeldrop 只删除该目标下的部分标签 (key) regex
labelkeep 仅保留匹配正则的标签 regex
hashmod 将源标签值哈希后取模,设置到目标标签 source_labels, target_label, modulus
lowercase 将源标签值转为小写 source_labels, target_label
uppercase 将源标签值转为大写 source_labels, target_label

3.3 正则与捕获组

  • 正则表达式采用 RE2 语法,完全匹配。

  • 使用括号 () 捕获子串,在 replacement 中用 $1$2 引用。

  • 若未指定 regex,默认为 (.*),即匹配整个值。


4. relabel_configs实战场景与配置示例

4.1 为targets自定义打标签

  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]
        labels:
          env: prod
          IT_Contact: kyle
          Business_Contact_Primary: kyle

image

4.2 过滤目标(keep / drop)

场景:仅保留健康状态为 passing 的 Consul 服务。

relabel_configs:
  - source_labels: [__meta_consul_health]
    regex: 'passing'
    action: keep

场景:丢弃所有以 10.0.0 开头的目标。

relabel_configs:
  - source_labels: [__address__]
    regex: '10\.0\.0\..*'
    action: drop

4.3 修改或添加标签(replace)

replace读取 source_labels 做输入,输出写入 target_label;source_labels 对应的原始标签不会被修改、删除。

场景:从 __address__ 提取 IP

relabel_configs:
  - source_labels: [__address__]
    regex: "([^:]+):([0-9]+)"
    target_label: ip
    replacement: "$1"
    action: replace

场景:将 __meta_consul_service_address__meta_consul_service_port 拼接为 instance 标签。

relabel_configs:
  - source_labels: [__meta_consul_service_address, __meta_consul_service_port]
    separator: ':'
    target_label: instance
    replacement: '$1'

场景:给所有目标添加固定标签 team=monitoring

relabel_configs:
  # 静态打标签:为本job下所有实例统一写入 team="monitoring"
  # replace动作不配置source_labels时,直接将replacement字面量赋值给target_label
  - target_label: team
    replacement: "monitoring"
    action: replace

场景:使用target_label新增标签。

  relabel_configs:
  - source_labels:
    - job
    target_label: test_jobs

场景:拼接metric地址。

  relabel_configs:
    # 指定正则表达式匹配成功的label进行标签管理的列表
  - source_labels:
    - __scheme__
    - __address__
    - __metrics_path__
    # 表示source_labels对应Label的名称或值进行匹配此处指定的正则表达式。
    # 此处我们对数据进行了分组,后面replacement会是哟合格"${1}"和"$2"进行引用。
    regex: "(http|https)(.*)" 
    # 指定用于连接多个source_labels为一个字符串的分隔符,若不指定,默认为分号";"。
    # 假设源数据如下:
    # 	__address__="10.0.0.31:9100"
    #		__metrics_path__="/metrics"
    #		__scheme__="http"
    # 拼接后操作的结果为: "http10.0.0.31:9100/metrics"
    separator: ""
    # 在进行Label替换的时候,可以将原来的source_labels替换为指定修改后的label。
    # 将来会新加一个标签,标签的名称为"yinzhengjie_prometheus_ep",值为replacement的数据。
    target_label: "metric_url"
    # 替换标签时,将target_label对应的值进行修改成此处的值
    replacement: "${1}://${2}"
    # 对Label或指标进行管理,场景的动作有replace|keep|drop|lablemap|labeldrop等,默认为replace。
    action: replace

4.4 删除标签(labeldrop / labelkeep)

场景:删除所有以 __meta_ 开头的临时标签(虽然它们默认不会存储,但可用于清理)。

relabel_configs:
  - regex: '__meta_.*'
    action: labeldrop

场景:仅保留 jobinstance__address__ 标签。

relabel_configs:
  - regex: '^(job|instance|__address__)$'
    action: labelkeep

4.5 批量重命名标签(labelmap)

场景:将 Consul 元标签 __meta_consul_service_metadata_<key> 映射为普通标签 <key>

relabel_configs:
  # 先硬编码写死 team="monitoring"
  - target_label: team
    replacement: 'monitoring'
    action: replace

  # 再labelmap,如果consul metadata有team,会覆盖掉上面硬编码结果!
  - regex: '__meta_consul_service_metadata_(.*)'
    replacement: '$1'
    action: labelmap

---

👉结果:如果 consul 服务 metadata 定义了 team=ops,最终 team="ops",硬编码失效。

此操作会对所有标签名匹配正则的标签执行:去掉前缀 __meta_consul_service_metadata_,保留剩余部分作为新标签名。

4.6 哈希分片(hashmod)

场景:将多个目标分散到多个 Prometheus 实例进行抓取,避免单实例压力过大。

relabel_configs:
  - source_labels: [__address__]
    modulus: 3
    target_label: __tmp_hash
    action: hashmod
  - source_labels: [__tmp_hash]
    regex: '1'
    action: keep

此配置将目标地址哈希后模 3,只保留余数为 1 的目标,实现分片。

4.7 大小写转换(lowercase / uppercase)

场景:将 environment 标签值统一为小写。

relabel_configs:
  - source_labels: [environment]
    target_label: environment
    action: lowercase

4.8 K8S示例

参考链接:
	https://github.com/prometheus/prometheus/blob/release-2.53/documentation/examples/prometheus-kubernetes.yml
	https://prometheus.io/docs/prometheus/2.53/configuration/configuration/#kubernetes_sd_config
	
	
源代码如下:
[root@prometheus ~]# egrep -v "^.*#|^$" /tmp/prometheus-kubernetes.yml
global:
  keep_dropped_targets: 100
scrape_configs:
  - job_name: "kubernetes-apiservers"
    kubernetes_sd_configs:
      - role: endpoints
    scheme: https
    tls_config:
      ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    authorization:
      credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    relabel_configs:
      - source_labels:
          [
            __meta_kubernetes_namespace,
            __meta_kubernetes_service_name,
            __meta_kubernetes_endpoint_port_name,
          ]
        action: keep
        regex: default;kubernetes;https
  - job_name: "kubernetes-nodes"
    scheme: https
    tls_config:
      ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    authorization:
      credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    kubernetes_sd_configs:
      - role: node
    relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
  - job_name: "kubernetes-cadvisor"
    scheme: https
    metrics_path: /metrics/cadvisor
    tls_config:
      ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    authorization:
      credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    kubernetes_sd_configs:
      - role: node
    relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
  - job_name: "kubernetes-service-endpoints"
    kubernetes_sd_configs:
      - role: endpoints
    relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: service
  - job_name: "kubernetes-services"
    metrics_path: /probe
    params:
      module: [http_2xx]
    kubernetes_sd_configs:
      - role: service
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - target_label: __address__
        replacement: blackbox-exporter.example.com:9115
      - source_labels: [__param_target]
        target_label: instance
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        target_label: namespace
      - source_labels: [__meta_kubernetes_service_name]
        target_label: service
  - job_name: "kubernetes-ingresses"
    metrics_path: /probe
    params:
      module: [http_2xx]
    kubernetes_sd_configs:
      - role: ingress
    relabel_configs:
      - source_labels:
          [
            __meta_kubernetes_ingress_scheme,
            __address__,
            __meta_kubernetes_ingress_path,
          ]
        regex: (.+);(.+);(.+)
        replacement: ${1}://${2}${3}
        target_label: __param_target
      - target_label: __address__
        replacement: blackbox-exporter.example.com:9115
      - source_labels: [__param_target]
        target_label: instance
      - action: labelmap
        regex: __meta_kubernetes_ingress_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        target_label: namespace
      - source_labels: [__meta_kubernetes_ingress_name]
        target_label: ingress
  - job_name: "kubernetes-pods"
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod

5. metric_relabel_configs修改metric标签案例

metric_relabel_configs删除指标

- job_name: "node-exporter"
  static_configs:
    - targets: ["10.0.0.42:9100"]
  metric_relabel_configs:
    - source_labels: [__name__]
      regex: "node_cpu_.*"
      action: drop

image

6. 结合 Consul 服务发现的 Relabel 实战

6.1 Consul 可用元标签

Prometheus 的 Consul 服务发现会为每个目标生成一系列 __meta_consul_* 标签,常用的包括:

元标签 含义
__meta_consul_service 服务名称
__meta_consul_service_id 服务 ID
__meta_consul_service_address 服务地址
__meta_consul_service_port 服务端口
__meta_consul_tags 服务标签列表(逗号分隔)
__meta_consul_health 健康检查状态
__meta_consul_node 节点名称
__meta_consul_dc 数据中心
__meta_consul_service_metadata_<key> 服务元数据

6.2 典型配置解析

scrape_configs:
  - job_name: "consul-node-seriver-discovery"
    # 配置基于consul的服务发现
    consul_sd_configs:
      - server: "127.0.0.1:8500"   # 仅对接本机 Consul Client,无单点故障
        datacenter: "dc1"          # 必须与集群实际 DC 名称严格一致
        refresh_interval: "30s"    # 服务列表刷新间隔,平衡实时性与压力
        services: ["node-exporter"] # 源头仅拉取指定服务,减少无效开销
        allow_stale: true          # 允许非 Leader 返回数据,降低控制面压力
        # 开启 ACL 时使用,凭证文件需严格限制权限
        # token_file: "/etc/prometheus/secrets/consul-token"

    # 标签重写规则
    relabel_configs:
      # 1. 核心过滤:仅保留健康状态为 passing 的实例,故障自动摘流
      - source_labels: [__meta_consul_health]
        regex: "passing"
        action: keep

      # 2. 拼接最终抓取地址:服务IP + 服务端口
      - source_labels: [__meta_consul_service_address, __meta_consul_service_port]
        separator: ":"
        target_label: __address__

      # 3. 映射业务标签:节点名称、数据中心、环境元数据
      - source_labels: [__meta_consul_node]
        target_label: node
      - source_labels: [__meta_consul_datacenter]
        target_label: datacenter

      - regex: '__meta_consul_service_metadata_(.*)'
        replacement: '$1'
        action: labelmap

image

7. 生产常见陷阱与最佳实践

  1. 规则串行执行:Relabel 规则从上至下依次生效,后置规则会覆盖前置规则,静态标签与 labelmap 顺序需严格把控

  2. replace 不删除源标签:replace 仅新增/覆盖目标标签,不会修改源标签,实现替换源标签需同名覆盖或手动删除

  3. 标签大小写敏感:Prometheus 标签严格区分大小写,生产统一使用「小写+下划线」命名规范

  4. meta 与 tags 区分:Consul tags 无法被 labelmap 拆分,业务维度统一使用 meta 字段注册

  5. 层级错误静默失效:metric_relabel_configs 必须与 static_configs 同级,缩进错误无报错、不生效

  6. relabel 阶段限制:relabel_configs 无法获取指标名 name,指标过滤必须使用 metric_relabel_configs

  7. 正则默认值坑点:无手动 regex 时默认 (.*),无捕获组时 $1 为空

  8. 调试技巧:通过 Prometheus /targets 页面查看 relabel 前后标签变化,配合 promtool 校验配置

8. 总结

Prometheus 用 Label 建立多维时间序列,Relabel 则负责在数据生命周期的不同阶段,对这些维度进行筛选、转换、复制、删除和路由。

知识点:

1. Prometheus 时间序列由 metric name + label set 唯一确定。

2. 修改、新增、删除 label 都可能导致新的时间序列。

3. job 通常来自 job_name。

4. instance 在没有被显式设置时,默认来源于 __address__。

5. __meta_* 是 Service Discovery 阶段提供的元数据。

6. __address__ 可以通过 target relabel 修改实际抓取地址。

7. relabel_configs 是抓取之前处理 Target。

8. metric_relabel_configs 是抓取之后、入库之前处理 Samples。

9. alert_relabel_configs 和 write_relabel_configs 分别处理 Alert 和 Remote Write 数据。

10. 标签真正最大的风险是高基数,而不是单纯“标签数量多”。
posted @ 2026-08-23 01:31  kyle_7Qc  阅读(12)  评论(0)    收藏  举报