完整的采集神器(UI服务发现与Relabelling的机制与范例(一)- )
优采云 发布时间: 2021-11-08 11:02完整的采集神器(UI服务发现与Relabelling的机制与范例(一)-
)
本章解释了服务发现和重新标记的机制和示例。
通过服务发现,我们可以在不重启Prometheus服务的情况下动态发现需要监控的Target实例信息。
如上图所示,对于在线环境,我们可能分为不同的集群:dev、stage、prod。每个集群运行多个主机节点,每个服务器节点运行一个节点导出器实例。Node Exporter 实例会自动注册到Consul 中,Prometheus 根据Consul 返回的Node Exporter 实例信息动态维护Target 列表,并轮询这些Target 以获取监控数据。
但是,如果我们可能还需要:
面对这些场景的需求,我们其实是希望 Prometheus Server 能够根据一定的规则(比如标签)从服务发现注册返回的 Target 实例中选择性地采集 某些 Exporter 实例监控数据。
接下来,我们将实验如何通过 Prometheus 强大的 Relabel 机制来实现这些具体目标。
Prometheus 的 Relabeling 机制
Prometheus 的所有 Target 实例都收录一些默认的 Metadata 标签信息。您可以在 Prometheus UI 的 Targets 页面中查看这些实例的 Metadata 标签的内容:
默认情况下,当 Prometheus 完成加载 Target 实例时,这些 Target 将收录一些默认标签:
上面的标签会告诉 Prometheus 如何从 Target 实例中获取监控数据。除了这些默认标签,我们还可以为 Target 添加自定义标签。例如,在“基于文件的服务发现”部分的示例中,我们通过 JSON 配置文件向 Target 实例添加了自定义标签 env。如下图,标签最终会保存在来自这个实例采集的样本数据中:
node_cpu{cpu="cpu0",env="prod",instance="localhost:9100",job="node",mode="idle"}
一般来说,系统内部使用的是带有__前面标签的Target,所以这些标签不会被写入到样本数据中。但是,也有一些例外。例如,我们会发现所有通过 Prometheus采集 传递的样本数据都会收录一个名为 instance 的标签,标签的内容对应 Target 实例的 __address__ 。事实上,这里已经发生了一个标签重写的过程。
这种重写Target实例标签的机制发生在采集样本数据之前,在Prometheus中称为Relabeling。
Prometheus 允许用户通过 采集 任务设置中的 relabel_configs 添加自定义 Relabeling 过程。
使用 replace/labelmap 重写标签
Relabeling最基本的应用场景是根据Target实例中收录的元数据标签动态添加或覆盖标签。例如,一个通过 Consul 动态发现的服务实例,也会收录以下 Metadata 标签信息:
默认情况下,来自 Node Exporter 实例 采集 的示例数据如下:
node_cpu{cpu="cpu0",instance="localhost:9100",job="node",mode="idle"} 93970.8203125
我们希望有一个额外的标签 dc 可以指示样本所属的数据中心:
node_cpu{cpu="cpu0",instance="localhost:9100",job="node",mode="idle", dc="dc1"} 93970.8203125
每个采集任务的配置中可以添加多个relabel_config配置。最简单的relabel配置如下:
scrape_configs:
- job_name: node_exporter
consul_sd_configs:
- server: localhost:8500
services:
- node_exporter
relabel_configs:
- source_labels: ["__meta_consul_dc"]
target_label: "dc"
采集任务通过Consul动态发现Node Exporter实例信息作为监控采集的目标。上一节我们知道通过Consul动态发现的监控Target会收录一些额外的Metadata标签,比如__meta_consul_dc标签表示当前实例所在的Consul数据中心,所以我们希望从这些采集 instance to 的监控样本也可以收录这样的标签,例如:
node_cpu{cpu="cpu0",dc="dc1",instance="172.21.0.6:9100",job="consul_sd",mode="guest"}
这样就可以方便的根据dc标签的值,根据不同的数据中心汇总分析各自的数据。
在本例中,通过从 Target 实例中获取 __meta_consul_dc 的值,并重写从该实例中获取的所有样本。
完整的relabel_config配置如下:
# The source labels select values from existing labels. Their content is concatenated
# using the configured separator and matched against the configured regular expression
# for the replace, keep, and drop actions.
[ source_labels: '[' [, ...] ']' ]
# Separator placed between concatenated source label values.
[ separator: | default = ; ]
# Label to which the resulting value is written in a replace action.
# It is mandatory for replace actions. Regex capture groups are available.
[ target_label: ]
# Regular expression against which the extracted value is matched.
[ regex: | default = (.*) ]
# Modulus to take of the hash of the source label values.
[ modulus: ]
# Replacement value against which a regex replace is performed if the
# regular expression matches. Regex capture groups are available.
[ replacement: | default = $1 ]
# Action to perform based on regex matching.
[ action: | default = replace ]
action定义了当前relabel_config如何处理Metadata标签,默认的action行为是replace。替换行为会根据regex的配置匹配source_labels标签的值(多个source_labels的值会按照分隔符拼接),并将匹配的值写入target_label。如果有多个匹配的组,可以使用${1},${2}确定要写入的内容。如果没有匹配,则 target_label 将不会更新。
repalce 操作允许用户根据 Target 的 Metadata 标签重写或编写新的标签键值对。在多环境场景下,可以帮助用户添加环境相关的特征维度,让数据更好的聚合。
除了使用replace,还可以将action的配置定义为labelmap。与replace不同,labelmap会根据regex的定义匹配Target实例的所有标签的名称,并将匹配的内容作为新标签名称,其值作为新标签的值。
比如在监控Kubernetes下的所有主机节点时,要将这些节点上定义的标签写入样本,可以使用如下relabel_config配置:
- job_name: 'kubernetes-nodes'
kubernetes_sd_configs:
- role: node
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
使用labelkeep或labeldrop,可以过滤Target标签,只保留满足过滤条件的标签,例如:
relabel_configs:
- regex: label_should_drop_(.+)
action: labeldrop
此配置将使用正则表达式匹配当前 Target 实例的所有标签,并将符合 regex 规则的标签从 Target 实例中移除。labelkeep 正好相反,它将删除所有与正则表达式定义不匹配的标签。
使用 keep/drop 过滤 Target 实例
上篇我们介绍了Prometheus的Relabeling机制,使用replace/labelmap/labelkeep/labeldrop来管理标签。本节开头提到的第二个问题是,当使用集中式服务发现注册中心时,环境中的所有导出器实例都会在服务发现注册中心注册。不同职能(开发、测试、运维)的人可能只关心部分监控数据。他们可能会部署自己的 Prometheus Server 来监控他们关心的指标数据。如果让这些 Prometheus Servers采集 显然,所有环境下的所有 Exporter 数据都会有很大的资源浪费。如何让这些不同的 Prometheus Server采集 各自关注?答案是重新标记。除了默认的replace,relabel_config的action还支持keep/drop行为。比如我们只想要采集数据中心dc1中Node Exporter实例的样本数据,那么可以使用如下配置:
scrape_configs:
- job_name: node_exporter
consul_sd_configs:
- server: localhost:8500
services:
- node_exporter
relabel_configs:
- source_labels: ["__meta_consul_dc"]
regex: "dc1"
action: keep
当action设置为keep时,Prometheus会丢弃source_labels值中与regex正则表达式内容不匹配的Target实例,当action设置为drop时,它会丢弃那些source_labels值匹配的Target实例正则表达式的内容。实例。可以简单的理解为keep用于选择,drop用于排除。
使用hashmod计算source_labels的hash值
当 relabel_config 设置为 hashmod 时,Prometheus 将使用模值作为系数来计算 source_labels 值的哈希值。例如:
scrape_configs
- job_name: 'file_ds'
relabel_configs:
- source_labels: [__address__]
modulus: 4
target_label: tmp_hash
action: hashmod
file_sd_configs:
- files:
- targets.json
根据当前Target实例__address__的值,系数为4,这样每个Target实例都会收录一个新的标签tmp_hash,取值范围在1到4之间。 查看Target实例的标签信息,可以看到结果如下,每个 Target 实例都收录一个新的 tmp_hash 值:
利用Hashmod的能力在Target实例层面实现采集任务的功能分区:
scrape_configs:
- job_name: some_job
relabel_configs:
- source_labels: [__address__]
modulus: 4
target_label: __tmp_hash
action: hashmod
- source_labels: [__tmp_hash]
regex: ^1$
action: keep
这里需要注意的是,如果relabel操作只是生成一个临时变量作为下一次relabel操作的输入,那么我们可以使用__tmp作为标签名称的前缀,前缀定义的标签不会被写入到目标或 采集 到样本的标签。