Prometheus 简单使用

与其每天担心未来,不如努力现在。别对自己丧失信心,成长的路上,只有奋斗才能给你最大的安全感。

Prometheus 简介

Prometheus 是啥

Prometheus 是一套开源的系统监控报警框架。它启发于 Google 的 borgmon 监控系统,由工作在 SoundCloud 的 google 前员工在 2012 年创建,作为社区开源项目进行开发,并于 2015 年正式发布。2016 年,Prometheus 正式加入 Cloud Native Computing Foundation,成为受欢迎度仅次于 Kubernetes 的项目。

Prometheus 优点

  • 强大的多维度数据模型:
    1. 时间序列数据通过 metric 名和键值对来区分。
    2. 所有的 metrics 都可以设置任意的多维标签。
    3. 数据模型更随意,不需要刻意设置为以点分隔的字符串。
    4. 可以对数据模型进行聚合,切割和切片操作。
    5. 支持双精度浮点类型,标签可以设为全 unicode。
  • 灵活而强大的查询语句(PromQL):在同一个查询语句,可以对多个 metrics 进行乘法、加法、连接、取分数位等操作。
  • 易于管理: Prometheus server 是一个单独的二进制文件,可直接在本地工作,不依赖于分布式存储。
  • 高效:平均每个采样点仅占 3.5 bytes,且一个 Prometheus server 可以处理数百万的 metrics。
  • 使用 pull 模式采集时间序列数据,这样不仅有利于本机测试而且可以避免有问题的服务器推送坏的 metrics。
  • 可以采用 push gateway 的方式把时间序列数据推送至 Prometheus server 端。
  • 可以通过服务发现或者静态配置去获取监控的 targets。
  • 有多种可视化图形界面。
  • 易于伸缩。

Prometheus 组件

Prometheus 生态圈中包含了多个组件,其中许多组件是可选的:

  • Prometheus Server: 用于收集和存储时间序列数据。
  • Client Library: 客户端库,为需要监控的服务生成相应的 metrics 并暴露给 Prometheus server。当 Prometheus server 来 pull 时,直接返回实时状态的 metrics。
  • Push Gateway: 主要用于短期的 jobs。由于这类 jobs 存在时间较短,可能在 Prometheus 来 pull 之前就消失了。为此,这次 jobs 可以直接向 Prometheus server 端推送它们的 metrics。这种方式主要用于服务层面的 metrics,对于机器层面的 metrices,需要使用 node exporter。
  • Exporters: 用于暴露已有的第三方服务的 metrics 给 Prometheus。
  • Alertmanager: 从 Prometheus server 端接收到 alerts 后,会进行去除重复数据,分组,并路由到对收的接受方式,发出报警。常见的接收方式有:电子邮件,pagerduty,OpsGenie, webhook 等。
  • 一些其他的工具。

Prometheus 架构

img

从这个架构图,也可以看出 Prometheus 的主要模块包含, Server, Exporters, Pushgateway, PromQL, Alertmanager, WebUI 等。

它大致使用逻辑是这样:

  1. Prometheus server 定期从静态配置的 targets 或者服务发现的 targets 拉取数据。
  2. 当新拉取的数据大于配置内存缓存区的时候,Prometheus 会将数据持久化到磁盘(如果使用 remote storage 将持久化到云端)。
  3. Prometheus 可以配置 rules,然后定时查询数据,当条件触发的时候,会将 alert 推送到配置的 Alertmanager。
  4. Alertmanager 收到警告的时候,可以根据配置,聚合,去重,降噪,最后发送警告。
  5. 可以使用 API, Prometheus Console 或者 Grafana 查询和聚合数据。

Prometheus 适用于什么场景

Prometheus 适用于记录文本格式的时间序列,它既适用于以机器为中心的监控,也适用于高度动态的面向服务架构的监控。在微服务的世界中,它对多维数据收集和查询的支持有特殊优势。Prometheus 是专为提高系统可靠性而设计的,它可以在断电期间快速诊断问题,每个 Prometheus Server 都是相互独立的,不依赖于网络存储或其他远程服务。当基础架构出现故障时,你可以通过 Prometheus 快速定位故障点,而且不会消耗大量的基础架构资源。

Prometheus 不适合什么场景

Prometheus 非常重视可靠性,即使在出现故障的情况下,你也可以随时查看有关系统的可用统计信息。如果你需要百分之百的准确度,例如按请求数量计费,那么 Prometheus 不太适合你,因为它收集的数据可能不够详细完整。这种情况下,你最好使用其他系统来收集和分析数据以进行计费,并使用 Prometheus 来监控系统的其余部分。

Prometheus 数据模型

数据模型

Prometheus 所有采集的监控数据均以指标(metric)的形式保存在内置的时间序列数据库当中(TSDB):属于同一指标名称,同一标签集合的、有时间戳标记的数据流。除了存储的时间序列,Prometheus 还可以根据查询请求产生临时的、衍生的时间序列作为返回结果。

指标名称和标签

每一条时间序列由指标名称(Metrics Name)以及一组标签(键值对)唯一标识。其中指标的名称(metric name)可以反映被监控样本的含义(例如,http_requests_total — 表示当前系统接收到的 HTTP 请求总量),指标名称只能由 ASCII 字符、数字、下划线以及冒号组成,同时必须匹配正则表达式 [a-zA-Z_:][a-zA-Z0-9_:]*

[info] 注意

冒号用来表示用户自定义的记录规则,不能在 exporter 中或监控对象直接暴露的指标中使用冒号来定义指标名称。

通过使用标签,Prometheus 开启了强大的多维数据模型:对于相同的指标名称,通过不同标签列表的集合,会形成特定的度量维度实例(例如:所有包含度量名称为 /api/tracks 的 http 请求,打上 method=POST 的标签,就会形成具体的 http 请求)。该查询语言在这些指标和标签列表的基础上进行过滤和聚合。改变任何度量指标上的任何标签值(包括添加或删除指标),都会创建新的时间序列。

标签的名称只能由 ASCII 字符、数字以及下划线组成并满足正则表达式 [a-zA-Z_][a-zA-Z0-9_]*。其中以 __ 作为前缀的标签,是系统保留的关键字,只能在系统内部使用。标签的值则可以包含任何 Unicode 编码的字符。

时序样本

在时间序列中的每一个点称为一个样本(sample),样本由以下三部分组成:

  • 指标(metric):指标名称和描述当前样本特征的 labelsets;
  • 时间戳(timestamp):一个精确到毫秒的时间戳;
  • 样本值(value): 一个 folat64 的浮点型数据表示当前样本的值。

格式

通过如下表达方式表示指定指标名称和指定标签集合的时间序列:

1
<metric name>{<label name>=<label value>, ...} value timestamps

例如,指标名称为 api_http_requests_total,标签为 method="POST"handler="/messages" 的时间序列可以表示为:

1
api_http_requests_total{method="POST", handler="/messages"}

这与 OpenTSDB 中使用的标记法相同。

指标类型

Prometheus 的客户端库中提供了四种核心的指标类型。但这些类型只是在客户端库(客户端可以根据不同的数据类型调用不同的 API 接口)和在线协议中,实际在 Prometheus server 中并不对指标类型进行区分,而是简单地把这些指标统一视为无类型的时间序列。不过,将来我们会努力改变这一现状的。

