本章节讲解服务发现与Relabelling的机制与范例。

通过服务发现的方式,我们可以在不重启Prometheus服务的情况下动态的发现需要监控的Target实例信息。

如上图所示,对于线上环境我们可能会划分为:dev, stage, prod不同的集群。每一个集群运行多个主机节点,每个服务器节点上运行一个Node Exporter实例。Node Exporter实例会自动注册到Consul中,而Prometheus则根据Consul返回的Node Exporter实例信息动态的维护Target列表,从而向这些Target轮询监控数据。

然而,如果我们可能还需要:

  • 按照不同的环境dev, stage, prod聚合监控数据?
  • 对于研发团队而言,我可能只关心dev环境的监控数据,如何处理?
  • 如果为每一个团队单独搭建一个Prometheus Server。那么如何让不同团队的Prometheus Server采集不同的环境监控数据?

面对以上这些场景下的需求时,我们实际上是希望Prometheus Server能够按照某些规则(比如标签)从服务发现注册中心返回的Target实例中有选择性的采集某些Exporter实例的监控数据。

接下来,我们实验如何通过Prometheus强大的Relabel机制来实现以上这些具体的目标。

Prometheus的Relabeling机制

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

默认情况下,当Prometheus加载Target实例完成后,这些Target时候都会包含一些默认的标签:

  • __address__:当前Target实例的访问地址<host>:<port>
  • __scheme__:采集目标服务访问地址的HTTP Scheme,HTTP或者HTTPS
  • __metrics_path__:采集目标服务访问地址的访问路径
  • __param_<name>:采集任务目标服务的中包含的请求参数

上面这些标签将会告诉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实例中包含的metadata标签,动态的添加或者覆盖标签。例如,通过Consul动态发现的服务实例还会包含以下Metadata标签信息:

  • __meta_consul_address:consul地址
  • __meta_consul_dc:consul服务所在的数据中心
  • __meta_consulmetadata:服务的metadata
  • __meta_consul_node:consul服务node节点的信息
  • __meta_consul_service_address:服务访问地址
  • __meta_consul_service_id:服务ID
  • __meta_consul_service_port:服务端口
  • __meta_consul_service:服务名称
  • __meta_consul_tags:服务包含的标签信息

在默认情况下,从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数据中心,因此我们希望从这些实例中采集到的监控样本中也可以包含这样一个标签,例如:

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: '[' <labelname> [, ...] ']' ] # Separator placed between concatenated source label values.
[ separator: <string> | 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: <labelname> ] # Regular expression against which the extracted value is matched.
[ regex: <regex> | default = (.*) ] # Modulus to take of the hash of the source label values.
[ modulus: <uint64> ] # Replacement value against which a regex replace is performed if the
# regular expression matches. Regex capture groups are available.
[ replacement: <string> | default = $1 ] # Action to perform based on regex matching.
[ action: <relabel_action> | default = replace ]

其中action定义了当前relabel_config对Metadata标签的处理方式,默认的action行为为replace。 replace行为会根据regex的配置匹配source_labels标签的值(多个source_label的值会按照separator进行拼接),并且将匹配到的值写入到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

该配置会使用regex匹配当前Target实例的所有标签,并将符合regex规则的标签从Target实例中移除。labelkeep正好相反,会移除那些不匹配regex定义的所有标签。

使用keep/drop过滤Target实例

在上一部分中我们介绍了Prometheus的Relabeling机制,并且使用了replace/labelmap/labelkeep/labeldrop对标签进行管理。而本节开头还提到过第二个问题,使用中心化的服务发现注册中心时,所有环境的Exporter实例都会注册到该服务发现注册中心中。而不同职能(开发、测试、运维)的人员可能只关心其中一部分的监控数据,他们可能各自部署的自己的Prometheus Server用于监控自己关心的指标数据,如果让这些Prometheus Server采集所有环境中的所有Exporter数据显然会存在大量的资源浪费。如何让这些不同的Prometheus Server采集各自关心的内容?答案还是Relabeling,relabel_config的action除了默认的replace以外,还支持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的值匹配到regex正则表达式内容的Target实例。可以简单理解为keep用于选择,而drop用于排除。

使用hashmod计算source_labels的Hash值

当relabel_config设置为hashmod时,Prometheus会根据modulus的值作为系数,计算source_labels值的hash值。例如:

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 作为标签名的前缀,通过该前缀定义的标签就不会写入到Target或者采集到的样本的标签中。

