0%

Prometheus 监控系统搭建

本来这一篇应该有很多图才是的,但是这玩意加个图实在是太麻烦了,没有搞,主要讲讲流程。

这个系统的另一部分是 grafana,不过这里不说了,那个需要很多图才能说明白,可以自行搜索。

前言

本文不会细说 Prometheus 的原理、机制等,这里只是简单说一下,详细的还得自己去看文档

文档链接:prometheus

Prometheus 是什么?

简单来说,就是一个时序数据库(TSDB),它可以存储时序数据,也可以向外提供查询(通过 PromQL)。

Prometheus 的作用是什么?

  • 通过存储时序数据,让我们可以监控一些我们感兴趣的系统指标,如 CPU、内存 占用等,然后可以通过 AlertManager 来在指标到达阈值的时候告知相关人员。从而做出及时处理。

  • 另外一个方面,我们也可以通过历史时序数据来看到指标的变化趋势,从而在趋势发生的初期就做出处理。

Prometheus 能监控什么?

  • 服务器基础指标,只有你想不到,没有它监控不到,如:CPU、内存、磁盘、网络、甚至上下文切换次数等

  • 常见软件的监控,如 MySQL、MongoDB,这些软件通过一些 exporter 来采集,目前有很多现成的,覆盖了常见的软件。具体可以在 exporters 上找到

  • 自定义指标的监控,其实 Prometheus 采集的数据格式很简单,只要我们按照指定的格式返回一段 HTTP 文本就行。

Prometheus 工作机制

上面说了,Prometheus 的定位其实是一个数据库,所以在实际使用中,一般会配合使用 grafana 来将 Prometheus 采集到的数据展示为图表。

使用环境

  • CentOS 7 64位

Prometheus 安装

下载 Prometheus

下载地址:Prometheus

1
2
3
wget https://github.com/prometheus/prometheus/releases/download/v2.29.1/prometheus-2.29.1.linux-amd64.tar.gz
tar -xvf prometheus-2.29.1.linux-amd64.tar.gz
cd prometheus-2.29.1.linux-amd64

修改配置文件

prometheus.yml

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
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).

# Alertmanager configuration
#alerting:
# alertmanagers:
# - static_configs:
# - targets:
# - localhost:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
#rule_files:
# - "rules.yml"
# - "second_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=<job_name>` to any timeseries scraped from this config.
- job_name: 'server_status'

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

static_configs:
- targets: ['test1.com:9092', 'test2.com:9092', 'test3.com:9092']

relabel_configs:
- source_labels: [__address__]
target_label: instance
regex: '([^:]+)(:[0-9]+)?'
replacement: '${1}'

这里先把 alertingrule_files 的配置注释掉,后面安装了 AlertManager 之后再来配置。

需要注意的时候,到这一步的时候,我们的 prometheus 是还不能正常使用的,因为我们的数据源实际上还没有配置。

这里需要详细说明的是:

  • global.scrape_interval 间隔多久采集一次数据
  • scrape_configs 采集的数据源配置

scrape_configs 配置详解

这个是最核心的一个配置了,主要配置了我们的 Prometheus 需要从哪里采集数据,先说一下上面每一个配置项:

  • job_name 这个是区分我们的时序数据源类型的标识,这个标识是我们自己区分数据使用的,可以自定义。这里命名为 server_status 是因为我这个配置就是采集服务器的状态数据的。
  • static_configs 主要作用是配置我们的数据源地址
  • relabel_configs 我们在这个配置里面可以改写一些标签的值,比如上面这个配置会将 test1.com:9092 里面的端口移除,最后我们使用 PromQL 查询的时候就可以不填写端口了。

exporter 安装

Exporter 是什么?

Exporter 就是部署在我们要监控的服务器上,协助 Prometheus 采集数据的一个轻量的服务。(目标服务器->exporter)->Prometheus