Counter

  • 一种累加的 metric,典型的应用如:请求的个数,结束的任务数, 出现的错误数等等。

例如 Prometheus server 中 http_requests_total, 表示 Prometheus 处理的 http 请求总数,我们可以使用 delta, 很容易得到任意区间数据的增量,这个会在 PromQL 一节中细讲。

image-20200410152345078

Gauge

  • 一种常规的 metric,典型的应用如:温度,运行的 goroutines 的个数。
  • 可以任意加减。

例如 Prometheus server 中 go_goroutines, 表示 Prometheus 当前 goroutines 的数量。

image-20200410152301768

Histogram

  • 可以理解为柱状图,典型的应用如:请求持续时间,响应大小。
  • 可以对观察结果采样,分组及统计。

例如,查询prometheus_http_request_duration_seconds_sum{handler=“/api/v1/query”,instance=“localhost:9090”,job=“prometheus”}时,返回结果如下:

image-20200410152805983

Summary

  • 类似于 Histogram, 典型的应用如:请求持续时间,响应大小。
  • 提供观测值的 count 和 sum 功能。
  • 提供百分位的功能,即可以按百分比划分跟踪结果。

instance 和 jobs

Prometheus 中,将任意一个独立的数据源(target)称之为实例(instance)。包含相同类型的实例的集合称之为作业(job)。 如下是一个含有四个重复实例的作业:

1
2
3
4
5
- job: api-server
- instance 1: 1.2.3.4:5670
- instance 2: 1.2.3.4:5671
- instance 3: 5.6.7.8:5670
- instance 4: 5.6.7.8:5671

自生成标签和时序

Prometheus 在采集数据的同时,会自动在时序的基础上添加标签,作为数据源(target)的标识,以便区分:

  • job: The configured job name that the target belongs to.
  • instance: The <host>:<port> part of the target’s URL that was scraped.

如果其中任一标签已经在此前采集的数据中存在,那么将会根据 honor_labels 设置选项来决定新标签。详见官网解释: scrape configuration documentation

对每一个实例而言,Prometheus 按照以下时序来存储所采集的数据样本:

  • up{job="<job-name>", instance="<instance-id>"}: 1 表示该实例正常工作
  • up{job="<job-name>", instance="<instance-id>"}: 0 表示该实例故障
  • scrape_duration_seconds{job="<job-name>", instance="<instance-id>"} 表示拉取数据的时间间隔
  • scrape_samples_post_metric_relabeling{job="<job-name>", instance="<instance-id>"} 表示采用重定义标签(relabeling)操作后仍然剩余的样本数
  • scrape_samples_scraped{job="<job-name>", instance="<instance-id>"} 表示从该数据源获取的样本数

其中 up 时序可以有效应用于监控该实例是否正常工作。

Export

文本格式

在讨论 Exporter 之前,有必要先介绍一下 Prometheus 文本数据格式,因为一个 Exporter 本质上就是将收集的数据,转化为对应的文本格式,并提供 http 请求。

Exporter 收集的数据转化的文本内容以行 (\n) 为单位,空行将被忽略, 文本内容最后一行为空行

注释

文本内容,如果以 # 开头通常表示注释。

  • # HELP 开头表示 metric 帮助说明。
  • # TYPE 开头表示定义 metric 类型,包含 counter, gauge, histogram, summary, 和 untyped 类型。
  • 其他表示一般注释,供阅读使用,将被 Prometheus 忽略。

采样数据

内容如果不以 # 开头,表示采样数据。它通常紧挨着类型定义行,满足以下格式:

1
2
3
4
metric_name [
"{" label_name "=" `"` label_value `"` { "," label_name "=" `"` label_value `"` } [ "," ] "}"
] value [ timestamp ]
1.2.3.

下面是一个完整的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# HELP http_requests_total The total number of HTTP requests.
# TYPE http_requests_total counter
http_requests_total{method="post",code="200"} 1027 1395066363000
http_requests_total{method="post",code="400"} 3 1395066363000

# Escaping in label values:
msdos_file_access_time_seconds{path="C:\\DIR\\FILE.TXT",error="Cannot find file:\n\"FILE.TXT\""} 1.458255915e9

# Minimalistic line:
metric_without_timestamp_and_labels 12.47

# A weird metric from before the epoch:
something_weird{problem="division by zero"} +Inf -3982045

# A histogram, which has a pretty complex representation in the text format:
# HELP http_request_duration_seconds A histogram of the request duration.
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.05"} 24054
http_request_duration_seconds_bucket{le="0.1"} 33444
http_request_duration_seconds_bucket{le="0.2"} 100392
http_request_duration_seconds_bucket{le="0.5"} 129389
http_request_duration_seconds_bucket{le="1"} 133988
http_request_duration_seconds_bucket{le="+Inf"} 144320
http_request_duration_seconds_sum 53423
http_request_duration_seconds_count 144320

# Finally a summary, which has a complex representation, too:
# HELP rpc_duration_seconds A summary of the RPC duration in seconds.
# TYPE rpc_duration_seconds summary
rpc_duration_seconds{quantile="0.01"} 3102
rpc_duration_seconds{quantile="0.05"} 3272
rpc_duration_seconds{quantile="0.5"} 4773
rpc_duration_seconds{quantile="0.9"} 9001
rpc_duration_seconds{quantile="0.99"} 76656
rpc_duration_seconds_sum 1.7560473e+07
rpc_duration_seconds_count 2693

需要特别注意的是,假设采样数据 metric 叫做 x, 如果 xhistogramsummary 类型必需满足以下条件:

  • 采样数据的总和应表示为 x_sum
  • 采样数据的总量应表示为 x_count
  • summary 类型的采样数据的 quantile 应表示为 x{quantile="y"}
  • histogram 类型的采样分区统计数据将表示为 x_bucket{le="y"}
  • histogram 类型的采样必须包含 x_bucket{le="+Inf"}, 它的值等于 x_count 的值。
  • summaryhistoramquantilele 必需按从小到大顺序排列。

常用查询

收集到 node_exporter 的数据后,我们可以使用 PromQL 进行一些业务查询和监控,下面是一些比较常见的查询。

注意:以下查询均以单个节点作为例子,如果大家想查看所有节点,将 instance="xxx" 去掉即可。

CPU 使用率

1
2
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
1.

CPU 各 mode 占比率

1
2
avg by (instance, mode) (irate(node_cpu_seconds_total[5m])) * 100
1.

机器平均负载

1
2
3
4
node_load1{instance="xxx"} // 1分钟负载
node_load5{instance="xxx"} // 5分钟负载
node_load15{instance="xxx"} // 15分钟负载
1.2.3.

内存使用率

1
2
100 - ((node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes)/node_memory_MemTotal_bytes) * 100
1.

磁盘使用率

1
2
100 - node_filesystem_free{instance="xxx",fstype!~"rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|fuse.*"} / node_filesystem_size{instance="xxx",fstype!~"rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|fuse.*"} * 100
1.

或者你也可以直接使用 {fstype=“xxx”} 来指定想查看的磁盘信息

网络 IO

