全局配置文件
$ cat /data/prometheus/prometheus.yml
# my global config
global:
scrape_interval: 30s # 每隔多久采集一次指标
scrape_timeout: 10s # 每次采集的超时时间
evaluation_interval: 30s # 每隔多久执行一次 rules
external_labels: # 当和其他外部系统交互时的标签,如远程存储、联邦集群时
origin_prometheus: hk-prometheus
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
- 127.0.0.1:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
- "rules/*.rules"
.....
- global:此片段指定的是 prometheus 的全局配置,比如采集间隔,抓取超时时间等。
- rule_files:此片段指定报警规则文件,prometheus 根据这些规则信息,会推送报警信息到 alertmanager 中。
- scrape_configs: 此片段指定抓取配置,prometheus 的数据采集通过此片段配置。
- alerting: 此片段指定报警配置,这里主要是指定 prometheus 将报警规则推送到指定的 alertmanager 实例地址。
此部分内容需参考 prometheus 集群和高可用部分,如果是单机架构则无需配置。
- remote_write: 指定后端的存储的写入 api 地址。
- remote_read: 指定后端的存储的读取 api 地址。
scrape_config 参数
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus-server'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
- job_name: 'blackbox-platform-probe-http-get-prod'
metrics_path: /probe
params:
module: [http_2xx] # http 检测模块
file_sd_configs:
- refresh_interval: 1m
files:
- "targets/blackbox/blackbox-platform-probe-http-get-prod.yml"
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 127.0.0.1:9115
- scrape_interval: 抓取间隔, 默认继承 global 值。
- scrape_timeout: 抓取超时时间, 默认继承 global 值。
- metric_path: 抓取路径,默认是 /metrics
- scheme: 指定采集使用的协议,http 或者 https。
- params: 指定 url 参数。
- params[module]: 使用模块,常用
- http_2xx:http 检测模块
- tcp_connect: TCP 检测模块
- dns:DNS 检测模块
- basic_auth: 指定认证信息。
- *_sd_configs: 指定服务发现配置(基于文件;基于 Consul 等)
- static_configs: 静态指定服务 job。
- relabel_config: relabel 设置。
Prometheus 的 Relabeling 机制
服务发现与 Relabeling
在本章的前几个小节中笔者已经分别介绍了 Prometheus 的几种服务发现机制。通过服务发现的方式,管理员可以在不重启 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 节点的信息
- __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 值:
在第 6 章的“Prometheus 高可用”小节中,正是利用了 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 或者采集到的样本的标签中。