Exporter 可以看作是一个 HTTP 服务器,它运行在我们的服务器上,当我们请求它的时候,它会去采集服务器上的指标数据,然后返回给发起请求的客户端。

比如,node_exporter,假设我们在 1.2.3.4:9092 这个服务器上启动了 node_exporter,当我们请求 http://1.2.3.4:9092/metrics 的时候,会返回如下数据:

1
2
3
4
5
6
7
8
9
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 2.8845e-05
go_gc_duration_seconds{quantile="0.25"} 4.7691e-05
go_gc_duration_seconds{quantile="0.5"} 8.7005e-05
go_gc_duration_seconds{quantile="0.75"} 0.000117043
go_gc_duration_seconds{quantile="1"} 0.002664528
go_gc_duration_seconds_sum 74.855671321
go_gc_duration_seconds_count 681610

这就是 exporter 返回的格式,HELP 说明接下来的数据是什么样的数据,而 TYPE 指定了接下来数据的类型。Prometheus 总共有四种数据类型,上面的 go_gc_duration_seconds 的类型为 summary

安装一个 node_exporter

到 node_exporter 的 releases 页面下载一个来安装:

1
2
3
wget https://github.com/prometheus/node_exporter/releases/download/v1.2.2/node_exporter-1.2.2.linux-amd64.tar.gz
tar -xvf node_exporter-1.2.2.linux-amd64.tar.gz
cd node_exporter-1.2.2.linux-amd64

启动 node_exporter

1
./node_exporter --web.listen-address=:9092

测试是否安装成功

1
curl http://1.2.3.4:9092

如果能返回类似上面格式的数据,说明我们的 exporter 部署成功了。

修改 Prometheus 配置

将里面的 scrape_configs 修改为以下内容:

1
2
3
4
5
6
7
8
9
10
11
scrape_configs:
- job_name: 'server_status'

static_configs:
- targets: ['1.2.3.4:9092']

relabel_configs:
- source_labels: [__address__]
target_label: instance
regex: '([^:]+)(:[0-9]+)?'
replacement: '${1}'

这里的 1.2.3.4 在我们配置的时候替换为实际的 ip 即可,这里的 relabel_configs 配置表明我们最终的目标主机地址的标签会替换为名字为 instance 的标签。

启动 Prometheus

到现在为止,我们的配置文件如下:

prometheus.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.

scrape_configs:
- job_name: 'server_status'

static_configs:
- targets: ['1.2.3.4:9092']

relabel_configs:
- source_labels: [__address__]
target_label: instance
regex: '([^:]+)(:[0-9]+)?'
replacement: '${1}'

我们使用这个配置文件来启动我们的 Prometheus 服务器:

1
prometheus --config.file=prometheus.yml --web.listen-address=:9091

这里的 --config.file 指定了配置文件的路径,--web.listen-address 指定了我们的 Prometheus 监听的地址。

测试

假设我们的 Prometheus 的服务器 ip 为 192.168.2.168,我们通过浏览器访问 http://192.168.2.168:9091 就可以看到我们的 Prometheus 自带的 web 页面,这个页面可以看到我们的采集目标是否正常运作(也就是上面的 scrape_configs 指定的地址能否正常访问),也可以通过 PromQL 来做一些查询。

Prometheus 报警规则设置

我们在 prometheus 安装目录下定义一个名字为 rules.yml 的配置文件,这个文件主要用来配置 Prometheus 的报警规则的。下面是一个示例文件:

rules.yml

1
2
3
4
5
6
7
8
9
10
11
groups:
- name: test_cpu_monitor
rules:
- alert: Cpu
expr: (1 - avg(rate(node_cpu_seconds_total{mode="idle"}[1m])) by (instance)) * 100 > 90
for: 1m
labels:
severity: "warning"
annotations:
summary: "{{ $labels.instance }} {{ $labels.job }} cpu usage larger than 90%"
description: "cpu usage {{ $labels.instance }}"
  • expr 是一个 PromQL 表达式,这个表达式的结果是 true 的时候,这个报警规则报警状态为 pending(还不会报警),如果 5 分钟之后,这个表达式依然是 true,则会触发报警。