1
2
3
4
5
6
// 上行带宽
sum by (instance) (irate(node_network_receive_bytes{instance="xxx",device!~"bond.*?|lo"}[5m])/128)

// 下行带宽
sum by (instance) (irate(node_network_transmit_bytes{instance="xxx",device!~"bond.*?|lo"}[5m])/128)
1.2.3.4.5.

网卡出/入包

1
2
3
4
5
6
// 入包量
sum by (instance) (rate(node_network_receive_bytes{instance="xxx",device!="lo"}[5m]))

// 出包量
sum by (instance) (rate(node_network_transmit_bytes{instance="xxx",device!="lo"}[5m]))
1.2.3.4.5.

Prometheus 配置详解

要想知道一个工具是如何运行的,那么了解其配置参数,对了解整个工具以及后续的瓶颈了解、优化是非常有帮助的。

官方文档说明: https://prometheus.io/docs/prometheus/latest/configuration/configuration/

Prometheus 配置分为两个部分,命令行传递的不可变配置,配置文件传递的可变配置。所谓不可变是指进程进行运行中是不可以动态更新。

Prometheus提供了两个可执行文件:prometheus 和 promtool,前者用于prometheus server的启停,后者为prometheus调试工具,常用于配置文件检查。

prometheus 常用参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-h, --help                              显示帮助信息
--version 显示版本
--config.file="prometheus.yml" 指定配置文件
--web.listen-address="0.0.0.0:9090" 指定监听的端口
--web.max-connections=512 最大连接数
--web.enable-lifecycle 是否开启reload和shutdown的远程API
--web.enable-admin-api 是否开启管理API
--web.console.templates="consoles" 控制台模板目录
--web.console.libraries="console_libraries" 控制台库文件目录
--storage.tsdb.path="data/" 数据存储路径
--storage.tsdb.retention.time 数据保留时间,默认15天
--query.timeout=2m 查询超时时间
--query.max-concurrency=20 最大并发查询数量
--query.max-samples=50000000 单次查询返回的最大样本数
--log.level=info 日志级别: [debug, info, warn, error]
--log.format=logfmt 日志输出格式:[logfmt, json]

promtool 常用参数:

1
2
check config <config-files>...  检查配置文件
check rules <rule-files>... 检查规则文件

热加载

Prometheus改变参数可以通过命令行参数以及配置文件,其中命令行参数只要是修改系统参数,例如存储路径的指定或者挂载磁盘
Prometheus可以在运行时重新加载它的配置。 如果新配置格式不正确,则更改将不会应用。 通过向Prometheus进程发送SIGHUP或向/-/reload端点发送HTTP POST请求(启用--web.enable-lifecycle标志时)来触发配置reload。 这也将重新加载任何配置的规则文件。

prometheus通过--config.file命令行参数指定配置文件

1
2
3
配置热加载:
#1. kill -HUP pid # 发送 SIGHUP 信号给prometheus进程
#2. curl -X POST http://IP/-/reload # 调用 /-/reload API,仅在启用 --web.enable-lifecycle 状态下

通用类型

1
2
3
4
5
6
7
8
9
10
11
1. <boolean>:true false
2. <duration>:与正则表达式[0-9]+(ms|[smhdwy])匹配的持续时间
3. <labelname>:与正则表达式匹配的字符串[a-zA-Z_][a-zA-Z0-9_]*
4. <labelvalue>:一个unicode字符串
5. <filename>:当前工作目录中的有效路径
6. <host>:一个有效的字符串,由一个主机名或IP后跟一个可选的端口号组成
7. <path>:有效的URL路径
8. <scheme>:可以取值为http或https的字符串
9. <string>:一个常规字符串
10. <secret>:一个常用的密码字符串,例如密码
11. <tmpl_string>:在使用前被模板扩展的字符串

配置文件格式

原始配置文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# my global config
global:
# 默认情况下抓取目标的频率.
[ scrape_interval: <duration> | default = 1m ]
# 抓取超时时间.
[ scrape_timeout: <duration> | default = 10s ]
# 评估规则的频率.
[ evaluation_interval: <duration> | default = 1m ]
# 与外部系统通信时对时间序列或者告警信息添加的标签,如remote storage、alertmanager等
external_labels:
[ <labelname>: <labelvalue> ... ]
# PromQL查询日志,reload操作会重新打开日志
[ query_log_file: <string> ]

# 警报指定与Alertmanager相关的设置.
alerting:
# 告警标签重写
alert_relabel_configs:
[ - <relabel_config> ... ]
# alertmanager 配置
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093

# 规则文件指定了一个globs列表.
# 从所有匹配的文件中读取规则和警报.
# 根据 global 的 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# - "/etc/config/rules/*.yml" # 代表rules目录下的所有以.yml结尾的文件

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']

# 与远程写入功能相关的设置.
remote_write:
[ - <remote_write> ... ]

# 与远程读取功能相关的设置.
remote_read:
[ - <remote_read> ... ]

global: 全局配置(如果有内部单独设定,会覆盖这个参数)
alerting: 告警插件定义。这里会设定alertmanager这个报警插件。
rule_files: 告警规则。 按照设定参数进行扫描加载,用于自定义报警规则,其报警媒介和route路由由alertmanager插件实现。
scrape_configs:采集配置。配置数据源,包含分组job_name以及具体target。又分为静态配置和服务发现

global 模块

global配置是一个全局的配置,如果没有对每一个job(scrape_configs下的job_name项)配置,就采用全局的配置。

1
2
3
4
5
6
7
# my global config
global:

scrape_interval: 15s # 默认15s 全局每次数据收集的间隔
evaluation_interval: 15s # 规则扫描时间间隔是15秒,默认不填写是 1分钟
scrape_timeout: 5s #超时时间
external_labels: # 用于外部系统标签的,不是用于metrics(度量)数据

常用的命令行参数(prometheus插件基本都是二进制的,可以通过二进制文件 -h了解参数用于自定义启动参数,否则默认)

1
2
3
4
5
./prometheus -h
--config.file="/opt/config/prometheus.yml" # 读取指定配置文件
--web.listen-address="0.0.0.0:9090" # 指定prometheus运行端口
--log.level=info # 日志级别
--alertmanager.timeout=10s # 与报警组件的超时时间

alerting 模块

1
2
3
4
5
6
7
8
9
10
# 警报指定与Alertmanager相关的设置.
alerting:
# 告警标签重写
alert_relabel_configs:
[ - <relabel_config> ... ]
# alertmanager 配置
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093

这里定义和prometheus集成的alertmanager插件,用于监控报警。

alert_relabel_configs

警报重新标记在发送到Alertmanager之前应用于警报。 它具有与目标重新标记相同的配置格式和操作。 外部标签后应用警报重新标记。

这样做的一个用途是确保具有不同外部标签的HA对Prometheus服务器发送相同的警报。

alertmanager_config

alertmanager部分指定Prometheus服务器向其发送警报的Alertmanager实例。 它还提供参数以配置如何与这些Alertmanagers进行通信。

Alertmanagers可以通过static_configs参数静态配置,也可以使用其中一种支持的服务发现机制动态发现。

此外,relabel_configs允许从发现的实体中选择Alertmanagers,并对使用的API路径提供高级修改,该路径通过__alerts_path__标签公开。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 推送警报时按目标Alertmanager超时。
[ timeout: <duration> | default = 10s ]

