7-Prometheus Label 原理与实践

熊 1 阅读 监控平台

1. 标签的作用

标签作用: Prometheus中存储的数据为时间序列 , 是由Metric的名字和一系列的标签(键值对)唯一标识的, 不同的标签代表不同的时间序列 , 即通过指定标签查询指定数据 。

不同的标签代表不同的时间序列 , 即通过指定标签查询指定数据。

指标+标签实现了查询条件的作用 , 可以指定不同的标签过滤不同的数据。

2. Metadata标签

在被监控端纳入普罗米修斯里面定义了一些元数据标签。

在Prometheus所有的Target实例中 , 都包含一些默认的Metadata标签信息。可以通过Prometheus UI的Targets页面中查看这些实例的Metadata标签的内容:

__address__  #当前Target实例的访问地址<host>:<port>
__scheme__  #采集目标服务访问地址的HTTP Scheme , HTTP或者HTTPS
__metrics_path__  #采集目标服务访问地址的访问路径

上面这些标签将会告诉Prometheus如何从该Target实例中获取监控数据。除了这些默认的标签以外 , 我们还可以为Target添加自定义的标签。

image-20240624233346691

在抓取被监控端就会带上这些标签 , 这些标签就是声明要采集谁 , 协议是什么 , 以及暴露的接口是谁

一般来说元标签只是普罗米修斯去使用 , 我们一般不会让其做什么事情 , 并且这些标签是不会写到数据库当中的 , 使用promql是查询不到这些标签的 , 因为这些标签只是普罗米修斯内部去使用的 , 不会存储在时序数据库供我们查询

3. 自定义标签

可以自定义标签 , 有了这些标签可以针对特定的标签去查询 , 比如根据机房 , 或者项目查询某些机器。

添加的标签越多 , 查询的维度越细。

scrape_configs:
  - job_name: "BJ Linux Server"
    static_configs:
      - targets: ["192.168.71.55:9100"]
        labels:
          idc: tongniu
          project: www
  - job_name: "Shanghai Linux Server"
    static_configs:
      - targets: ["192.168.71.56:9100","192.168.71.57:9100"]    
        labels:
          idc: sss
          project: blog
​
image-20240624234905426

可以看到基于自定义标签实现多维度的查询 : node_cpu_seconds_total{job="Shanghai Linux Server",idc="sss",project="blog"}

image-20240624235352659

4. 重新标记标签

重新标记目的: 为了更好的标识监控指标。

在两个阶段可以重新标记:

relabel_configs #在采集之前(比如在采集之前重新定义元标签)
metric_relabel_configs #在存储之前准备抓取指标数据时, 可以使用relabel_configs添加一些标签、也可以只采集特定目标或过滤目标。 已经抓取到指标数据时, 可以使用metric_relabel_configs做最后的重新标记和过滤。
prometheus-relabels-1

重新标记标签一般用途

  • 动态生成新标签 根据已有的标签生成新标签

  • 过滤采集的Target

  • 删除不需要或者敏感标签

  • 添加新标签

4.1 action:重新标记标签动作

  • replace:默认, 通过regex匹配source_label的值, 使用replacement来引用表达式匹配的分组, 分组使用2...引用(正则匹配, 提取字段重新创建新标签, 注意这里是创建新的标签)。

  • keep:删除regex与连接不匹配的目标 source_labels , keep drop就是让普罗米修斯采集和不采集哪些目标

  • drop:删除regex与连接匹配的目标 source_labels

  • labeldrop:删除regex匹配的标签

  • labelkeep:删除regex不匹配的标签

  • labelmap:匹配regex所有标签名称, 并将捕获的内容分组, 用第一个分组内容作为新的标签名(使用正则提取出多个字段, 使用匹配到的作为新标签名, 但是标签的内容不会改变, 相对于对原有标签换了个名字)。

4.2 重新标记标签:重命名标签

场景1:动态生成添加标签(对已有的标签重新标记)

- job_name: 'Linux Server'
  basic_auth:
    username: prometheus
    password: 123456
  static_configs:
  - targets: ['192.168.179.99:9100']
  metric_relabel_configs:
  - action: replace
    source_labels: ["instance"]
    regex: (.*):([0-9]+)  # 正则匹配标签值, ( )分组
    replacement: $1       # 引用分组匹配的内容
    target_label: "ip"

可以看到该标签已经进入数据库里面了, 这样就根据源标签通过正则匹配动态生成了新的标签。

node_cpu_seconds_total{job="BJ Linux Server"}

image-20240625004217247