Prometheus监控神器-服务发现篇(二)的更多相关文章

  1. spring cloud+dotnet core搭建微服务架构:服务发现(二)

    前言 上篇文章实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A调用服务B,那么服务A访问的是服务B的负载均衡地址,通过负载均衡来指向到服务B的真实地址,上篇文章已经说了这 ...

  2. spring cloud+.net core搭建微服务架构:服务发现(二)

    前言 上篇文章实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A调用服务B,那么服务A访问的是服务B的负载均衡地址,通过负载均衡来指向到服务B的真实地址,上篇文章已经说了这 ...

  3. Prometheus监控系统之入门篇(一)续

    在上篇Prometheus监控系统之入门篇(一)中我们讲解了Prometheus的基本架构和工作流程, 并从0到1搭建了Prometheus服务,pushgateway以及告警系统. 本篇我们主要介绍 ...

  4. Prometheus监控神器-Alertmanager篇(1)

    本章节主要涵盖了Alertmanager的工作机制与配置文件的比较详细的知识内容,由浅入深的给大家讲解. 警报一直是整个监控系统中的重要组成部分,Prometheus监控系统中,采集与警报是分离的.警 ...

  5. Prometheus监控神器-Rules篇

    本章主要对如何使用Prometheus与Alertmanager组件集成配置,以及对警报规则 Rules 的俩种类型及其模板内容进行讲解. 与Alertmanager集成 Prometheus把产生的 ...

  6. prometheus监控golang服务实践

    一.prometheus基本原理介绍 prometheus是基于metric采样的监控,可以自定义监控指标,如:服务每秒请求数.请求失败数.请求执行时间等,每经过一个时间间隔,数据都会从运行的服务中流 ...

  7. SpringCloud接入EDAS——服务发现篇

    旁白 很久没有写技术文章了,最近不是写水文就是写小说.说到底,还是最近很少研究技术的缘故,已经到了江郎才尽的地步了. 不过,LZ无意间看到自己团队的小伙伴写的一些文章,觉得还是不错的,于是便动了心思, ...

  8. Prometheus监控系统之入门篇(一)

    1. 简介 Prometheus: (简称Prom)是由SoundCloud开发的开源监控报警系统.是大名鼎鼎的CNCF云原生基金会下的第二大开源项目.具有如下特点: 使用Go语言开发 内置时序数据库 ...

  9. 使用Prometheus监控Golang服务-基于YoyoGo框架

    Prometheus Prometheus是一个非常棒的工具,结合grafana能够让我在不写代码,或者少写代码的情况下搭建一套有效的监控体系.这里介绍一下Prometheus监控golang程序的方 ...

随机推荐

  1. 041_go语言中的panic

    代码演示: package main import "os" func main() { // panic("a problem") _, err := os. ...

  2. JavaScript 模块封装

    JavaScript 模块封装 前言介绍 在最早的时候JavaScript这门语言其实是并没有模块这一概念,但是随着时间的推移与技术的发展将一些复用性较强的代码封装成模块变成了必要的趋势. 在这篇文章 ...

  3. java web工程导入jar包流程,容易犯错

    1)首先把jar包拷贝到WEB-INF/lib下 2)在Eclipse中web/WEB-INF/lib路径下刷新.(省略此步骤就会找不到) 3)Java Build Path中Remove掉Web A ...

  4. 性能分析(4)- iowait 使用率过高案例

    性能分析小案例系列,可以通过下面链接查看哦 https://www.cnblogs.com/poloyy/category/1814570.html 前言 前面两个案例讲的都是上下文切换导致的 CPU ...

  5. Vue 生成条形码 jsbarcode的使用

    安装依赖包 npm install jsbarcode --save 在使用页面引入依赖包 import JsBarcode from 'jsbarcode' 定义img标签和id <img i ...

  6. .NET 跨平台框架Avalonia UI: 填坑指北(一):熟悉UI操作

    Avalonia 是一个跨平台的 .NET UI 框架,支持 Windows.Linux.Mac OSX... (以及Android  IOS soon..) 本篇主要介绍Avalonia开发过程和L ...

  7. 【趣味设计模式系列】之【代理模式2--JDK动态代理源码解析】

    1. 图解 上图主要描述了JDK动态代理的执行过程,下面做详细分析. 2. Proxy源码分析 上一篇,在使用JDK动态代理的时候,借助于Proxy类,使用newProxyInstance静态方法,创 ...

  8. SVN的基本使用

    2020年7月6日 为什么需要版本控制? 需要清晰地保存某些文件的不同修订版本 控制文件的发屐过程,找出导致 BUG 的原因 轻松将项目或文件恢复到指定版本 极大方便团队之间协同开发,防止出现混乱 在 ...

  9. 浏览器自动化的一些体会4 webBrowser控件之零碎问题2

    1. DocumentCompleted的多次执行问题 有的网页,会多次触发DocumentCompleted事件,由于它是异步的,不会阻塞,所以如果不恰当处理,会造成某些代码被错误地多次执行,造成意 ...

  10. 理解RESTful原理

    如何给老婆解释什么是RESTful 老婆经常喜欢翻看我订阅的技术杂志,她总能从她的视角提出很多有趣的问题. 一个悠闲的周日下午,她午觉醒来,又习惯性的抓起这个月的杂志,饶有兴趣地看了起来. 果不其然, ...