我们可以使用 prometheus 安装目录下面的 promtool 来检查报警规则配置是否正确:

1
./promtool check config prometheus.yml

在增加了这个报警规则配置文件之后,接下来我们还需要修改 Prometheus 的配置文件,添加以下配置:

1
2
rule_files:
- "rules.yml"

AlertManager 安装配置

我们可以在官方的 github releases 上找到我们对应系统版本的安装包。

1
2
3
wget https://github.com/prometheus/alertmanager/releases/download/v0.23.0-rc.0/alertmanager-0.23.0-rc.0.linux-amd64.tar.gz
tar -xvf alertmanager-0.23.0-rc.0.linux-amd64.tar.gz
cd alertmanager-0.23.0-rc.0.linux-amd64

我们添加以下配置文件:

alertmanager.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
global:
smtp_smarthost: 'smtp.qq.com:25'
smtp_from: 'xx@qq.com'
smtp_auth_username: 'xxx@qq.com'
smtp_auth_password: 'xxyy'
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 1h
receiver: 'web.hook' # 发送报警信息给下面哪一个接收方,匹配 receivers 里面的 name
receivers:
- name: 'ruby'
email_configs:
- to: 'xx@gmail.com'
- name: 'web.hook'
webhook_configs:
- url: 'http://localhost:8010/dingtalk/webhook2/send'
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']

测试配置文件是否正确

在 alertmanager 的安装目录下面有一个名为 amtool 的文件,我们可以通过这个文件来检查我们的配置文件是否正确

1
./amtool check-config alertmanager.yml

安装配置钉钉 webhook

在这里我们就不使用邮件来发送了,我们使用钉钉来发送报警通知。

这里的报警需要用到钉钉机器人,具体可以搜索一下,然后去钉钉群里面配置一个即可。

prometheus-webhook-dingtalk

在 github 上已经有一个实现的钉钉报警webhook版本了,直接使用即可:

1
2
3
wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v2.0.0/prometheus-webhook-dingtalk-2.0.0.linux-amd64.tar.gz
tar -xvf prometheus-webhook-dingtalk-2.0.0.linux-amd64.tar.gz
cd prometheus-webhook-dingtalk-2.0.0.linux-amd64

我们在这个目录下创建一个 config.yml 配置文件:

1
2
3
targets:
webhook2:
url: https://oapi.dingtalk.com/robot/send?access_token=xxx

在这里其他无关的配置就不列出来了,关键的配置就这三行。url 就是我们钉钉机器人的请求地址。这个地址可以在配置钉钉机器人的界面获取。

启动 webhook

配置完之后,我们可以通过以下命令来启动:

1
./prometheus-webhook-dingtalk --config.file=config.yml --web.listen-address=:8010

修改 AlertManager 配置

在上一步启动的时候,我们会看到它输出了一个 webhook 地址,如 http://localhost:8010/dingtalk/webhook2/send,而这个地址就是沟通 alertmanager 跟 钉钉 的桥梁了。

我们在上面安装配置 AlertManager 那一步已经写入了这个配置,所以这一步就直接跳过了。

给 Prometheus 添加报警配置

我们安装了 AlertManager、也安装了钉钉报警的 webhook 服务,但是这个时候我们的 Prometheus 依然是不能报警的,我们还需要修改 Prometheus 的配置,让 Prometheus 在判断到需要报警的时候,去告知 AlertManager。

prometheus.yml 添加以下配置:

1
2
3
4
5
alerting:
alertmanagers:
- static_configs:
- targets:
- localhost:9093

这个 localhost:9093 是我们 AlertManager 监听的端口。

修改完配置之后,我们将 rules.yml 里面的 PromQL 表达式的报警值设置低一点,这样我们就可以看到报警了,待我们测试没有问题,再将报警值修改为我们预定的值即可。比如:

