初识Prometheus

Prometheus简介


Prometheus受启发于Google的Brogmon监控系统(相似的Kubernetes是从Google的Brog系统演变而来),从2012年开始由前Google工程师在Soundcloud以开源软件的形式进行研发,并且于2015年早期对外发布早期版本。2016年5月继Kubernetes之后成为第二个正式加入CNCF基金会的项目,同年6月正式发布1.0版本。2017年底发布了基于全新存储层的2.0版本,能更好地与容器平台、云平台配合。

功能特征


  • 多维数据模型(由度量名称和键值对标识的时间序列数据)
  • PromQL:一种强大且灵活的查询语言,可以利用多维数据完成复杂的查询
  • 不依赖分布式存储,单个服务器节点可直接工作
  • 基于HTTP的pull模式采集时间序列数据。
  • 可以使用pushgateway(prometheus的可选中间件)实现push模式。
  • 可以使用动态服务发现或静态配置发现目标。
  • 支持多种图形及仪表盘。
  • 支持分层与水平联合

Prometheus架构


Prometheus Server

Prometheus Server是监控系统的服务端,服务端通过服务发现的方式,抓取被监控服务的指标,或者通过pushgateway的间接抓取,抓取到指标数据后,通过特定的存储引擎进行存储,同时暴露一个HTTP服务,提供用 PromQL来进行数据查询。注意,Prometheus是定时采样数据,而不是全量数据。

Exporter

Prometheus需要服务暴露http接口,如果服务本身没有,我们不需要改造服务,可以通过exporter来间接获取。Exporter就充当了Prometheus采集的目标,而由各个exporter去直接获取指标。目前大多数的服务都有现成的exporter,我们不需要重复造轮子,拿来用即可,如MySQL,MongoDB等,可以参考这里

Push Gateway

Prometheus采集指标的方式主要有两种,一种是服务端暴露接口(Exporter),由Prometheus主动去抓取指标,称为pull模式。另一种是服务端主动上报,服务端将指标主动上报至Push Gateway,Prometheus再从 Push Gateway中获取,称为push模式。而Push Gateway就是push模式中重要的中介角色,用于暂存服务端上报的指标,等待Prometheus收集。

为什么要有两种模式呢?我们来比较一下这两种模式的特点。

  • Pull模式:Prometheus主动抓取的方式,可以由Prometheus服务端控制抓取的频率,简单清晰,控制权在Prometheus服务端。通过服务发现机制,可以自动接入新服务,去掉下线的服务,无需任何人工干预。对于各种常见的服务,官方或社区有大量Exporter来提供指标采集接口,基本无需开发。是官方推荐的方式。
  • Push模式:由服务端主动上报至Push Gateway,采集最小粒度由服务端决定,等于Push Gateway充当了中介的角色,收集各个服务主动上报的指标,然后再由Prometheus来采集。但是这样就存在了Push Gateway这个性能单点,而且Push Gateway也要处理持久化问题,不然宕机也会丢失部分数据。同时需要服务端提供主动上报的功能,可能涉及一些开发改动。不是首选的方式,但是在一些场景下很适用。例如,一些临时性的任务,存在时间可能非常短,如果采用Pull模式,可能抓取不到数据。

Alert Manager

Alert Manager是Prometheus的报警组件,当Prometheus服务端发现报警时,推送alert到Alert Manager,再由Alert Manager发送到通知端,如Email,Slack,微信,钉钉等。Alert Manager根据相关规则提供了报警的分组、聚合、抑制、沉默等功能。

Web UI/Grafana

Prometheus提供了一个简单的web UI界面,用于查询数据,查看告警、配置等,官方推荐使用另一个开源项目grafana来做指标的可视化展示,制作仪表盘等。

安装Prometheus Server


Prometheus基于Golang编写,编译后的软件包,不依赖于任何的第三方依赖。只需要下载对应平台的二进制包,解压并且添加基本的配置即可正常启动Prometheus Server。

二进制包安装

对于非Docker环境,可以在https://prometheus.io/download/根据操作系统架构类型找到最新版本的Prometheus Server安装包。

解压到/opt/目录,解压出来的目录中包含Prometheus二进制文件promtools二进制文件和默认的Prometheus配置文件prometheus.yml