# 将推送HTTP路径警报的前缀。
[ path_prefix: <path> | default = / ]

# 配置用于请求的协议方案。
[ scheme: <scheme> | default = http ]

# 使用配置的用户名和密码在每个请求上设置`Authorization`标头。 password和password_file是互斥的。
basic_auth:
[ username: <string> ]
[ password: <string> ]
[ password_file: <string> ]

# 使用配置的承载令牌在每个请求上设置“Authorization”标头。 它与`bearer_token_file`互斥。
[ bearer_token: <string> ]

# 使用配置的承载令牌在每个请求上设置“Authorization”标头。 它与`bearer_token`互斥。
[ bearer_token_file: /path/to/bearer/token/file ]

# 配置scrape请求的TLS设置。
tls_config:
[ <tls_config> ]

# 可选的代理URL。
[ proxy_url: <string> ]

# Azure服务发现配置列表。
azure_sd_configs:
[ - <azure_sd_config> ... ]
# Consul服务发现配置列表。
consul_sd_configs:
[ - <consul_sd_config> ... ]
# DNS服务发现配置列表。
dns_sd_configs:
[ - <dns_sd_config> ... ]
# ECS服务发现配置列表。
ec2_sd_configs:
[ - <ec2_sd_config> ... ]
# 文件服务发现配置列表。
file_sd_configs:
[ - <file_sd_config> ... ]
# GCE服务发现配置列表。
gce_sd_configs:
[ - <gce_sd_config> ... ]
# K8S服务发现配置列表。
kubernetes_sd_configs:
[ - <kubernetes_sd_config> ... ]
# Marathon服务发现配置列表。
marathon_sd_configs:
[ - <marathon_sd_config> ... ]
# AirBnB's Nerve 服务发现配置列表。
nerve_sd_configs:
[ - <nerve_sd_config> ... ]
# Zookepper服务发现配置列表。
serverset_sd_configs:
[ - <serverset_sd_config> ... ]
# Triton服务发现配置列表。
triton_sd_configs:
[ - <triton_sd_config> ... ]
# 标记为静态配置的Alertmanagers列表。
static_configs:
[ - <static_config> ... ]

# 对发现的alertmanager进行筛选和标签重写,比如API中PATH
relabel_configs:
[ - <relabel_config> ... ]

rule_files 模块

这个主要是用来设置告警规则,基于设定什么指标进行报警(类似触发器trigger)。这里设定好规则以后,prometheus会根据全局global设定的evaluation_interval参数进行扫描加载,规则改动后会自动加载。其报警媒介和route路由由alertmanager插件实现。

1
2
3
4
5
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# - "/etc/config/rules/*.yml" # 代表rules目录下的所有以.yml结尾的文件

规则文件分为两种:记录规则(recording rule)和报警规则(altering rule)。报警规则在告警管理中。recording rules 目的是将常用的复杂查询结果周期性写入数据库,避免频繁计算带来的资源消耗,一般将dashboard中复杂查询写入recording rules 中。

recording rule

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# recording rule
groups:
# 组名,配置文件中不能重复
- name: <string>
# 多久计算计算一次
[ interval: <duration> | default = global.evaluation_interval ]
rules:
# 入库的指标名称
- record: <string>
# PromQL表达式
expr: <string>
# 标签
labels:
[ <labelname>: <labelvalue> ]

altering rule

1
2
3
4
5
6
7
8
9
10
11
12
13
# alerting rule
groups:
# 组名,一个文件中唯一标识
- name: <string>
[ interval: <duration> | default = global.evaluation_interval ]
rules:
- alert: <string> # 报警名称
expr: <string> # 报警规则表达式
[ for: <duration> | default = 0s ] # 当触发条件持续指定时间再发送告警,发送前告警为pending
labels: # 告警标签
[ <labelname>: <tmpl_string> ] # 会覆盖已有的标签,用于后面alertmanager中筛选
annotations: # 告警注释
[ <labelname>: <tmpl_string> ] # 一般添加发送邮件的内容、标题等等。常用字段有:summary,description

scrape_configs 模块

1
2
3
4
5
6
7
8
9
10
scrape_configs 默认规则:
scrape_configs:
# The job name is added as a label `job=` to any timeseries scraped from this config.
- job_name: 'prometheus'

# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.

static_configs:
- targets: ['localhost:9090']

prometheus获取数据源target的方式有多种,如静态配置和服务发现配置,prometheus支持多种服务发现,在prometheus中的服务发现主要分为以下几种:

  • static_configs:静态服务发现
  • kubernetes_sd_configs: 基于Kubernetes的服务发现,这章讲的内容
  • consul_sd_configs: Consul 服务发现
  • dns_sd_configs: DNS 服务发现
  • file_sd_configs: 文件服务发现
  • ……
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# 默认分配给已抓取指标的job名称。
job_name: <job_name>

# 从job中抓取目标的频率.
[ scrape_interval: <duration> | default = <global_config.scrape_interval> ]

# 抓取此job时,每次抓取超时时间.
[ scrape_timeout: <duration> | default = <global_config.scrape_timeout> ]

# 从目标获取指标的HTTP资源路径.
[ metrics_path: <path> | default = /metrics ]

# honor_labels控制Prometheus如何处理已经存在于已抓取数据中的标签与Prometheus将附加服务器端的标签之间的冲突("job"和"instance"标签,手动配置的目标标签以及服务发现实现生成的标签)。
#
# 如果honor_labels设置为"true",则通过保留已抓取数据的标签值并忽略冲突的服务器端标签来解决标签冲突。
#
# 如果honor_labels设置为"false",则通过将已抓取数据中的冲突标签重命名为"exported_ <original-label>"(例如"exported_instance","exported_job")然后附加服务器端标签来解决标签冲突。 这对于联合等用例很有用,其中应保留目标中指定的所有标签。
#
# 请注意,任何全局配置的"external_labels"都不受此设置的影响。 在与外部系统通信时,它们始终仅在时间序列尚未具有给定标签时应用,否则将被忽略。
#
[ honor_labels: <boolean> | default = false ]

# 配置用于请求的协议方案.
[ scheme: <scheme> | default = http ]

# 可选的HTTP URL参数.
params:
[ <string>: [<string>, ...] ]

# 使用配置的用户名和密码在每个scrape请求上设置`Authorization`标头。 password和password_file是互斥的。
basic_auth:
[ username: <string> ]
[ password: <secret> ]
[ password_file: <string> ]

# 使用配置的承载令牌在每个scrape请求上设置`Authorization`标头。 它`bearer_token_file`和是互斥的。
[ bearer_token: <secret> ]

# 使用配置的承载令牌在每个scrape请求上设置`Authorization`标头。 它`bearer_token`和是互斥的。
[ bearer_token_file: /path/to/bearer/token/file ]

# 配置scrape请求的TLS设置.
tls_config:
[ <tls_config> ]

# 可选的代理URL.
[ proxy_url: <string> ]

# Azure服务发现配置列表.
azure_sd_configs:
[ - <azure_sd_config> ... ]

# Consul服务发现配置列表.
consul_sd_configs:
[ - <consul_sd_config> ... ]

