Prometheus监控神器-服务发现篇(二)
本章节讲解服务发现与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监控神器-服务发现篇(二)的更多相关文章
- spring cloud+dotnet core搭建微服务架构:服务发现(二)
前言 上篇文章实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A调用服务B,那么服务A访问的是服务B的负载均衡地址,通过负载均衡来指向到服务B的真实地址,上篇文章已经说了这 ...
- spring cloud+.net core搭建微服务架构:服务发现(二)
前言 上篇文章实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A调用服务B,那么服务A访问的是服务B的负载均衡地址,通过负载均衡来指向到服务B的真实地址,上篇文章已经说了这 ...
- Prometheus监控系统之入门篇(一)续
在上篇Prometheus监控系统之入门篇(一)中我们讲解了Prometheus的基本架构和工作流程, 并从0到1搭建了Prometheus服务,pushgateway以及告警系统. 本篇我们主要介绍 ...
- Prometheus监控神器-Alertmanager篇(1)
本章节主要涵盖了Alertmanager的工作机制与配置文件的比较详细的知识内容,由浅入深的给大家讲解. 警报一直是整个监控系统中的重要组成部分,Prometheus监控系统中,采集与警报是分离的.警 ...
- Prometheus监控神器-Rules篇
本章主要对如何使用Prometheus与Alertmanager组件集成配置,以及对警报规则 Rules 的俩种类型及其模板内容进行讲解. 与Alertmanager集成 Prometheus把产生的 ...
- prometheus监控golang服务实践
一.prometheus基本原理介绍 prometheus是基于metric采样的监控,可以自定义监控指标,如:服务每秒请求数.请求失败数.请求执行时间等,每经过一个时间间隔,数据都会从运行的服务中流 ...
- SpringCloud接入EDAS——服务发现篇
旁白 很久没有写技术文章了,最近不是写水文就是写小说.说到底,还是最近很少研究技术的缘故,已经到了江郎才尽的地步了. 不过,LZ无意间看到自己团队的小伙伴写的一些文章,觉得还是不错的,于是便动了心思, ...
- Prometheus监控系统之入门篇(一)
1. 简介 Prometheus: (简称Prom)是由SoundCloud开发的开源监控报警系统.是大名鼎鼎的CNCF云原生基金会下的第二大开源项目.具有如下特点: 使用Go语言开发 内置时序数据库 ...
- 使用Prometheus监控Golang服务-基于YoyoGo框架
Prometheus Prometheus是一个非常棒的工具,结合grafana能够让我在不写代码,或者少写代码的情况下搭建一套有效的监控体系.这里介绍一下Prometheus监控golang程序的方 ...
随机推荐
- nvidia-smi:控制您的GPU
翻译 https://www.microway.com/hpc-tech-tips/nvidia-smi_control-your-gpus/ 大多数用户知道如何检查其CPU的状态,查看多少系统内存 ...
- (恐怕是)写得最通俗易懂的一篇关于HashMap的文章——xx大佬这样说
先看再点赞,给自己一点思考的时间,微信搜索[沉默王二]关注这个有颜值却假装靠才华苟且的程序员. 本文 GitHub github.com/itwanger 已收录,里面还有一线大厂整理的面试题,以及我 ...
- python6.1创建类
class Dog(object): type1="宠物"#类变量 #初始化方法 def __init__(self,name,age,color): self.name=name ...
- 基于Qt实现的TCP端口数据转发服务器
对于Qt,比较喜欢qt的sdk框架,我也是用于做一些工作中用到的工具软件,基于qt的sdk做起来也比较快: 一.概述 今天要说的这个tcp端口转发服务器,主要是用于将监听端口的数据转发到另外一个服务器 ...
- 用 Python 写个消消乐小游戏
提到开心消消乐这款小游戏,相信大家都不陌生,其曾在 2015 年获得过玩家最喜爱的移动单机游戏奖,受欢迎程度可见一斑,本文我们使用 Python 来做个简单的消消乐小游戏. 很多人学习python,不 ...
- linux tcpdump抓包Post请求
tcpdump -s 0 -A 'tcp dst port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354)' -w f ...
- C语言学习笔记之switch有无break差别
今天复习到了switch语句,我们正常的写法中,是经常把switch和break搭配在一起的 当我们把break去掉呢 可以看到,我们选择2时,的确会到case 2里面执行语句,可是没有break还是 ...
- CentOS7 安装 Nexus
CentOS7 安装 Nexus 所需软件包 jdk-8u231-linux-x64.tar.gz nexus-3.24.0-02-unix.tar.gz 创建安装目录 mkdir -p /opt/n ...
- SSH安全免密码登录:ssh key
ssh key 使用非对称加密方式生成公钥和私钥 私钥存放在本地~/.ssh目录 公钥可以对外公开,放在服务器的~/.ssh/authorized_keys 1.linux平台生成ssh key ss ...
- Azure Application Gateway(一)对后端 Web App 进行负载均衡
一,引言 今天,我们学习一个新的知识点-----Azure Application Gateway,通过Azure 应用程序网关为我么后端的服务提供负载均衡的功能.我们再文章头中大概先了解一下什么是应 ...