1
2
3
tar zxf prometheus-2.29.1.linux-amd64.tar.gz -C /opt/
mv /opt/prometheus-2.29.1.linux-amd64/ /opt/prometheus
cd /opt/prometheus

Prometheus作为一个时间序列数据库,其采集的数据会以文件的形式存储在本地中,默认的存储路径为/data/,当启动Prometheus时会自动创建。也可以通过--storage.tsdb.path参数修改本地数据存储的路径

配置Prometheus作为系统服务进行管理

1
2
3
4
5
6
7
8
9
10
11
cat > /usr/lib/systemd/system/prometheus.service << EOF
[Unit]
Description=prometheus
[Service]
ExecStart=/opt/prometheus/prometheus --config.file=/opt/prometheus/prometheus.yml --storage.tsdb.path=/opt/prometheus/data/ --web.enable-lifecycle
ExecReload=/bin/kill -HUP \$MAINPID
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF

ExecStart为启动Prometheus的具体命令,需要确保二进制文件和配置文件路径与实际环境一致。若需进行其他参数的自定义配置,直接将参数追加到命令最后即可。以下为几个常用的配置参数:

参数 作用
--config.file=prometheus.yml 指定配置文件
--web.listen-address=0.0.0.0:9090 指定监听地址和端口
--log.level=info 设置日志级别
--alertmanager.timeout=10s 设置与报警组件的超时时间
--storage.tsdb.path=/data/ 指定数据目录
--storage.tsdb.retention.time=15d 设置数据保存时间,默认15天
--web.enable-lifecycle 开启热加载功能

启动Prometheus服务

1
2
3
systemctl daemon-reload
systemctl enable prometheus
systemctl start prometheus

正常情况下,如果启动成功通过systemctl status prometheus可以看到以下输出内容,关键信息为Server is ready to receive web requests.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
● prometheus.service - prometheus
Loaded: loaded (/usr/lib/systemd/system/prometheus.service; disabled; vendor preset: disabled)
Active: active (running) since Tue 2021-08-17 10:04:22 CST; 4s ago
Main PID: 1383 (prometheus)
CGroup: /system.slice/prometheus.service
└─1383 /opt/prometheus/prometheus --config.file=/opt/prometheus/prometheus.yml --storage.tsdb.path=/opt/prometheus/data/ --web.enable-lifecycle

Aug 17 10:04:22 prometheus-binary prometheus[1383]: level=info ts=2021-08-17T02:04:22.189Z caller=head.go:815 component=tsdb msg="Replaying on-disk m... if any"
Aug 17 10:04:22 prometheus-binary prometheus[1383]: level=info ts=2021-08-17T02:04:22.189Z caller=head.go:829 component=tsdb msg="On-disk memory mapp…on=5.273µs
Aug 17 10:04:22 prometheus-binary prometheus[1383]: level=info ts=2021-08-17T02:04:22.189Z caller=head.go:835 component=tsdb msg="Replaying WAL, this...a while"
Aug 17 10:04:22 prometheus-binary prometheus[1383]: level=info ts=2021-08-17T02:04:22.189Z caller=head.go:892 component=tsdb msg="WAL segment loaded"...egment=0
Aug 17 10:04:22 prometheus-binary prometheus[1383]: level=info ts=2021-08-17T02:04:22.189Z caller=head.go:898 component=tsdb msg="WAL replay complete…=350.257µs
Aug 17 10:04:22 prometheus-binary prometheus[1383]: level=info ts=2021-08-17T02:04:22.190Z caller=main.go:839 fs_type=EXT4_SUPER_MAGIC
Aug 17 10:04:22 prometheus-binary prometheus[1383]: level=info ts=2021-08-17T02:04:22.190Z caller=main.go:842 msg="TSDB started"
Aug 17 10:04:22 prometheus-binary prometheus[1383]: level=info ts=2021-08-17T02:04:22.190Z caller=main.go:969 msg="Loading configuration file" filena...heus.yml
Aug 17 10:04:22 prometheus-binary prometheus[1383]: level=info ts=2021-08-17T02:04:22.200Z caller=main.go:1006 msg="Completed loading of configuration file" …µs
Aug 17 10:04:22 prometheus-binary prometheus[1383]: level=info ts=2021-08-17T02:04:22.200Z caller=main.go:784 msg="Server is ready to receive web requests."
Hint: Some lines were ellipsized, use -l to show in full.