# DNS服务发现配置列表。
dns_sd_configs:
[ - <dns_sd_config> ... ]

# EC2服务发现配置列表。
ec2_sd_configs:
[ - <ec2_sd_config> ... ]

# OpenStack服务发现配置列表。
openstack_sd_configs:
[ - <openstack_sd_config> ... ]

# 文件服务发现配置列表。
file_sd_configs:
[ - <file_sd_config> ... ]

# GCE服务发现配置列表。
gce_sd_configs:
[ - <gce_sd_config> ... ]

# Kubernetes服务发现配置列表。
kubernetes_sd_configs:
[ - <kubernetes_sd_config> ... ]

# Marathon服务发现配置列表。
marathon_sd_configs:
[ - <marathon_sd_config> ... ]

# AirBnB的神经服务发现配置列表。
nerve_sd_configs:
[ - <nerve_sd_config> ... ]

# Zookeeper Serverset服务发现配置列表。
serverset_sd_configs:
[ - <serverset_sd_config> ... ]

# Triton服务发现配置列表。
triton_sd_configs:
[ - <triton_sd_config> ... ]

# 静态抓取目标配置,一般只有极个别场景才会配置,否则会导致主配置文件更新频繁,并且很臃肿
static_configs:
# 指定抓取目标的地址
targets:
[ - '<host>' ]
# 对采集到的数据指定额外的标签
labels:
[ <labelname>: <labelvalue> ... ]

# target 标签重写规则
relabel_configs:
[ - <relabel_config> ... ]

# metrics 标签重写规则。
metric_relabel_configs:
[ - <relabel_config> ... ]

# 样本数限制,超过规定之则被丢弃。0表示不限制
[ sample_limit: <int> | default = 0 ]

# target 数量限制,超过的将被丢弃,目前为实验性功能。0表示不限制
[ target_limit: <int> | default = 0 ]

tls_config

tls_config允许配置TLS连接。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 用于验证API服务器证书的CA证书。
[ ca_file: <filename> ]

# 用于服务器的客户端证书身份验证的证书和密钥文件。
[ cert_file: <filename> ]
[ key_file: <filename> ]

# ServerName扩展名,用于指示服务器的名称。
# https://tools.ietf.org/html/rfc4366#section-3.1
[ server_name: <string> ]

# 禁用服务器证书的验证。
[ insecure_skip_verify: <boolean> ]

file_sd_config

配置target 的文件可以是json也可以是yaml,推荐使用yaml,方便查看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 主配置文件中 <file_sd_config>
# 配置target的文件列表
files:
[ - <filename_pattern> ... ]

# 从这些文件中读取配置的时间间隔
[ refresh_interval: <duration> | default = 5m ]

# 自动发现文件配置案例
- targets:
- address1
- address2
labels:
labelname1: labelvalue1
labelname2: labelvalue2

dns_sd_config

基于DNS的服务发现配置允许指定一组DNS域名,这些域名会定期查询以发现目标列表。 要联系的DNS服务器从/etc/resolv.conf中读取。

此服务发现方法仅支持基本的DNS A,AAAA和SRV记录查询,但不支持RFC6763中指定的高级DNS-SD方法。

在重新标记阶段,元标签__meta_dns_name在每个目标上可用,并设置为生成已发现目标的记录名称。

1
2
3
4
5
6
7
8
9
10
11
12
# 要查询的DNS域名列表。
names:
[ - <domain_name> ]

# 要执行的DNS查询的类型。
[ type: <query_type> | default = 'SRV' ]

# 查询类型不是SRV时使用的端口号。
[ port: <number>]

# 提供名称后刷新的时间。
[ refresh_interval: <duration> | default = 30s ]

其中<domain_name>是有效的DNS域名。 其中<query_type>是SRV,A或AAAA。

consul_sd_configs

consul 是基于go语言写的注册中心,在生产中可以作为prometheus自动发现的中间件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# consul 地址信息
[ server: <host> | default = "localhost:8500" ]
[ token: <secret> ]
[ datacenter: <string> ]
[ scheme: <string> | default = "http" ]
[ username: <string> ]
[ password: <secret> ]

tls_config:
[ <tls_config> ]

# 自动发现请求访问哪些服务,默认是所有服务
services:
[ - <string> ]

# 过滤目标节点,只有全部包含这些tag的服务地址才会给prometheus认定为target
tags:
[ - <string> ]

# 通过元数据的键值对节点进行过滤
[ node_meta:
[ <string>: <string> ... ] ]

# The string by which Consul tags are joined into the tag label.
[ tag_separator: <string> | default = , ]

# Allow stale Consul results (see https://www.consul.io/api/features/consistency.html). Will reduce load on Consul.
[ allow_stale: <boolean> | default = true ]

# 访问consul的时间间隔
[ refresh_interval: <duration> | default = 30s ]

kubernetes_sd_config

Kubernetes SD配置允许从Kubernetes的RESTAPI中检索scrape目标,并始终与群集状态保持同步。

可以配置以下role类型之一来发现目标:

  • node
  • service
  • pod
  • endpoints
  • ingress

node

node角色发现每个群集节点有一个目标,其地址默认为Kubelet的HTTP端口。 目标地址默认为NodeInternalIPNodeExternalIPNodeLegacyHostIPNodeHostName的地址类型顺序中Kubernetes节点对象的第一个现有地址。

可用元标签:

1
2
3
4
__meta_kubernetes_node_name: 节点名称
__meta_kubernetes_node_label_<labelname>: node的labels
__meta_kubernetes_node_annotation_<annotationname>: node的annotation
__meta_kubernetes_node_address_<address_type>: 如果存在四个值中(NodeInternalIP, NodeExternalIP, NodeLegacyHostIP, and NodeHostName)的一个

此外,节点的instance标签将设置为从API服务器检索的节点名称。

service

service角色为每个服务发现每个服务端口的目标。 这对于服务的黑盒监控通常很有用。 该地址将设置为服务的Kubernetes DNS名称和相应的服务端口。

可用元标签:

1
2
3
4
5
6
7
8
9
__meta_kubernetes_namespace:服务对象的命名空间。
__meta_kubernetes_service_annotation_<annotationname>:服务对象的注释。
__meta_kubernetes_service_cluster_ip:服务的群集IP地址。 (不适用于ExternalName类型的服务)
__meta_kubernetes_service_external_name:服务的DNS名称。 (适用于ExternalName类型的服务)
__meta_kubernetes_service_label_ <labelname>:服务对象的标签。
__meta_kubernetes_service_name:服务对象的名称。
__meta_kubernetes_service_port_name:目标服务端口的名称。
__meta_kubernetes_service_port_number:目标的服务端口号。
__meta_kubernetes_service_port_protocol:目标服务端口的协议。

pod

pod角色发现所有pod并将其容器暴露为目标。 对于容器的每个声明端口,将生成单个目标。 如果容器没有指定端口,则会创建每个容器的无端口目标,以通过重新标记手动添加端口。

