[[426218]]
Relabeling 重新标记是标记配置 Prometheus 元信息的方式,它是重新转换和过滤 Prometheus 中 label 标签对象的核心,本文我们将了解 Relabeling 规则的标记工作原理以及在不同场景中的应用方式。
Prometheus 发现、重新抓取和处理不同类型的标记 label 标签对象,根据标签值操作或过滤这些对象非常有用,重新比如:
Relabeling 是作为一系列转换步骤实现的,我们可以在 Prometheus 的标记配置文件中应用这些步骤来过滤或修改标记对象,我们可以对一下类型的重新标记对象应用 Relabeling 操作:
所有这些 relabeling 配置块都是相同类型的 relabel_config,每个配置块都由一个规则列表组成,标记这些规则依次应用于每个标记的重新对象。
例如,一个 relabeling 规则可以根据正则表达式的匹配来保留或丢弃一个对象,可以修改其标签,也可以将一整组标签映射到另一组。一旦一个 relabeling 步骤决定放弃一个有标签的对象,就不会对这个对象执行进一步的 relabeling 步骤,它将从输出列表中删除。
以双下划线__开头的标签属于特殊的标签,它们在重新标记后会被删除。标记对象的来源最初可以附加这些隐藏的标签,以提供关于标记对象的额外元数据,这些特殊的标签可以在 relabeling 阶段被用来对对象的标签进行修改。
对于抓取指标,其中就包含一些隐藏的标签,可以用来控制目标应该如何被抓取。
上面的这些标签都可以使用 relabeling 规则来设置或覆盖,这样就可以为抓取目标进行自定义抓取行为。
此外,服务发现机制也可以提供一组以 __meta_ 开头的标签,包含关于目标的特定发现元数据。例如,当发现 Kubernetes 集群中的 pod 时,Kubernetes 服务发现引擎将为每个 pod 目标提供一个 __meta_kubernetes_pod_name 的标签,包含被发现的 pod 的名字,以及一个 __meta_kubernetes_pod_ready 标签,表明 pod 是否处于就绪状态,关于服务发现生成的元标签可以查看官方文档 https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config 了解更多。
如果一个 relabeling 步骤需要将一个值保存到一个临时标签中(以便在随后的步骤中处理),那么我们可以使用 __tmp 标签名称前缀进行标记,以 __tmp 开通的标签是不会被 Prometheus 本身使用的。
Relabeling 规则主要由以下的一些配置属性组成,但对于每种类型的操作,只使用这些字段的一个子集。
Relabeling 的一个常见操作就是设置或者覆盖一个标签的值,我们可以通过 replace 这个操作来完成,如果没有指定 action 字段,则默认就是 replace。
一个 replace 动作的规则配置方式如下所示:
- action: replace
- source_labels: [<source label name list>]
- separator: <source labels separator> # 默认为 ';'
- regex: <regular expression> # 默认为 '(.*)' (匹配任何值))
- replacement: <replacement string> # 默认为 '$1' (使用第一个捕获组作为 replacement)
- target_label: <target label>
该操作按顺序执行以下步骤:
下面我们来简单看一看 replace 操作的示例。
最简单的 replace 例子就是将一个标签设置为一个固定的值,比如你可以把 env 标签设置为 production:
- action: replace
- replacement: production
- target_label: env
这里我们并没有设置规则的大部分属性,这是因为大部分的默认值已经可以满足这里的需求了,这里会将替换的字符串 production 作为 target_label 标签 env 的新值存储起来,也就是将 env 标签的值设置为 production。
另一个稍微复杂的示例是重写一个被抓取任务实例的端口,我们可以用一个固定的 80 端口来替换 __address__ 标签的端口:
- action: replace
- source_labels: [__address__]
- regex: ([^:]+)(?::\d+)? # 第一个捕获组匹配的是 host,第二个匹配的是 port 端口。
- replacement: "$1:80"
- target_label: __address__
这里我们替换的源标签为 __address__,然后通过正则表达式 ([^:]+)(?::\d+)? 进行匹配,这里有两个捕获组,第一个匹配的是 host(,第二个匹配的是端口2),所以在 replacement 字符串中我们保留第一个捕获组 $1,然后将端口更改为 80,这样就可以将 __address__ 的实例端口更改为 80 端口,然后重新写会 __address__ 这个目标标签。
Relabeling 另一个常见的用例就是过滤有标签的对象,keep 或 drop 这两个动作可以来完成,使用这两个操作,可以帮助我们完成如下的一些操作:
一个 keep 动作的配置规则如下所示:
- action: keep
- source_labels: [<source label name list>]
- separator: <source labels separator> # 默认为 ';'
- regex: <regular expression> # 默认为 '(.*)' (匹配任何值)
keep 操作同样按顺序执行如下步骤:
drop 动作和 keep 类似,只是它是删除一个对象而不是保留。
同样接下来看一看 keep 和 drop 的示例。
在服务发现的时候,我们可能只想抓取那些具有特定元数据标签的目标,例如,下面的配置让我们只抓取 Kubernetes 中具有 example.io/should_be_scraped=true 这个 annotation 的目标。
- action: keep
- source_labels:
- [__meta_kubernetes_service_annotation_example_io_should_be_scraped]
- regex: true
Kubernetes 服务发现机制下面会将 labels 标签与 annotation 作为元信息输出到 Prometheus,这些元信息都包含 __meta_ 前缀,这里我们的配置就是保留具有 example.io/should_be_scraped 这个 annotation 标签,且值为 true 的目标。
当使用 metric_relabel_configs 来控制目标的抓取方式时,我们可以使用下面的规则来只存储指标名称以 api_ 或 http_ 开头的指标。
- action: keep
- source_labels: [__name__]
- regex: "(api_|http_).*"
有时我们可能想把源标签的值映射到一组新的标签中去,这个时候就可以使用 labelmap 这个动作了。labelmap 最常用的使用场景就是从服务发现中获取一组隐藏的或临时的元数据标签,并将它们映射到新的目标标签中。
labelmap 动作的配置规则如下所示:
- action: labelmap
- regex: <regular expression> # 默认为 '(.*)'
- replacement: <replacement string> # 默认为 '$1'
和前面的一些 action 不同,labelmap 是对标签名而不是标签值进行重新匹配和操作。labelmap 按顺序执行以下步骤:
下面我们看一个使用 labelmap 映射 Kubernetes Service 标签的示例。当使用基于 Kubernetes 的服务发现来发现 pod 端点时,我们可能希望每个端点的最终目标标签也包含 Kubernetes Service 标签,这样可以更好的区分端点数据。Kubernetes 服务发现机制会将这些标签添加到 Prometheus 中去,标签名称格式为 __meta_kubernetes_service_label_
- action: labelmap
- regex: __meta_kubernetes_service_label_(.+)
- replacement: "k8s_$1"
通过上面的 labelmap 操作,regex 正则表达式中匹配标签名,然后将标签名对应的值复制到 k8s_$1 的新标签中,$1 就是匹配的标签名这个捕获组。
有的时候我们也有保留或删除一些标签的需求,比如有的目标在时间序列上提供了许多额外的标签,这些标签用途不大,这个时候我们就可以使用 labelkeep 和 labeldrop 这两个操作,使用这两个操作可以有选择地保留或删除一些标签。
labelkeep 的配置规则如下所示:
- action: labelkeep
- regex: <regular expression> # 默认为'(.*)'
一样 labelkeep 按顺序执行下面的步骤:
labeldrop 与 labelkeep 类似,只是它是删除那些匹配正则表达式的标签而不是保留。
下面我们看一看 labelkeep/labeldrop 操作的简单示例。
当运行两个相同的 Prometheus 作高可用的时候,通常两个服务器都被配置为有一个外部标签(通过全局配置选项 external_labels),表明它们代表哪个副本,例如:replica: A 和 replica: B,在从两个副本向同一个 Alertmanager 实例发送报警之前,Prometheus 需要删除这个副本标签,这样 Alertmanager 就不会把收到的报警看成不同的报警了,否则可能我们会收到两个同样的报警通知。这个时候我们就可以使用 labeldrop 来实现这个操作。
- action: labeldrop
- regex: replica
这条配置规则很简单的,就是匹配 replica 这个标签,然后执行 labeldrop 删除标签动作即可。
有的时候我们抓取的指标在每个时间序列上都附加了一些额外的标签,这些标签对于我们来说用处不大,还会增加 Prometheus 的存储压力,所以我们可以想办法删除不需要的额外标签。
比如现在我们想要删除一 info_ 开头的标签,我们可以使用下面的配置规则来完成。
- action: labeldrop
- regex: info_.*
同样也只是配置一个要删除的目标标签的正则表达式即可,只要匹配了的标签都会执行 labeldrop 操作将该标签进行删除。
在一些场景下我们可能需要运行多个几乎相同的 Prometheus 副本来横向扩展,每个副本只抓取部分目标,这样可以降低 Prometheus 的压力,在这种情况下 hashmod 操作有助于我们对目标进行分片操作。
hashmod 的配置规则如下所示:
- action: hashmod
- source_labels: [<source label name list>]
- modulus: <modulus value>
- target_label: <target label>
该操作按顺序执行下面的步骤:
将上一步的模数值存储在 target_label 目标标签中
使用 hashmod 的主要场景是将一个服务的整体目标进行分片,用于水平扩展 Prometheus,通过首先根据每个目标的一个或多个标签计算基于哈希的模数来实现的,然后只保留具有特定输出模数值的目标。比如为了根据 instance 标签对目标进行分片,只保留分片 2 的实例,我们可以把 hashmod 和 keep 结合起来操作。
- - action: hashmod
- source_labels: [instance]
- modulus: 10
- target_label: __tmp_hashmod
- - action: keep
- source_labels: [__tmp_hashmod]
- regex: 2
首先通过 hashmod 操作对 instance 标签进去哈希操作,将取模后的值存储在临时标签 __tmp_hashmod 中,然后通过第二个 keep 操作,只保留分片数为 2 的指标,这样就达到了分片的目的。
到这里我们基本上就了解了 relabeling 的使用,后续我们可以再去了解服务发现在 Prometheus 中的使用。
责任编辑:姜华 来源: k8s技术圈 prometheus监控远端服务
(责任编辑:时尚)
美尚生态(300495.SZ):控股股东解除质押及质押2894万股 占其所持股份比例14.39%
8.2K星标“程序员考公指南”登顶GitHub,创建者坦言:告别996,真香!
喜提200万美金!雷军百万美金重奖工程师,秒充与隐私保护团队获大奖
中盈盛达融资担保(01543.HK)完成发行2.60亿元公司债 票面利率为4.60%
中国版波士顿动力!Science 子刊封面:机器狗「绝影」陌生环境中摸爬滚打