容器安装

容器安装的方式需先安装Docker环境,首先先配置docker-ce repository

1
2
3
4
5
6
7
8
9
# 安装所需要的包,yum-utils提供了yum-config-manager工具,device-mapper-persistent-data和lvm2是设备映射存储驱动所需要的
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2

# 设置稳定版的repo仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

说明
若无法访问国外网站,可配置国内阿里云的docker源

1
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo

配置好Docker仓库后,执行如下命令安装最新版Docker

1
2
# 安装最新版本的docker-ce
yum install docker-ce docker-ce-cli containerd.io -y

说明
若要安装指定版本的docker,按照如下步骤

1
2
3
4
5
# 列出repo仓库中可用的docker版本并降序排列
yum list docker-ce --showduplicates | sort -r

# 确认好要安装的版本,例如为18.09.9,则替换yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io -y中的<VERSION_STRING>进行安装
例如:yum install docker-ce-18.09.9 docker-ce-cli-18.09.9 containerd.io -y

启动Docker并设置开机自启

1
2
3
systemctl start docker
systemctl enable docker
systemctl status docker

设置阿里云镜像加速器(可选)

1
2
3
4
5
6
7
8
9
10
mkdir -p /etc/docker
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://lerc8rqe.mirror.aliyuncs.com"]
}
EOF

systemctl daemon-reload
systemctl restart docker
docker info

https://prometheus.io/download/根据操作系统架构类型找到最新版本的Prometheus Server安装包。

解压,将解压目录中的Prometheus配置文件prometheus.yml拷贝到/opt/prometheus目录中

1
2
3
4
5
tar zxf prometheus-2.29.1.linux-amd64.tar.gz
mkdir -p /opt/prometheus
cp -a prometheus-2.29.1.linux-amd64/prometheus.yml /opt/prometheus/
mkdir -p /opt/prometheus/data/
chmod 777 /opt/prometheus/data/

使用Prometheus的镜像启动Prometheus Server,将宿主机文件系统中的prometheus.yml文件挂载到容器中的/etc/prometheus/prometheus.yml,使用容器数据卷实现Prometheus数据持久化存储到宿主机上并设置容器名称为prometheus(便于后续对容器进行重启等操作)

1
docker run -d --restart=always --name=prometheus -p 9090:9090 -v /opt/prometheus/data:/prometheus -v /opt/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus:v2.29.1

访问Portal

启动完成后,可以通过http://<IP>:9090访问Prometheus的UI界面

Prometheus配置


官网文档:https://prometheus.io/docs/prometheus/latest/configuration/configuration/

Prometheus通过命令行标志和配置文件进行配置。虽然命令行标志配置了不可变的系统参数(例如存储位置、要保存在磁盘和内存中的数据等),但配置文件定义了与抓取作业及其实例相关的所有内容,以及要加载的规则文件。要查看所有可用的命令行标志,可运行./prometheus -h

Prometheus可以在运行时重新加载其配置。如果新配置的格式不正确,则不会应用更改。通过向Prometheus进程发送SIGHUP信号或向通过curl -X POST http://[IP]:[Port]/-/reload/-/reload发送HTTP POST请求,可以触发配置重新加载,这也将重新加载任何已配置的规则文件。

说明
热加载功能从2.0版本开始默认关闭,要在启动Prometheus时添加--web.enable-lifecycle标志

配置文件

要指定要加载的配置文件,可使用--config.file标志

该文件以YAML格式编写,由下面描述的方案定义。括号表示参数是可选的。对于非列表参数,该值设置为指定的默认值。