可用元标签:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
__meta_kubernetes_namespace:pod对象的命名空间。
__meta_kubernetes_pod_name:pod对象的名称。
__meta_kubernetes_pod_ip:pod对象的pod IP。
__meta_kubernetes_pod_label_ <labelname>:pod对象的标签。
__meta_kubernetes_pod_annotation_ <annotationname>:pod对象的注释。
__meta_kubernetes_pod_container_name:目标地址指向的容器的名称。
__meta_kubernetes_pod_container_port_name:容器端口的名称。
__meta_kubernetes_pod_container_port_number:容器端口号。
__meta_kubernetes_pod_container_port_protocol:容器端口的协议。
__meta_kubernetes_pod_ready:对于pod的就绪状态,设置为true或false。
__meta_kubernetes_pod_phase:在生命周期中设置为Pending,Running,Succeeded,Failed或Unknown。
__meta_kubernetes_pod_node_name:将pod安排到的节点的名称。
__meta_kubernetes_pod_host_ip:pod对象的当前主机IP。
__meta_kubernetes_pod_uid:pod对象的UID。
__meta_kubernetes_pod_controller_kind:对象类型的pod控制器。
__meta_kubernetes_pod_controller_name:pod控制器的名称。

endpoints

endpoints角色从列出的服务端点发现目标。 对于每个端点地址,每个端口发现一个目标。 如果端点由pod支持,则pod的所有其他容器端口(未绑定到端点端口)也会被发现为目标。

可用元标签:

1
2
3
4
5
6
7
__meta_kubernetes_namespace:端点对象的命名空间。
__meta_kubernetes_endpoints_name:端点对象的名称。对于直接从端点列表中发现的所有目标(不是从底层pod中另外推断的那些),附加以下标签:
__meta_kubernetes_endpoint_ready:对端点的就绪状态设置为true或false。
__meta_kubernetes_endpoint_port_name:端点端口的名称。
__meta_kubernetes_endpoint_port_protocol:端点端口的协议。
__meta_kubernetes_endpoint_address_target_kind:端点地址目标的种类。
__meta_kubernetes_endpoint_address_target_name:端点地址目标的名称。

如果端点属于某个服务,则会附加角色:服务发现的所有标签。
对于由pod支持的所有目标,将附加角色的所有标签:pod发现。

ingress

ingress角色发现每个入口的每个路径的目标。 这通常用于黑盒监控入口。 地址将设置为入口规范中指定的主机。

可用元标签:

1
2
3
4
5
6
__meta_kubernetes_namespace:入口对象的名称空间。
__meta_kubernetes_ingress_name:入口对象的名称。
__meta_kubernetes_ingress_label_ <labelname>:入口对象的标签。
__meta_kubernetes_ingress_annotation_<annotationname>:入口对象的注释。
__meta_kubernetes_ingress_scheme:入口的协议方案,如果设置了TLS配置,则为https。 默认为http。
__meta_kubernetes_ingress_path:来自入口规范的路径。 默认为/。

有关Kubernetes发现的配置选项,请参见下文:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 访问Kubernetes API的信息。

# API服务器地址。 如果保留为空,则假定Prometheus在集群内部运行并自动发现API服务器,并在/var/run/secrets/kubernetes.io/serviceaccount/上使用pod的CA证书和不记名令牌文件。
[ api_server: <host> ]

# 应该被发现的实体的Kubernetes角色。
role: <role>

# 用于向API服务器进行身份验证的可选身份验证信息。请注意,`basic_auth`,`bearer_token`和`bearer_token_file`选项是互斥的.password和password_file是互斥的。

# 可选的HTTP基本认证信息。
basic_auth:
[ username: <string> ]
[ password: <secret> ]
[ password_file: <string> ]

# 可选的承载令牌认证信息。
[ bearer_token: <secret> ]

# 可选的承载令牌文件认证信息。
[ bearer_token_file: <filename> ]

# 可选的代理URL。
[ proxy_url: <string> ]

# TLS配置。
tls_config:
[ <tls_config> ]

# 可选命名空间发现 如果省略,则使用所有名称空间。
namespaces:
names:
[ - <string> ]

其中<role>必须是endpointsservicepodnodeingress

有关为Kubernetes配置Prometheus的详细示例,请参阅此示例Prometheus配置文件。

您可能希望查看第三方Prometheus操作,它可以在Kubernetes上自动执行Prometheus设置。

static_config

static_config允许指定目标列表和它们的公共标签集。 这是在scrape配置中指定静态目标的规范方法。

1
2
3
4
5
6
7
# 静态配置指定的目标。
targets:
[ - '<host>' ]

# 分配给从目标中已抓取的所有指标的标签。
labels:
[ <labelname>: <labelvalue> ... ]

relabel_config

重新标记是一个功能强大的工具,可以在目标的标签集被抓取之前重写它,每个采集配置可以配置多个重写标签设置,并按照配置的顺序来应用于每个目标的标签集。

目标重新标签之后,以__开头的标签将从标签集中删除的。

如果使用只需要临时的存储临时标签值的,可以使用_tmp作为前缀标识。

relabel的action类型

  • replace: regex匹配source_labels,替换为 replacement ,写入 target_label
  • keep:删除regex与source_labels不匹配的target
  • drop: 删除regex与source_labels匹配的target
  • labelmap: 对所有标签key进行regex匹配(不是source_labels),将原标签的key替换为replacement指定的key,通常用于改写 __ 开头的标签
  • labeldrop: 对所有标签key进行regex匹配(不是source_labels),匹配到的标签被删除(不是target被删除)
  • labelkeep: 对所有标签key进行regex匹配(不是source_labels),不匹配到的标签被删除(不是target被删除)
  • hashmod: 当一个job中监控目标数量太多时(自动发现中容易出现),将任务分散到不同的机器上。hashmod会将 source_labels值哈希后采用 modulus 取余数,并赋值到一个标签,然后在接下来的relabel中进行保留或者剔除,这样能实现每个prometheus采集一部分target数据

对于标签重写规则重点关注下。本节针对不同 action 进行 target 的标签重写,实验环境如下: 在 prometheus-72 上启动三个 node_exporter 实例,分别监听 8081, 8082, 8083 端口,prometheus-72 从这三个 node_exporter 中采集数据。

1
2
3
4
[root@prometheus-72 ~]# jobs
[1] Running /opt/apps/node_exporter/node_exporter --log.level=error --web.listen-address=":8081" &
[2]- Running /opt/apps/node_exporter/node_exporter --log.level=error --web.listen-address=":8082" &
[3]+ Running /opt/apps/node_exporter/node_exporter --log.level=error --web.listen-address=":8083" &

action: replace

重写规则之前:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@prometheus-72 prometheus]# cat prometheus.yml 
global:
scrape_interval: 60s
external_labels:
monitor: 'codelab-monitor'

scrape_configs:
- job_name: 'node'
static_configs:
- targets: ["10.4.7.72:8081"]
labels:
app: app-01
env: dev
role: master
- targets: ["10.4.7.72:8082"]
labels:
app: app-02
env: prod
role: master
- targets: ["10.4.7.72:8083"]
labels:
app: app-02
env: prod
role: slave

img

添加新标签host,使其格式为: master-dev-72

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
global:
scrape_interval: 60s
external_labels:
monitor: 'codelab-monitor'