1
expr: (1 - avg(rate(node_cpu_seconds_total{mode="idle"}[1m])) by (instance)) * 100 > 1  # CPU 占用大于 1% 就报警

修改完 prometheus.yml 以及 rules.yml 这两个配置文件之后,重启一下 Prometheus,让配置生效。

不出意外的话,过 5 分钟我们就可以收到报警通知了。

最终的目录结构以及配置文件、启动命令

Prometheus

目录结构:

1
2
3
4
5
6
7
8
9
10
.
├── console_libraries
├── consoles
├── data
├── LICENSE
├── NOTICE
├── prometheus # prometheus 启动的入口文件
├── prometheus.yml # Prometheus 配置文件
├── promtool # 检查 prometheus 配置文件是否有效的工具
└── rules.yml # 报警规则配置,会在 prometheus.yml 引入
  1. prometheus.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.

alerting:
alertmanagers:
- static_configs:
- targets:
- localhost:9093

rule_files:
- "rules.yml"

scrape_configs:
- job_name: 'server_status'

static_configs:
- targets: ['1.2.3.4:9092'] # 这里为监控目标服务器上 node_exporter 的地址

relabel_configs:
- source_labels: [__address__]
target_label: instance
regex: '([^:]+)(:[0-9]+)?'
replacement: '${1}'
  1. rules.yml
1
2
3
4
5
6
7
8
9
10
11
groups:
- name: test_cpu_monitor
rules:
- alert: Cpu
expr: (1 - avg(rate(node_cpu_seconds_total{mode="idle"}[1m])) by (instance)) * 100 > 90 # cpu 占用大于 90 的时候报警
for: 1m
labels:
severity: "warning"
annotations:
summary: "{{ $labels.instance }} {{ $labels.job }} cpu usage larger than 90%"
description: "cpu usage {{ $labels.instance }}"

启动命令:

1
./prometheus --config.file=prometheus.yml --web.listen-address=:9091

node_exporter

这个需要在我们的目标服务器上安装,当然,我们也可以安装在 Prometheus 所在的服务器上。

目录结构:

1
2
3
├── LICENSE
├── node_exporter
└── NOTICE

这个没有需要配置的,启动的时候指定一个监听地址即可,如下:

启动命令:

1
./node_exporter --web.listen-address=:9092

AlertManager

目录结构:

1
2
3
4
5
6
├── alertmanager     # AlertManager 的启动入口文件
├── alertmanager.yml # AlertManager 配置文件
├── amtool # 检查配置文件是否有效的工具
├── data
├── LICENSE
└── NOTICE
  1. alertmanager.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
global:
smtp_smarthost: 'smtp.qq.com:25'
smtp_from: 'xx@qq.com'
smtp_auth_username: 'xx@qq.com'
smtp_auth_password: 'xx'
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 1h
receiver: 'web.hook'
receivers:
- name: 'web.hook'
webhook_configs:
- url: 'http://localhost:8010/dingtalk/webhook2/send'
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']

启动命令:

1
./alertmanager --config.file=alertmanager.yml

prometheus-webhook-dingtalk

目录结构:

1
2
3
4
5
├── config.example.yml          # 配置示例文件
├── config.yml # 实际使用的配置文件
├── contrib
├── LICENSE
└── prometheus-webhook-dingtalk # 启动的入口文件
  1. config.yml
1
2
3
targets:
webhook2:
url: https://oapi.dingtalk.com/robot/send?access_token=db655f2c0a13a5abc91368422e39d0e83bc397218047e66c24acf55af43e0fc2

启动命令:

1
./prometheus-webhook-dingtalk --config.file=config.yml --web.listen-address=:8010

再进一步

上面我们都是通过手动运行的方式来启动的,但是在实际应用中,我们可能会使用 supervisor 来配置。又或者有更高级的方式,k8s 然后服务发现啥的。