通用占位符定义如下:

  • <boolean>: 一个布尔值,可以取值truefalse
  • <duration>: 匹配正则表达式的持续时间((([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?|0),例如1d, 1h30m, 5m,10s
  • <filename>: 当前工作目录中的有效路径
  • <host>: 由主机名或IP后跟可选端口号组成的有效字符串
  • <int>: 一个整数值
  • <labelname>: 匹配正则表达式的字符串[a-zA-Z_][a-zA-Z0-9_]*
  • <labelvalue>: 一串unicode字符
  • <path>: 一个有效的URL路径
  • <scheme>: 一个可以取值的字符串httphttps
  • <secret>:作为秘密的常规字符串,例如密码
  • <string>: 普通字符串
  • <size>:以字节为单位的大小,例如512MB。需要一个单位。支持的单位:B、KB、MB、GB、TB、PB、EB。
  • <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
51
52
global:
# How frequently to scrape targets by default.
# 数据采集时间间隔,默认1分钟
[ scrape_interval: <duration> | default = 1m ]

# How long until a scrape request times out.
# 数据采集超时时间,默认10秒
[ scrape_timeout: <duration> | default = 10s ]

# How frequently to evaluate rules.
# 评估告警规则时间间隔,默认1分钟
[ evaluation_interval: <duration> | default = 1m ]

# The labels to add to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
# 和外部系统(联邦、远程存储、Alertmanager)通信时为时间序列或警报添加的标签列表
external_labels:
[ <labelname>: <labelvalue> ... ]

# File to which PromQL queries are logged.
# Reloading the configuration will reopen the file.
# 记录PromQL查询的文件,重新加载配置将重新打开该文件
[ query_log_file: <string> ]

# Rule files specifies a list of globs. Rules and alerts are read from
# all matching files.
# 规则文件指定一个全局的列表,从所有匹配的文件中读取规则和告警
rule_files:
[ - <filepath_glob> ... ]

# A list of scrape configurations.
# 抓取配置列表,用于配置被监控端,称为target,每个target用job_name分组管理,又分为静态配置和动态服务发现
scrape_configs:
[ - <scrape_config> ... ]

# Alerting specifies settings related to the Alertmanager.
# 告警配置
alerting:
alert_relabel_configs:
[ - <relabel_config> ... ]
alertmanagers:
[ - <alertmanager_config> ... ]

# Settings related to the remote write feature.
# 与远程写入功能相关的配置
remote_write:
[ - <remote_write> ... ]

# Settings related to the remote read feature.
# 与远程读取功能相关的配置
remote_read:
[ - <remote_read> ... ]

scrape_config部分指定一组目标和参数,描述如何对其进行抓取。在一般情况下,一个抓取配置指定单个作业。在高级配置中,这可能会改变。可以通过static_configs参数静态配置目标,也可以使用支持的服务发现机制之一动态发现目标。此外,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
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# The job name assigned to scraped metrics by default.
# 默认情况下分配给抓取指标的作业名称
job_name: <job_name>

# How frequently to scrape targets from this job.
# 配置这个job的数据采集时间间隔
[ scrape_interval: <duration> | default = <global_config.scrape_interval> ]

# Per-scrape timeout when scraping this job.
# 配置这个job的数据采集超时时间
[ scrape_timeout: <duration> | default = <global_config.scrape_timeout> ]

# The HTTP resource path on which to fetch metrics from targets.
# 从目标获取指标的HTTP资源路径
[ metrics_path: <path> | default = /metrics ]

# honor_labels controls how Prometheus handles conflicts between labels that are
# already present in scraped data and labels that Prometheus would attach
# server-side ("job" and "instance" labels, manually configured target
# labels, and labels generated by service discovery implementations).
#
# If honor_labels is set to "true", label conflicts are resolved by keeping label
# values from the scraped data and ignoring the conflicting server-side labels.
#
# If honor_labels is set to "false", label conflicts are resolved by renaming
# conflicting labels in the scraped data to "exported_<original-label>" (for
# example "exported_instance", "exported_job") and then attaching server-side
# labels.
#
# Setting honor_labels to "true" is useful for use cases such as federation and
# scraping the Pushgateway, where all labels specified in the target should be
# preserved.
#
# Note that any globally configured "external_labels" are unaffected by this
# setting. In communication with external systems, they are always applied only
# when a time series does not have a given label yet and are ignored otherwise.
#
# honor_labels控制Prometheus如何处理已存在于抓取数据中的标签与Prometheus将在服务器端附加的标签(“job”和“instance”标签、手动配置的目标标签以及由服务发现实现生成的标签)之间的冲突。
# 如果honor_labels设置为“true”,则通过保留来自抓取数据的标签值并忽略冲突的服务器端标签来解决标签冲突。
# 如果honor_labels设置为“false”,则通过将抓取数据中的冲突标签重命名为“exported_<original-label>”(例如“exported_instance”、“exported_job”)然后附加服务器端标签来解决标签冲突。
# 将honor_labels设置为“true”对于联邦和抓取Pushgateway等用例很有用,在这些用例中应保留目标中指定的所有标签。
# 请注意,任何全局配置的“external_labels”都不受此设置的影响。在与外部系统通信时,它们总是仅在时间序列还没有给定标签时才应用,否则将被忽略。
[ honor_labels: <boolean> | default = false ]

# honor_timestamps controls whether Prometheus respects the timestamps present
# in scraped data.
#
# If honor_timestamps is set to "true", the timestamps of the metrics exposed
# by the target will be used.
#
# If honor_timestamps is set to "false", the timestamps of the metrics exposed
# by the target will be ignored.
# honor_timestamps控制Prometheus是否遵循抓取数据中存在的时间戳
# 如果honor_timestamps配置为true,则使用被监控端暴露的指标的时间戳
# 如果honor_timestamps配置为false,则被监控端暴露的指标的时间戳会被忽略
[ honor_timestamps: <boolean> | default = true ]

# Configures the protocol scheme used for requests.
# 配置用于请求的协议,默认为http
[ scheme: <scheme> | default = http ]

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

# Sets the `Authorization` header on every scrape request with the
# configured username and password.
# password and password_file are mutually exclusive.
# 使用配置的用户名和密码在每个抓取请求上设置Authorization头部。密码和密码文件是互斥的
basic_auth:
[ username: <string> ]
[ password: <secret> ]
[ password_file: <string> ]

# Sets the `Authorization` header on every scrape request with
# the configured credentials.
# 使用配置的凭证在每个抓取请求上设置Authorization头部
authorization:
# Sets the authentication type of the request.
# 设置请求的身份验证类型
[ type: <string> | default: Bearer ]
# Sets the credentials of the request. It is mutually exclusive with
# `credentials_file`.
# 设置请求的凭证,和credentials_file是互斥的
[ credentials: <secret> ]
# Sets the credentials of the request with the credentials read from the
# configured file. It is mutually exclusive with `credentials`.
# 使用从配置文件读取的凭据设置请求的凭证,与credentials是互斥的
[ credentials_file: <filename> ]

# Optional OAuth 2.0 configuration.
# Cannot be used at the same time as basic_auth or authorization.
# 可选的OAuth2.0配置。不能与basic_auth和authorization同时使用
oauth2:
[ <oauth2> ]

# Configure whether scrape requests follow HTTP 3xx redirects.
# 设置抓取请求是否遵循HTTP 3xx重定向
[ follow_redirects: <bool> | default = true ]

# Configures the scrape request's TLS settings.
# 配置抓取请求的TLS设置
tls_config:
[ <tls_config> ]

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

# List of Azure service discovery configurations.
# Azure服务发现配置列表
azure_sd_configs:
[ - <azure_sd_config> ... ]

# List of Consul service discovery configurations.
# Consul服务发现配置列表
consul_sd_configs:
[ - <consul_sd_config> ... ]

# List of DigitalOcean service discovery configurations.
# DigitalOcean服务发现配置列表
digitalocean_sd_configs:
[ - <digitalocean_sd_config> ... ]

# List of Docker service discovery configurations.
# Docker服务发现配置列表
docker_sd_configs:
[ - <docker_sd_config> ... ]

# List of Docker Swarm service discovery configurations.
# Docker Swarm服务发现配置列表
dockerswarm_sd_configs:
[ - <dockerswarm_sd_config> ... ]

# List of DNS service discovery configurations.
# DNS服务发现配置列表
dns_sd_configs:
[ - <dns_sd_config> ... ]

# List of EC2 service discovery configurations.
# EC2服务发现配置列表
ec2_sd_configs:
[ - <ec2_sd_config> ... ]

# List of Eureka service discovery configurations.
# Eureka服务发现配置列表
eureka_sd_configs:
[ - <eureka_sd_config> ... ]

# List of file service discovery configurations.
# 文件服务发现配置列表
file_sd_configs:
[ - <file_sd_config> ... ]

# List of GCE service discovery configurations.
# GCE服务发现配置列表
gce_sd_configs:
[ - <gce_sd_config> ... ]

# List of Hetzner service discovery configurations.
# Hetzner服务发现配置列表
hetzner_sd_configs:
[ - <hetzner_sd_config> ... ]

# List of HTTP service discovery configurations.
# HTTP服务发现配置列表
http_sd_configs:
[ - <http_sd_config> ... ]

# List of Kubernetes service discovery configurations.
# Kubernetes服务发现配置列表
kubernetes_sd_configs:
[ - <kubernetes_sd_config> ... ]

# List of Kuma service discovery configurations.
# Kuma服务发现配置列表
kuma_sd_configs:
[ - <kuma_sd_config> ... ]

# List of Lightsail service discovery configurations.
# Lightsail服务发现配置列表
lightsail_sd_configs:
[ - <lightsail_sd_config> ... ]

# List of Linode service discovery configurations.
# Linode服务发现配置列表
linode_sd_configs:
[ - <linode_sd_config> ... ]

# List of Marathon service discovery configurations.
# Marathon服务发现配置列表
marathon_sd_configs:
[ - <marathon_sd_config> ... ]

# List of AirBnB's Nerve service discovery configurations.
# AirBnB's Nerve服务发现配置列表
nerve_sd_configs:
[ - <nerve_sd_config> ... ]

# List of OpenStack service discovery configurations.
# OpenStack服务发现配置列表
openstack_sd_configs:
[ - <openstack_sd_config> ... ]

# List of Scaleway service discovery configurations.
$ Scaleway服务发现配置列表
scaleway_sd_configs:
[ - <scaleway_sd_config> ... ]

# List of Zookeeper Serverset service discovery configurations.
# Zookeeper服务发现配置列表
serverset_sd_configs:
[ - <serverset_sd_config> ... ]

# List of Triton service discovery configurations.
# Triton服务发现配置列表
triton_sd_configs:
[ - <triton_sd_config> ... ]

# List of labeled statically configured targets for this job.
# 此job的静态配置目标列表
static_configs:
[ - <static_config> ... ]

# List of target relabel configurations.
# target重新标记配置列表
relabel_configs:
[ - <relabel_config> ... ]

# List of metric relabel configurations.
# 指标重新标记配置列表
metric_relabel_configs:
[ - <relabel_config> ... ]

# An uncompressed response body larger than this many bytes will cause the
# scrape to fail. 0 means no limit. Example: 100MB.
# This is an experimental feature, this behaviour could
# change or be removed in the future.
# 大于这个字节数的未压缩响应体将导致抓取失败。0表示没有限制。例如100MB,这是一个实验特征,这种行为在未来可能会改变或删除
[ body_size_limit: <size> | default = 0 ]
# Per-scrape limit on number of scraped samples that will be accepted.
# If more than this number of samples are present after metric relabeling
# the entire scrape will be treated as failed. 0 means no limit.
[ sample_limit: <int> | default = 0 ]

# Per-scrape limit on number of labels that will be accepted for a sample. If
# more than this number of labels are present post metric-relabeling, the
# entire scrape will be treated as failed. 0 means no limit.
[ label_limit: <int> | default = 0 ]

# Per-scrape limit on length of labels name that will be accepted for a sample.
# If a label name is longer than this number post metric-relabeling, the entire
# scrape will be treated as failed. 0 means no limit.
[ label_name_length_limit: <int> | default = 0 ]

# Per-scrape limit on length of labels value that will be accepted for a sample.
# If a label value is longer than this number post metric-relabeling, the
# entire scrape will be treated as failed. 0 means no limit.
[ label_value_length_limit: <int> | default = 0 ]

# Per-scrape config limit on number of unique targets that will be
# accepted. If more than this number of targets are present after target
# relabeling, Prometheus will mark the targets as failed without scraping them.
# 0 means no limit. This is an experimental feature, this behaviour could
# change in the future.
[ target_limit: <int> | default = 0 ]

更多配置参数可查看https://github.com/prometheus/prometheus/blob/main/config/testdata/conf.good.yml

监控指标数据模型

数据模型

  • Prometheus将所有数据存储为时间序列;
  • 具有相同度量名称以及标签属于同一个指标;
  • 每个时间序列都由度量标准名称和一组键值对(称为标签)唯一标识,通过标签查询指定指标。

指标格式

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

使用Node Export采集主机数据


安装Node Export采集主机数据

在Prometheus的架构设计中,Prometheus Server并不直接服务监控特定的目标,其主要任务负责数据的收集,存储并且对外提供数据查询支持。因此为了能够能够监控到某些东西,如主机的CPU使用率,我们需要使用到Exporter。Prometheus周期性的从Exporter暴露的HTTP服务地址(通常是/metrics)拉取监控样本数据。

从上面的描述中可以看出Exporter可以是一个相对开放的概念,其可以是一个独立运行的程序独立于监控目标以外,也可以是直接内置在监控目标中。只要能够向Prometheus提供标准格式的监控样本数据即可。

为了能够采集到主机的运行指标如CPU, 内存,磁盘等信息。可以使用Node Exporter。Node Exporter同样采用Golang编写,并且不存在任何的第三方依赖,只需要下载,解压即可运行。可以在https://prometheus.io/download/根据操作系统架构类型获取最新的node exporter版本的二进制包。

运行node exporter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
tar zxf node_exporter-1.2.2.linux-amd64.tar.gz 
cd node_exporter-1.2.2.linux-amd64
cp -a node_exporter /usr/local/bin/

# 将node-exporter配置为系统服务管理
cat > /usr/lib/systemd/system/node-exporter.service << EOF
[Unit]
Description=node-exporter
After=network.target
[Service]
ExecStart=/usr/local/bin/node_exporter
ExecReload=/bin/kill -HUP \$MAINPID
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable node-exporter
systemctl start node-exporter
systemctl status node-exporter

访问http://<IP>:9100可以看到以下页面

初识Node Exporter监控指标

访问http://<IP>:9100/metrics,可以看到当前node export获取到的当前主机的所有监控数据,如下所示。

每一个监控指标之前都会有一段类似于如下形式的信息:

1
2
3
4
5
6
# HELP node_cpu_seconds_total Seconds the CPUs spent in each mode.
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 386.33
# HELP node_load1 1m load average.
# TYPE node_load1 gauge
node_load1 0

其中HELP用于解释当前指标的含义,TYPE则说明当前指标的数据类型。在上面的例子中node_cpu_seconds_total的注释表明当前指标是cpu0上idle进程占用CPU的总时间,CPU占用时间是一个只增不减的度量指标,从类型中也可以看出node_cpu_seconds_total的数据类型是计数器(counter),与该指标的实际含义一致。又例如node_load1该指标反映了当前主机在最近一分钟以内的负载情况,系统的负载情况会随系统资源的使用而变化,因此node_load1反映的是当前状态,数据可能增加也可能减少,从注释中可以看出当前指标类型为仪表盘(gauge),与指标反映的实际含义一致。

除了这些以外,在当前页面中根据主机系统的不同,你还可能看到如下监控指标:

  • node_boot_time:系统启动时间
  • node_cpu:系统CPU使用量
  • node_disk_io*:磁盘IO
  • node_filesystem*:文件系统用量
  • node_load*:系统负载
  • node_memory*:内存使用量
  • node_network*:网络带宽
  • node_time*:当前系统时间
  • go_*:node exporter中go相关指标
  • process_*:node exporter自身进程相关运行指标

从Node Exporter收集监控数据

为了让Prometheus Server能够从当前node exporter获取到监控数据,这里需要修改Prometheus配置文件。编辑prometheus.yml并在scrape_configs节点下添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: "prometheus"

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

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

# 新增如下部分采集node exporter监控数据
- job_name: "node"
static_configs:
- targets: ["10.211.55.4:9100"]

重启Prometheus Server或者重新热加载配置文件

1
2
3
4
5
# 二进制包安装
systemctl restart/reload prometheus

# 容器安装,prometheus为容器名称
docker restart prometheus

访问http://<IP>:9090,进入到Prometheus Server。输入“up”并且单击Execute按钮,如果Prometheus能够正常从node exporter获取数据,则会看到以下执行结果,其中“1”表示正常,反之“0”则为异常。

1
2
up{instance="10.211.55.4:9100", job="node"}             1
up{instance="localhost:9090", job="prometheus"} 1

或者直接选择"Status"->"Targets",如果Prometheus能够正常从node exporter获取数据,可以看到targets的StateUP

使用PromQL查询监控数据


Prometheus UI是Prometheus内置的一个可视化管理界面,通过Prometheus UI用户能够轻松的了解Prometheus当前的配置,监控任务运行状态等。 通过Graph面板,用户还能直接使用PromQL实时查询监控数据

切换到Graph面板,用户可以使用PromQL表达式查询特定监控指标的监控数据。如下所示,查询主机负载变化情况,可以使用关键字node_load1可以查询出Prometheus采集到的主机负载的样本数据,这些样本数据按照时间先后顺序展示,形成了主机负载随时间变化的趋势图表

PromQL是Prometheus自定义的一套强大的数据查询语言,除了使用监控指标作为查询关键字以为,还内置了大量的函数,帮助用户进一步对时序数据进行处理。例如使用rate()函数,可以计算在单位时间内样本数据的变化情况即增长率,因此通过该函数我们可以近似的通过CPU使用时间计算CPU的利用率

1
rate(node_cpu_seconds_total[2m])

这时如果要忽略是哪一个CPU的,只需要使用without表达式,将标签CPU去除后聚合数据即可

1
avg without(cpu) (rate(node_cpu_seconds_total[2m]))

那如果需要计算系统CPU的总体使用率,通过排除系统闲置的CPU使用率即可获得

1
1 - avg without(cpu) (rate(node_cpu_seconds_total{mode='idle'}[2m]))

通过PromQL我们可以非常方便的对数据进行查询,过滤,以及聚合,计算等操作。通过这些丰富的表达书语句,监控指标不再是一个单独存在的个体,而是一个个能够表达出正式业务含义的语言。

监控数据可视化


Prometheus UI提供了快速验证PromQL以及临时可视化支持的能力,而在大多数场景下引入监控系统通常还需要构建可以长期使用的监控数据可视化面板(Dashboard)。这时可以考虑使用第三方的可视化工具如Grafana,Grafana是一个开源的可视化平台,并且提供了对Prometheus的完整支持。

官网安装文档:https://grafana.com/docs/grafana/latest/setup-grafana/installation/

RPM包安装

配置Grafana OSS releases Yum源

1
2
3
4
5
6
7
8
9
10
11
cat > /etc/yum.repos.d/grafana.repo << EOF
[grafana]
name=grafana
baseurl=https://packages.grafana.com/oss/rpm
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://packages.grafana.com/gpg.key
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
EOF

安装Grafana

1
yum install grafana -y

启动Grafana

1
2
3
4
systemctl daemon-reload
systemctl enable grafana-server
systemctl start grafana-server
systemctl status grafana-server

容器安装

直接使用Grafana镜像启动即可

1
docker run -d --restart=always -p 3000:3000 --name grafana grafana/grafana:8.1.1

安装完成后访问http://<IP>:3000就可以进入到Grafana的界面中,默认情况下使用账户admin/admin进行登录(首次登录会要求修改默认密码)。单击"Add your first data source"添加数据源

选择“Prometheus”,单击右侧的“Select”

配置“Name”,勾选“Default”“URL”填写Prometheus的访问地址,滑到最下方单击“Save & test”完成添加,配置正确的情况下会提示"Data source is working"的信息。

在完成数据源的添加之后就可以在Grafana中创建可视化Dashboard了,Grafana提供了对PromQL的完整支持。选择左侧"Dashboards"->"Manage"->"New Dashboard"->“Add an empty panel”。如下所示,在该面板选择“Data Source”"Prometheus",在“Metrics browser”选项下通过PromQL查询需要可视化的数据,“Title”部分设置可视化数据的指标名称。最后单击界面中右上角的“Save”选项,就创建了我们的第一个可视化Dashboard了。

也可以在https://grafana.com/dashboards找到大量可直接使用的Dashboard。Dashboard通过JSON进行共享,下载并且导入这些JSON文件,就可以直接在"Dashboards"->"Manage"->"Import"导入这些已经定义好的Dashboard。下图为导入的Node Exporter Quickstart and Dashboard