scrape_configs:
- job_name: 'node'
static_configs:
- targets: ["10.4.7.72:8081"]
labels:
app: app-01
env: dev
role: master
- targets: ["10.4.7.72:8082"]
labels:
app: app-02
env: prod
role: master
- targets: ["10.4.7.72:8083"]
labels:
app: app-02
env: prod
role: slave
relabel_configs:
- source_labels: ["role", "env", "__address__"]
target_label: host
regex: (.+);(.+);([0-9]{1,3}\.){3}([0-9]+):[0-9]+ # source_labels默认 ; 拼接
replacement: $1-$2-$4

img

action: keep

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
global:
scrape_interval: 60s
external_labels:
monitor: 'codelab-monitor'

scrape_configs:
- job_name: 'node'
static_configs:
- targets: ["10.4.7.72:8081"]
labels:
app: app-01
env: dev
role: master
- targets: ["10.4.7.72:8082"]
labels:
app: app-02
env: prod
role: master
- targets: ["10.4.7.72:8083"]
labels:
app: app-02
env: prod
role: slave
relabel_configs:
- source_labels: ["role", "env", "__address__"]
target_label: host
regex: (.+);(.+);([0-9]{1,3}\.){3}([0-9]+):[0-9]+ # source_labels默认 ; 拼接
replacement: $1-$2-$4
- source_labels: ["env"] # 仅保留 env=prod 的target
regex: prod
action: keep

img

action: drop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
global:
scrape_interval: 60s
external_labels:
monitor: 'codelab-monitor'

scrape_configs:
- job_name: 'node'
static_configs:
- targets: ["10.4.7.72:8081"]
labels:
app: app-01
env: dev
role: master
- targets: ["10.4.7.72:8082"]
labels:
app: app-02
env: prod
role: master
- targets: ["10.4.7.72:8083"]
labels:
app: app-02
env: prod
role: slave
relabel_configs:
- source_labels: ["role", "env", "__address__"]
target_label: host
regex: (.+);(.+);([0-9]{1,3}\.){3}([0-9]+):[0-9]+ # source_labels默认 ; 拼接
replacement: $1-$2-$4
- source_labels: ["env"] # 删除 lable_name 为env,切value为prod的target
regex: prod
action: drop

img

action: labelkeep

尽量不要删除 __ 的标签,比如删了 __address__ 标签会导致 instance 生成异常,进而导致无法获取target信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[root@prometheus-72 prometheus]# cat prometheus.yml 
global:
scrape_interval: 60s
external_labels:
monitor: 'codelab-monitor'

scrape_configs:
- job_name: 'node'
static_configs:
- targets: ["10.4.7.72:8081"]
labels:
app: app-01
role: master
- targets: ["10.4.7.72:8082"]
labels:
app: app-02
env: prod
role: master
- targets: ["10.4.7.72:8083"]
labels:
app: app-02
env: prod
role: slave
relabel_configs:
- regex: (__|role).* # 非临时标签仅保留 role
action: labelkeep

img

action: labeldrop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
global:
scrape_interval: 60s
external_labels:
monitor: 'codelab-monitor'

scrape_configs:
- job_name: 'node'
static_configs:
- targets: ["10.4.7.72:8081"]
labels:
app: app-01
role: master
- targets: ["10.4.7.72:8082"]
labels:
app: app-02
env: prod
role: master
- targets: ["10.4.7.72:8083"]
labels:
app: app-02
env: prod
role: slave
relabel_configs:
- regex: env # 将env标签删除,并是上次target
action: labeldrop

img

action: labelmap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
global:
scrape_interval: 60s
external_labels:
monitor: 'codelab-monitor'

scrape_configs:
- job_name: 'node'
static_configs:
- targets: ["10.4.7.72:8081"]
labels:
app: app-01
role: master
- targets: ["10.4.7.72:8082"]
labels:
app: app-02
env: prod
role: master
- targets: ["10.4.7.72:8083"]
labels:
app: app-02
env: prod
role: slave
relabel_configs:
- regex: __(.+)__ # 将所有双下划线的标签名改为非双下划线的标签名称
action: labelmap

img

action: hashmod

当一个job中监控目标数量太多时(自动发现中容易出现),将任务分散到不同的机器上。hashmod会将 source_labels值哈希后采用 modulus 取余数,并赋值到一个标签,然后在接下来的relabel中进行保留或者剔除,这样能实现每个prometheus采集一部分target数据。下面案例中,其余后 __tmp_hash_value 值有 0、1、2,因此将target分为三组,可以由三个不同的prometheus去获取监控指标。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
global:
scrape_interval: 60s
external_labels:
monitor: 'codelab-monitor'

scrape_configs:
- job_name: 'node'
static_configs:
- targets: ["10.4.7.72:8081"]
labels:
app: app-01
role: master
- targets: ["10.4.7.72:8082"]
labels:
app: app-02
env: prod
role: master
- targets: ["10.4.7.72:8083"]
labels:
app: app-02
env: prod
role: slave
relabel_configs:
- source_labels: ["__address__"]
action: hashmod
modulus: 3
target_label: __tmp_hash_value
- source_labels: [__tmp_hash_value]
regex: "0"
action: drop

img

metric_relabel_configs

Prometheus 从数据源拉取数据后,会对原始数据进行编辑

其中 metric_relabel_configs是 Prometheus 在保存数据前的最后一步标签重新编辑(relabel_configs)。所以,哪怕你将 metric_relabel_configs模块放在 job_name模块的最前端,Prometheus 解析编辑文件后,也会将 metric_relabel_configs放在最后。

metric_relabel_configs 模块和 relabel_config 模块很相似。metric_relabel_configs一个很常用的用途:将监控不需要的数据,直接丢掉,不在Prometheus 中保存。

一般用于:

  1. 删除不必要的指标。
  2. 从指标中删除敏感或不需要的标签。
  3. 添加、编辑或者修改指标的标签值或者标签格式。

删除不需要的指标(metric)

prometheus 默认会将所有拉取到的 metrics 都写入自己的存储中。如果某些 metrics 对我们并没有太多意义,可以设置直接丢掉,减少磁盘空间的浪费。‘node_netstat_Icmp_OutMsgs’ 指标数据。

1
2
3
4
metric_relabel_configs:
- source_labels: [ __name__ ]
regex: 'node_netstat_Icmp_OutMsgs'
action: drop

使用 source_labels 参数选择要要操作的指标,并且还需要一组标签名称。
示例中使用 __name__ 标签,此标签是标识指标名称的预留标签。

如上,我们丢掉指定job_name中的

参考上面的配置,我们可以对指标(metric) 进行添加,删除,重命名等操作。

修改指标(metric) 中的标签(label)

如果我们使用 prometheus 监控 Kubernetes 运行状态;应该会遇到,在一个 query 中结合一个以上的job_name(metric_source)的情况。
不同的job_namemetriclabel命名可能不相同。比如:pod的名称可以使用“pod”或者“pod_name” 这两个 label记录。如果相同含义的label,名称却不相同;对query的编写就很困难了。至少我没有在PromQL中找到类似SQL 语句中的 as 的功能的关键词和方法
这样的话,正确的解决思路应该是在 Prometheus 拉取数据后,保存数据前;将 label 的名称进行重写;保证相同含义的label 有相同的名称。