4.3 重新标记标签: 过滤Target

场景2:选择采集的目标

- job_name: 'Linux Server'
  basic_auth:
    username: prometheus
    password: 123456
  static_configs:
  - targets: ['192.168.179.99:9100']
  relabel_configs:
  - action: drop
    regex: "192.168.179.99:9100"   # 正则匹配标签值
    source_labels: ["_address_"]

在target里面就没有了, 在普罗米修斯里面就看不到该台机器, 同时exporter也不会被停止, 这样就完成过滤目标需求。

4.4 重新标记标签:删除标签

有些标签不希望被存储上, 那么可以使用 labeldrop:删除regex匹配的标签去完成不需要入库 将里面的标签删除掉, 在入库之前删除。

- job_name: 'Linux Server'
  basic_auth:
    username: prometheus
    password: 123456
  static_configs:
  - targets: ['192.168.179.99:9100']
  relabel_configs:
  - action: labeldrop
    regex: "job"   #正则匹配标签名称

可以看到job标签被删除。

image-20240625005109827

5. 总结

标签的作用

  • 可以基于已有的标签, 生成一个标签

  • 也可以创建新的标签

  • 还可以过滤标签, 不想采集哪些

  • 哪些标签不要了也可以将其删除

5.1 keep

Keep只有匹配的才会去采集数据, 不匹配的就不采集。下面意思就是pod当中有些注解中声明了prometheus_io_scrape这个字段, 那么就会把你纳入监控, 如果没有声明就不会纳入监控。也就是k8s当中部署了这么多pod, 谁要监控, 谁不要被监控, 在部署service可以指定是否需要采集, 如果需要采集需要在注解当中声明prometheus_io_scrape: true。

在service 和pod里面声明配置注解, 那么就会采集注解里面含有这个值的

annotations:  prometheus.io/scrape: 'true'
# Service没配置注解prometheus.io/scrape的不采集
      - action: keep
        regex: true
        source_labels:
        - __meta_kubernetes_service_annotation_prometheus_io_scrape

5.2 replace

处理监控pod连接的ip地址, api接口, 还有协议都需要重新标记默认的字段。

# 重命名采集目标协议
      - action: replace
        regex: (https?)
        source_labels:
        - __meta_kubernetes_service_annotation_prometheus_io_scheme
        target_label: __scheme__
      # 重命名采集目标指标URL路径
      - action: replace
        regex: (.+)
        source_labels:
        - __meta_kubernetes_service_annotation_prometheus_io_path
        target_label: __metrics_path__
      # 重命名采集目标地址
      - action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        source_labels:
        - __address__
        - __meta_kubernetes_service_annotation_prometheus_io_port
        target_label: __address__

这里就可以使用新的标签kubernetes_namespace在promql里面基于命名空间这个标签去查询了, 因为__meta_kubernetes_namespace这个标签是不会被存储的。

 # 生成命名空间标签
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: kubernetes_namespace

实际访问指标接口 https://NodeIP:10250/metrics/cadvisor 这个接口只能APISERVER访问, 故此重新标记标签使用APISERVER代理访问。

这个就是直接指定标签的值, 也就是将采集的地址换为我指定的地址。

 # 修改NodeIP:10250为APIServerIP:6443
    - action: replace
      regex: (.*)
      source_labels: ["__address__"]  源标签配匹为address
      target_label: __address__
      replacement: 192.168.31.61:6443

5.3 labelmap

做上面这些事情是有两个阶段的, 一个是采集之前, 一个是采集之后, 如果在采集之前重新定义标签没生效, 那么可以使用采集之后的标签(因为使用的是k8s的服务发现, 不管用的是哪个服务发现, 默认带的都是源标签__meta_kubernetes_node_label 比如consul那么就是以consul开头的, 这些不同服务发现的标签就是为了新标签的生成, 就是为了更加好的标识监控指标, 源标签是不会入库的)。

  relabel_configs:
    # 将标签(.*)作为新标签名, 原有值不变(新的标签名字会被入库查询)
    - action: labelmap
      regex: __meta_kubernetes_node_label_(.*) 

(.*) , 以其开头所有值匹配到, 用这个匹配的值作为新的标签名字, 新的标签名字就可以入库, 就会被查询, 因为元标签以下划线开头的是不会入库的, 后面是用不了的/这样做的目的就是将后面(.*)匹配的值作为一个新标签, 并且将原有值赋予新标签, 后面可以基于这个新标签查询数据了


参考链接

构建企业级监控平台系列(十七): Prometheus Label 原理与实践 (qq.com)