1
2
3
4
5
6
7
8
9
10
11
12
13
metric_relabel_configs:
- source_labels: [pod]
separator: ;
regex: (.+)
target_label: pod_name
replacement: $1
action: replace
- source_labels: [container]
separator: ;
regex: (.+)
target_label: container_name
replacement: $1
action: replace

如上,将指定job_name中,所有的metrics中含有名为“pod”和“container”名称的label分别拷贝到名为“pod_name”,“container_name”的label中。
注意:如果metric 的 label的名称包含了“pod”和“container”关键词,但是不等于;则不会处理此label。

删除标签

删除标签通常用于隐藏敏感信息或者简化时间序列。

1
2
3
metric_relabel_configs:
- regex: 'kernelVersion'
action: labeldrop

为了删除标签,我们指定了一个正则表达式,然后指定删除标签的操作labeldrop。
这将删除与正在表达式匹配的所有标签。

remote_write

write_relabel_configs是在将样本发送到远程端点之前应用于样本的重新标记。 在外部标签之后应用写入重新标记。 这可用于限制发送的样本。

有一个如何使用此功能的小型演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 要发送样本的端点的URL.
url: <string>

# 对远程写端点的请求超时。
[ remote_timeout: <duration> | default = 30s ]

# 远程写入重新标记配置列表。
write_relabel_configs:
[ - <relabel_config> ... ]

# 使用配置的用户名和密码在每个远程写请求上设置`Authorization`标头.password和password_file是互斥的。
basic_auth:
[ username: <string> ]
[ password: <string> ]
[ password_file: <string> ]

# 使用配置的承载令牌在每个远程写请求上设置`Authorization`头。 它与`bearer_token_file`互斥。
[ bearer_token: <string> ]

# 使用配置的承载令牌在每个远程写请求上设置`Authorization`头。 它与`bearer_token`互斥。
[ bearer_token_file: /path/to/bearer/token/file ]

# 配置远程写入请求的TLS设置。
tls_config:
[ <tls_config> ]

# 可选的代理URL。
[ proxy_url: <string> ]

# 配置用于写入远程存储的队列。
queue_config:
# 在我们开始删除之前每个分片缓冲的样本数。
[ capacity: <int> | default = 10000 ]
# 最大分片数,即并发数。
[ max_shards: <int> | default = 1000 ]
# 最小分片数,即并发数。
[ min_shards: <int> | default = 1 ]
# 每次发送的最大样本数。
[ max_samples_per_send: <int> | default = 100]
# 样本在缓冲区中等待的最长时间。
[ batch_send_deadline: <duration> | default = 5s ]
# 在可恢复错误上重试批处理的最大次数。
[ max_retries: <int> | default = 3 ]
# 初始重试延迟。 每次重试都会加倍。
[ min_backoff: <duration> | default = 30ms ]
# 最大重试延迟。
[ max_backoff: <duration> | default = 100ms ]

有一个与此功能集成的列表。

remote_read

prometheus 可以从远程存储读取时间序列数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 要发送样本的端点的URL.
url: <string>

# 可选的匹配器列表,必须存在于选择器中以查询远程读取端点。
required_matchers:
[ <labelname>: <labelvalue> ... ]

# 对远程读取端点的请求超时。
[ remote_timeout: <duration> | default = 1m ]

# 本地存储应该有完整的数据。
[ read_recent: <boolean> | default = false ]

# 使用配置的用户名和密码在每个远程写请求上设置`Authorization`标头.password和password_file是互斥的。
basic_auth:
[ username: <string> ]
[ password: <string> ]
[ password_file: <string> ]

# 使用配置的承载令牌在每个远程写请求上设置`Authorization`头。 它与`bearer_toke_filen`互斥。
[ bearer_token: <string> ]

# 使用配置的承载令牌在每个远程写请求上设置`Authorization`头。 它与`bearer_token`互斥。
[ bearer_token_file: /path/to/bearer/token/file ]

# 配置远程写入请求的TLS设置。
tls_config:
[ <tls_config> ]

# 可选的代理URL。
[ proxy_url: <string> ]

有一个与此功能集成的列表。

其他监控工具

在前言中,简单介绍了我们选择 Prometheus 的理由,以及使用后给我们带来的好处。

在这里主要和其他监控方案对比,方便大家更好的了解 Prometheus。

Prometheus vs Zabbix

  • Zabbix 使用的是 C 和 PHP, Prometheus 使用 Golang, 整体而言 Prometheus 运行速度更快一点。
  • Zabbix 属于传统主机监控,主要用于物理主机,交换机,网络等监控,Prometheus 不仅适用主机监控,还适用于 Cloud, SaaS, Openstack,Container 监控。
  • Zabbix 在传统主机监控方面,有更丰富的插件。
  • Zabbix 可以在 WebGui 中配置很多事情,但是 Prometheus 需要手动修改文件配置。

Prometheus vs Graphite

  • Graphite 功能较少,它专注于两件事,存储时序数据, 可视化数据,其他功能需要安装相关插件,而 Prometheus 属于一站式,提供告警和趋势分析的常见功能,它提供更强的数据存储和查询能力。
  • 在水平扩展方案以及数据存储周期上,Graphite 做的更好。

Prometheus vs InfluxDB

  • InfluxDB 是一个开源的时序数据库,主要用于存储数据,如果想搭建监控告警系统, 需要依赖其他系统。
  • InfluxDB 在存储水平扩展以及高可用方面做的更好, 毕竟核心是数据库。

Prometheus vs OpenTSDB

  • OpenTSDB 是一个分布式时序数据库,它依赖 Hadoop 和 HBase,能存储更长久数据, 如果你系统已经运行了 Hadoop 和 HBase, 它是个不错的选择。
  • 如果想搭建监控告警系统,OpenTSDB 需要依赖其他系统。

Prometheus vs Nagios

  • Nagios 数据不支持自定义 Labels, 不支持查询,告警也不支持去噪,分组, 没有数据存储,如果想查询历史状态,需要安装插件。
  • Nagios 是上世纪 90 年代的监控系统,比较适合小集群或静态系统的监控,显然 Nagios 太古老了,很多特性都没有,相比之下Prometheus 要优秀很多。

Prometheus vs Sensu

  • Sensu 广义上讲是 Nagios 的升级版本,它解决了很多 Nagios 的问题,如果你对 Nagios 很熟悉,使用 Sensu 是个不错的选择。
  • Sensu 依赖 RabbitMQ 和 Redis,数据存储上扩展性更好。

总结

  • Prometheus 属于一站式监控告警平台,依赖少,功能齐全。
  • Prometheus 支持对云或容器的监控,其他系统主要对主机监控。
  • Prometheus 数据查询语句表现力更强大,内置更强大的统计函数。
  • Prometheus 在数据存储扩展性以及持久性上没有 InfluxDB,OpenTSDB,Sensu 好。

参考:

prometheus 监控概述(一)

prometheus 配置文件

prometheus之配置详解

Prometheus学习系列(十三)之配置解析

prometheus relabel 配置

Prometheus 配置文件中 metric_relabel_configs 配置

prometheus配置看着一篇就够了

-------------本文结束 感谢您的阅读-------------
作者Magiceses
有问题请 留言 或者私信我的 微博
满分是10分的话,这篇文章你给几分