0%

Prometheus之Alertmanager钉钉报警配置

promentheus 官方没有钉钉插件,需要使用三方插件 prometheus-webhook-dingtalk

GitHub地址:https://github.com/timonwong/prometheus-webhook-dingtalk/

1 下载dingtalk

1
2
3
4
5
6
7
8
9
# 下载文件
wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v2.0.0/prometheus-webhook-dingtalk-2.0.0.linux-amd64.tar.gz

# 解压文件
tar xf prometheus-webhook-dingtalk-2.0.0.linux-amd64.tar.gz -C /usr/local/
chown root:root -R /usr/local/prometheus-webhook-dingtalk-2.0.0.linux-amd64/

# 建立软连
ln -sv /usr/local/prometheus-webhook-dingtalk-2.0.0.linux-amd64/ /usr/local/prometheus-webhook-dingtalk

2 dingtalk使用帮助

1
2
3
4
5
6
7
8
9
10
11
12
13
2.2 dingtalk使用帮助
usage: prometheus-webhook-dingtalk [<flags>]
Flags:
-h, --help Show context-sensitive help (also try --help-long and --help-man).
--web.listen-address=:8060
The address to listen on for web interface.
--web.enable-ui Enable Web UI mounted on /ui path
--web.enable-lifecycle Enable reload via HTTP request.
--config.file=config.yml Path to the configuration file.
--log.level=info Only log messages with the given severity or above. One of: [debug, info, warn, error]
--log.format=logfmt Output format of log messages. One of: [logfmt, json]
--version Show application version.

3 dingtalk配置文件

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
2.3 dingtalk配置文件
# 生成文件
touch /usr/local/prometheus-webhook-dingtalk/config.yml

# 配置文件
cat > /usr/local/prometheus-webhook-dingtalk/config.yml << \EOF
## Request timeout
timeout: 5s

## Customizable templates path
templates:
- contrib/templates/legacy/template.tmpl

## You can also override default template using `default_message`
## The following example to use the 'legacy' template from v0.3.0
default_message:
title: '{{ template "legacy.title" . }}'
text: '{{ template "legacy.content" . }}'

## Targets, previously was known as "profiles"
targets:
webhook1:
url: https://oapi.dingtalk.com/robot/send?access_token=412c7cef2c39d96e565a54156b8aec88e02ec94ef19c0e096a6821e10f3430b9
# secret for signature
secret: secret
webhook_mention_all:
url: https://oapi.dingtalk.com/robot/send?access_token=412c7cef2c39d96e565a54156b8aec88e02ec94ef19c0e096a6821e10f3430b9
secret: secret
mention:
all: true
webhook_mention_users:
url: https://oapi.dingtalk.com/robot/send?access_token=412c7cef2c39d96e565a54156b8aec88e02ec94ef19c0e096a6821e10f3430b9
mention:
mobiles: ['13520642397']
EOF


# 查看内容
cat /usr/local/prometheus-webhook-dingtalk/config.yml

4 添加dingtalk.service文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 生成文件
touch /lib/systemd/system/dingtalk.service
# 配置文件
cat > /lib/systemd/system/dingtalk.service << \EOF
[Unit]
Descripton=dingtalk
Documentation=https://github.com/timonwong/prometheus-webhook-dingtalk/
After=network.target

[Service]
Restart=on-failure
WorkingDirectory=/usr/local/prometheus-webhook-dingtalk
ExecStart=/usr/local/prometheus-webhook-dingtalk/prometheus-webhook-dingtalk --config.file=/usr/local/prometheus-webhook-dingtalk/config.yml

[Install]
WantedBy=multi-user.target
EOF

# 检查配置文件
cat /lib/systemd/system/dingtalk.service

5 设置dingtalk开机启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2.5 设置dingtalk开机启动
~# systemctl enable dingtalk
Created symlink /etc/systemd/system/multi-user.target.wants/dingtalk.service → /lib/systemd/system/dingtalk.service.
~# systemctl start dingtalk
~# systemctl status dingtalk
● dingtalk.service
Loaded: loaded (/lib/systemd/system/dingtalk.service; disabled; vendor preset: enabled)
Active: active (running) since Wed 2021-12-01 14:29:35 CST; 4s ago
Docs: https://github.com/timonwong/prometheus-webhook-dingtalk/
Main PID: 26590 (prometheus-webh)
Tasks: 7 (limit: 7069)
Memory: 2.5M
CGroup: /system.slice/dingtalk.service
└─26590 /usr/local/prometheus-webhook-dingtalk/prometheus-webhook-dingtalk --config.file=/usr/local/prometheus>

Dec 01 14:29:35 nacos-03 systemd[1]: Started dingtalk.service.
Dec 01 14:29:35 nacos-03 prometheus-webhook-dingtalk[26590]: level=info ts=2021-12-01T06:29:35.918Z caller=main.go:60 msg=">
Dec 01 14:29:35 nacos-03 prometheus-webhook-dingtalk[26590]: level=info ts=2021-12-01T06:29:35.918Z caller=main.go:61 msg=">
Dec 01 14:29:35 nacos-03 prometheus-webhook-dingtalk[26590]: level=info ts=2021-12-01T06:29:35.918Z caller=coordinator.go:8>
Dec 01 14:29:35 nacos-03 prometheus-webhook-dingtalk[26590]: level=info ts=2021-12-01T06:29:35.919Z caller=coordinator.go:9>
Dec 01 14:29:35 nacos-03 prometheus-webhook-dingtalk[26590]: level=info ts=2021-12-01T06:29:35.919Z caller=main.go:98 compo>
Dec 01 14:29:35 nacos-03 prometheus-webhook-dingtalk[26590]: ts=2021-12-01T06:29:35.920Z caller=main.go:114 component=confi>
Dec 01 14:29:35 nacos-03 prometheus-webhook-dingtalk[26590]: level=info ts=2021-12-01T06:29:35.920Z caller=web.go:210 compo>

6 验证dingtalk端口

1
2
3
4
5
6
2.6 验证dingtalk端口
~# lsof -i :8060
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
prometheu 26590 root 3u IPv6 100982 0t0 TCP *:8060 (LISTEN)


7 集成 设置alertmanager

设置alertmanager 修改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
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
global:
resolve_timeout: 5m
# 发件人
smtp_from: '13520642397@139.com'
# 邮箱服务器的 POP3/SMTP 主机配置 smtp.qq.com 端口为 465 或 587
smtp_smarthost: 'smtp.139.com:25'
# 用户名
smtp_auth_username: '13520642397@139.com'
# 授权码 或 密码
smtp_auth_password: 'secret'
#smtp_auth_secret: 'secret'
smtp_require_tls: false
smtp_hello: '139.com'
templates:
# 指定预警内容模板
- '/etc/alertmanager/template/email.tmpl'
route:
# 指定通过什么字段进行告警分组(如:alertname=A和alertname=B的将会被分导两个组里面)
group_by: ['alertname']
# 在组内等待所配置的时间,如果同组内,5 秒内出现相同报警,在一个组内出现
group_wait: 5s
# 如果组内内容不变化,合并为一条警报信息,5 分钟后发送
group_interval: 5m
# 发送告警间隔时间 s/m/h,如果指定时间内没有修复,则重新发送告警
repeat_interval: 5m
# 默认的receiver。 如果一个报警没有被任何一个route匹配,则发送给默认的接收器
receiver: 'keendataMail'
#子路由(上面所有的route属性都由所有子路由继承,并且可以在每个子路由上进行覆盖)
routes:
- receiver: dingding.webhook1
continue: true
# 当触发当前预警的prometheus规则满足:标签alarmClassify的为normal时(标签名、标签值可以自定义,只要和编写的prometheus的rule里面设置的标签呼应上即可),往keendataMail发送邮件
- receiver: keendataMail
match_re:
alarmClassify: normal
# 当触发当前预警的prometheus规则满足:标签alarmClassify的值为special时(标签名、标签值可以自定义,只要和编写的prometheus的rule里面设置的标签呼应上即可),往QQemail发送邮件
- receiver: QQemail
match_re:
alarmClassify: special
receivers:
#
- name: 'dingding.webhook1'
webhook_configs:
- url: 'http://192.168.12.218:8060/dingtalk/webhook1/send'
send_resolved: true
- name: 'keendataMail'
email_configs:
# 如果想发送多个人就以 ',' 做分割
- to: 'zhangyichao@keendata.com'
send_resolved: true
# 接收邮件的标题
headers: {Subject: "alertmanager报警邮件"}
- name: 'QQemail'
email_configs:
# 如果想发送多个人就以 ',' 做分割
- to: '758829146@qq.com'
send_resolved: true
# 接收邮件的标题
headers: {Subject: "alertmanager报警邮件"}
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']


3.2 重启Alertmanager服务
~# systemctl restart alertmanager.service

参考材料

https://www.cnblogs.com/wangguishe/p/15629091.html

1、概念简述

prometheus(普罗米修斯):天生为采集存储监控数据而生的时序数据库。prometheus通过各种Exporter采集到监控数据,然后存储进prometheus中,以供查询展示

grafana:一个监控仪表系统。grafana的数据来源可以有很多(如:Prometheus、Graphite、OpenTSDB、InfluxDB、MySQL/PostgreSQL、Microsoft SQL Serve等等),其中用得最多的数据源是prometheus

注:prometheus也有自己的UI,不过功能没有grafana强大

img

2、安装 prometheus

第一步:确保安装有docker

查看docker版本

1
docker -v

image-20250222171904465

第二步:拉取镜像

1
2
#你也可以直接拉docker pull prom/prometheus, 即拉取最新的镜像docker pull prom/prometheus:lastest
docker pull prom/prometheus:v3.2.0

第三步:准备相关挂载目录及文件

准备目录

1
2
3
4
5
6
7
8
# /opt/prom/data目录,准备用来挂载放置prometheus的数据
# /opt/prom/config目录,准备用来放置prometheus的配置文件
# /opt/prom/rules目录,准备用来挂载放置prometheus的规则文件
mkdir -p /opt/prom/{data,config,rules}
# 授权相关文件夹权限
chmod -R 777 /opt/prom/data
chmod -R 777 /opt/prom/config
chmod -R 777 /opt/prom/rules

准备文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 配置文件
cat > /opt/prom/config/prometheus.yml << \EOF
global:
# 数据采集间隔
scrape_interval: 45s
# 告警检测间隔
evaluation_interval: 45s

# 告警规则
rule_files:
# 这里匹配指定目录下所有的.rules文件
- /prometheus/rules/*.rules

# 采集配置
scrape_configs:
# 采集项(prometheus)
- job_name: 'prometheus'
static_configs:
# prometheus自带了对自身的exporter监控程序,所以不需额外安装exporter就可配置采集项
- targets: ['localhost:9090']
EOF

# 查看一下配置文件
cat /opt/prom/config/prometheus.yml

prometheus配置项说明

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

    第四步:启动容器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 启动prometheus
    # config.file:指定容器中,配置文件的位置
    # web.enable-lifecycle:启动此项后,当配置文件发生变化后,可通过HTTP API 发送 post 请求到 /-/reload,实现热加载,如:curl -X POST http://47.105.39.189:9090/-/reload
    # -v /etc/localtime:/etc/localtime:ro表示让容器使用宿主机的时间, :ro表示只读(注:此方式只针对宿主机和容器的时区文件均为/etc/localtime)
    docker run --name prometheus -d \
    -p 9090:9090 \
    -v /etc/localtime:/etc/localtime:ro \
    -v /opt/prom/data:/prometheus/data \
    -v /opt/prom/config:/prometheus/config \
    -v /opt/prom/rules:/prometheus/rules \
    prom/prometheus:v3.2.0 --config.file=/prometheus/config/prometheus.yml --web.enable-lifecycle

    第五步:访问测试

    访问{ip}:9090即可
    image-20250222172031261

3、安装 grafana

第一步:确保安装有docker

略过 参考安装 prometheus 过程

第二步:拉取镜像

镜像有哪些版本,可以通过查看一个docker镜像有哪些版本查看

1
2
# 你也可以直接拉docker pull grafana/grafana, 即拉取最新的镜像docker pull grafana/grafana:lastest
docker pull grafana/grafana:11.5.2

第三步:准备相关挂载目录及文件

准备目录

1
2
3
4
5
6
7
8
# /opt/grafana/data目录,准备用来挂载放置grafana的数据
# /opt/grafana/plugins目录,准备用来放置grafana的插件
# /opt/grafana/config目录,准备用来挂载放置grafana的配置文件
mkdir -p /opt/grafana/{data,plugins,config}
# 授权相关文件夹权限
chmod -R 777 /opt/grafana/data
chmod -R 777 /opt/grafana/plugins
chmod -R 777 /opt/grafana/config

准备配置文件

1
2
3
4
5
6
7
8
9
10
# 先临时启动一个容器
docker run --name grafana-tmp -d -p 3000:3000 grafana/grafana:11.5.2
# 将容器中默认的配置文件拷贝到宿主机上
docker cp grafana-tmp:/etc/grafana/grafana.ini /opt/grafana/config/grafana.ini
# 移除临时容器
docker stop grafana-tmp
docker rm grafana-tmp

# 修改配置文件(需要的话)
# vim /opt/grafana/config/grafana.ini

第四步:启动容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 启动prometheus
# 环境变量GF_SECURITY_ADMIN_PASSWORD:指定admin的密码
# 环境变量GF_INSTALL_PLUGINS:指定启动时需要安装得插件
# grafana-clock-panel代表时间插件
# grafana-simple-json-datasource代表json数据源插件
# grafana-piechart-panel代表饼图插件
docker run -d \
-p 3000:3000 \
--name=grafana \
-v /etc/localtime:/etc/localtime:ro \
-v /opt/grafana/data:/var/lib/grafana \
-v /opt/grafana/plugins/:/var/lib/grafana/plugins \
-v /opt/grafana/config/grafana.ini:/etc/grafana/grafana.ini \
-e "GF_SECURITY_ADMIN_PASSWORD=admin" \
-e "GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource,grafana-piechart-panel" \
grafana/grafana:11.5.2

第五步:访问测试

访问{ip}:3000即可,使用账密admin/admin进行登录即可
image-20250222172312466

第六步:使用测试

1、添加数据源
image-20250222172435959
选择普罗米修斯作为数据源
image-20250222172752988
image-20250222172823827
保存按钮在最下面
image-20250222172906934

2、制作(或导入)仪表盘
grafana官网提供了很多模板,选择你喜欢的样式,直接输入Dashboard Id即可直接导入
这里列出几个本人使用的Dashboard Id
监控模版ID: 12633:Linux主机详情
image-20250222173029462

image-20250222173115439 image-20250222173209598

此时,界面就出来了
提示:这会儿还没有数据,是因为prometheus里面本来就没有数据,后面我们只需要使用相应的exporter往prometheus录入一些监控数据(如:安装node-exporter),这里就会显示出来了
在这里插入图片描述

4、安装 node-exporter

安装exporter监控采集程序,采集数据进prometheus
node-exporter

官方不建议通过Docekr方式部署node-exporter,因为它需要访问主机系统
node-exporter 可以采集机器(物理机、虚拟机、云主机等)的监控指标数据,能够采集到的指标包括 CPU, 内存,磁盘,网络,文件数等信息

1、安装node-exporter

1
2
3
4
5
6
7
8
9
10
# 下载
#wget https://github.com/prometheus/node_exporter/releases/download/v1.1.2/node_exporter-1.1.2.linux-amd64.tar.gz
https://github.com/prometheus/node_exporter/releases/download/v1.9.0/node_exporter-1.9.0.linux-amd64.tar.gz

# 解压
tar -xvf node_exporter-1.9.0.linux-amd64.tar.gz
cd /opt/prom/node_exporter-1.9.0.linux-amd64

# 启动
nohup ./node_exporter --web.listen-address=":9101" &

2、访问一下,确保node-exporter已正常启动

或者直接curl 192.168.12.218:9101 进行验证也可

image-20250219195954314

3、在prometheus中配置当前采集项
编辑配置文件

1
vim /opt/prom/config/prometheus.yml

增加当前采集项目

1
2
3
4
# node-exporter 采集主机信息
- job_name: 'node-exporter-hdp216-218'
static_configs:
- targets: ['192.168.12.216:9101','192.168.12.217:9101','192.168.12.218:9101']

完整配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
global:
# 数据采集间隔
scrape_interval: 45s
# 告警检测间隔
evaluation_interval: 45s

# 告警规则
rule_files:
# 这里匹配指定目录下所有的.rules文件
- /prometheus/rules/*.rules

# 采集配置
scrape_configs:
# 采集项(prometheus)
- job_name: 'prometheus'
static_configs:
# prometheus自带了对自身的exporter监控程序,所以不需额外安装exporter就可配置采集项
- targets: ['localhost:9090']
# node-exporter 采集主机信息
- job_name: 'node-exporter-hdp216-218'
static_configs:
- targets: ['192.168.12.216:9101','192.168.12.217:9101','192.168.12.218:9101']

4、使得最新的prometheus配置生效

你可以重启prometheus或者使用热加载使新配置生效,这里我们使用热加载的方式

1
2
3
# 前提条件:启动prometheus时,启用了web.enable-lifecycle
# 发送post请求到prometheus的/-/reload下触发热加载配置
curl -X POST http://192.168.12.218:9090/-/reload

注:若你触发热加载后,过个一会儿还没看到监控的变化, 那么你可以使用docker logs {prometheus容器}查看prometheus日志,看到底是否触发了热加载

1
2
# 参考命令
docker logs --tail=1000 -f ./prometheus

5、验证一下

此时,我们再在grafana上看监控面板,就会发现有数据了
image-20250222173534169

5、安装 alertmanager

安装alertmanager, 集成进 prometheus

第一步:确保安装有docker

略过 参考安装 prometheus 过程

第二步:拉取镜像

镜像有哪些版本,可以通过查看一个docker镜像有哪些版本查看

1
2
# 你也可以直接拉docker pull prom/alertmanager, 即拉取最新的镜像docker pull prom/alertmanager:lastest
docker pull prom/alertmanager:v0.28.0

第三步:准备相关挂载目录及文件

准备目录

1
2
3
4
5
6
# /opt/alertmanager/config目录,准备用来放置alertmanager的配置文件
# /opt/alertmanager/template目录,准备用来挂载放置alertmanager的模板文件
mkdir -p /opt/alertmanager/{config,template}
# 授权相关文件夹权限
chmod -R 777 /opt/alertmanager/config
chmod -R 777 /opt/alertmanager/template

准备配置文件

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
# 配置文件
cat > /opt/alertmanager/config/alertmanager.yml << \EOF
global:
resolve_timeout: 5m
# 发件人
smtp_from: 'yichao0803@163.com'
# 邮箱服务器的 POP3/SMTP 主机配置 smtp.qq.com 端口为 465 或 587
smtp_smarthost: 'smtp.163.com'
# 用户名
smtp_auth_username: 'yichao0803@163.com'
# 授权码 或 密码
smtp_auth_password: '你的授权码'
smtp_require_tls: false
smtp_hello: '163.com'
templates:
# 指定预警内容模板
- '/etc/alertmanager/template/email.tmpl'
route:
# 指定通过什么字段进行告警分组(如:alertname=A和alertname=B的将会被分导两个组里面)
group_by: ['alertname']
# 在组内等待所配置的时间,如果同组内,5 秒内出现相同报警,在一个组内出现
group_wait: 5s
# 如果组内内容不变化,合并为一条警报信息,5 分钟后发送
group_interval: 5m
# 发送告警间隔时间 s/m/h,如果指定时间内没有修复,则重新发送告警
repeat_interval: 5m
# 默认的receiver。 如果一个报警没有被任何一个route匹配,则发送给默认的接收器
receiver: 'justrydeng163email'
#子路由(上面所有的route属性都由所有子路由继承,并且可以在每个子路由上进行覆盖)
routes:
# 当触发当前预警的prometheus规则满足:标签alarmClassify的为normal时(标签名、标签值可以自定义,只要和编写的prometheus的rule里面设置的标签呼应上即可),往justrydeng163email发送邮件
- receiver: justrydeng163email
match_re:
alarmClassify: normal
# 当触发当前预警的prometheus规则满足:标签alarmClassify的值为special时(标签名、标签值可以自定义,只要和编写的prometheus的rule里面设置的标签呼应上即可),往justrydengQQemail发送邮件
- receiver: justrydengQQemail
match_re:
alarmClassify: special
receivers:
- name: 'justrydeng163email'
email_configs:
# 如果想发送多个人就以 ',' 做分割
- to: '13548417409@163.com'
send_resolved: true
# 接收邮件的标题
headers: {Subject: "alertmanager报警邮件"}
- name: 'justrydengQQemail'
email_configs:
# 如果想发送多个人就以 ',' 做分割
- to: '1249823187@qq.com'
send_resolved: true
# 接收邮件的标题
headers: {Subject: "alertmanager报警邮件"}
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
EOF

# 查看一下配置文件
cat /opt/alertmanager/config/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
25
26
# 因为我们进行了挂载,所以我们只需编辑宿主机上的模板文件即可
cat > /opt/alertmanager/template/email.tmpl << \EOF
{{ define "email.html" }}
<table border="1">
<tr>
<td>报警项</td>
<td>实例</td>
<td>报警阀值</td>
<td>开始时间</td>
<td>告警信息</td>
</tr>
{{ range $i, $alert := .Alerts }}
<tr>
<td>{{ index $alert.Labels "alertname" }}</td>
<td>{{ index $alert.Labels "instance" }}</td>
<td>{{ index $alert.Annotations "value" }}</td>
<td>{{ $alert.StartsAt }}</td>
<td>{{ index $alert.Annotations "description" }}</td>
</tr>
{{ end }}
</table>
{{ end }}
EOF

# 查看一下模板文件
cat /opt/alertmanager/template/email.tmpl

提示:模板文件中,占位符取值,取的是prometheus的rules文件中对应的值,你可以先写好prometheus的规则文件后,再来编写模板文件

第四步:启动容器

1
2
3
4
5
6
7
# 启动alertmanager (启动后docker ps检查一下,确保alertmanager起来了即可)
docker run -d --name=alertmanager \
-p 9093:9093 \
-v /etc/localtime:/etc/localtime:ro \
-v /opt/alertmanager/config/alertmanager.yml:/etc/alertmanager/alertmanager.yml \
-v /opt/alertmanager/template:/etc/alertmanager/template \
prom/alertmanager:v0.28.0

第五步:确保alertmanager正常启动

1
2
3
4
# 查看一下docker容器
docker ps | grep alertmanager
# 再看一下alertmanager的日志
docker logs --tail=50 alertmanager

6、集成进prometheus

第一步:启用alertmanager

编辑配置文件

1
vim /opt/prom/config/prometheus.yml

启用alertmanager

1
2
3
4
5
6
7
# 启用alertmanager
alerting:
alertmanagers:
- static_configs:
- targets:
# alertmanager的地址
- 192.168.12.218:9093

第二步:增加prometheus预警规则

提示:prometheus的rules机制,即便不集成alertmanager也是可以用的

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
# 因为我们启动prometheus时,是挂载了宿主机的/opt/prom/rules目录到/prometheus/rules下,且配置了/prometheus/rules目录下所有的.rules文件都会被作为规则文件的
# 所以我们只需要将规则文件创建到宿主机的/opt/prom/rules目录下即可
cat > /opt/prom/rules/os.rules << \EOF
groups:
- name: os
rules:
# prometheus是通过对应exporter的metric指标查询接口获取到被监测对象的数据的。当这个接口调用不通(或调用出错时),会认为up == 0,当持续时间满足for时,会发出对应的节点宕机预警
# 实际上,exporter的指标查询接口调不通,也可能是因为超时或者其它什么导致的,并不一定是被监控节点down机了
- alert: instance不可用(宕机或忙)告警
expr: up == 0
for: 1m
labels:
alarmClassify: normal
annotations:
summary: "监控程序{{ $labels.job }}所监控机器不可用"
description: "监控程序 {{ $labels.job }}(监控程序地址为{{ $labels.instance }}) down机超过1分钟了"
- alert: CPU告警
expr: 100-(avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by(instance)* 100) > 90
for: 5m
labels:
alarmClassify: normal
annotations:
summary: "CPU告警:CPU使用大于90%(目前使用:{{$value}}%)"
description: "CPU告警:监控程序{{$labels.instance}}所监控机器的CPU使用大于90%(目前使用:{{$value}}%). 已经持续5分钟了"
- alert: 内存告警
expr: 100 - ((node_memory_MemAvailable_bytes * 100) / node_memory_MemTotal_bytes) > 90
for: 30m
labels:
alarmClassify: normal
annotations:
summary: "内存告警:内存使用大于80%(目前使用:{{$value}}%)"
description: "内存告警:监控程序{{$labels.instance}}所监控机器的内存使用大于80%(目前使用:{{$value}}%)"
- alert: 磁盘分区使用率报警
expr: 100 - ((node_filesystem_avail_bytes{fstype=~"rootfs|xfs",mountpoint=~"/|/etc/hosts"} * 100) / node_filesystem_size_bytes{fstype=~"rootfs|xfs",mountpoint=~"/|/etc/hosts"}) > 80
for: 1m
labels:
alarmClassify: normal
annotations:
summary: "磁盘分区告警:{{$labels.mountpoint}} 磁盘分区使用大于80%(目前使用:{{$value}}%)"
description: "磁盘分区告警:监控程序{{$labels.instance}}所监控机器的磁盘分区使用量大于80%(目前使用:{{$value}}%). 其它信息:device:{{$labels.device}}, mount:{{$labels.mountpoint}} "
- alert: 挂载磁盘分区使用率报警
expr: 100 - ((node_filesystem_avail_bytes{mountpoint=~"/rootfs/newDisk|/backup"} * 100) / node_filesystem_size_bytes{mountpoint=~"/rootfs/newDisk|/backup"}) > 80
for: 1m
labels:
alarmClassify: normal
annotations:
summary: "挂载磁盘分区告警:{{$labels.mountpoint}} 挂载磁盘分区使用大于80%(目前使用:{{$value}}%)"
description: "挂载磁盘分区告警:监控程序{{$labels.instance}}所监控机器的挂载磁盘分区使用量大于80%(目前使用:{{$value}}%). 其它信息:device:{{$labels.device}}, mount:{{$labels.mountpoint}} "
- alert: IO性能
expr: ((irate(node_disk_io_time_seconds_total[30m]))* 100) > 95
for: 1m
labels:
alarmClassify: normal
annotations:
summary: "{{$labels.mountpoint}} 流入磁盘IO使用率过高"
description: "监控程序{{$labels.instance}}所监控机器的{{$labels.mountpoint }}流入磁盘IO大于95%(目前使用:({{$value}}))"
- alert: 网络(入)
expr: ((sum(rate (node_network_receive_bytes_total{device!~'tap.*|veth.*|br.*|docker.*|virbr*|lo*'}[5m])) by (instance)) / 100) > 10240
for: 5m
labels:
alarmClassify: normal
annotations:
summary: "{{$labels.mountpoint}} 流入网络带宽过高"
description: "监控程序{{$labels.instance}}所监控机器的 {{$labels.mountpoint }} 流入网络带宽持续5分钟高于10Mb. RX带宽使用率{{$value}}"
- alert: 网络(出)
expr: ((sum(rate (node_network_transmit_bytes_total{device!~'tap.*|veth.*|br.*|docker.*|virbr*|lo*'}[5m])) by (instance)) / 100) > 10240
for: 5m
labels:
alarmClassify: normal
annotations:
summary: "{{$labels.mountpoint}} 流出网络带宽过高"
description: "监控程序{{$labels.instance}}所监控机器的 {{$labels.mountpoint }} 流出网络带宽持续5分钟高于10Mb. RX带宽使用率{{$value}}"
EOF

# 查看一下os.rules规则
cat /opt/prom/rules/os.rules

一条告警规则主要由以下几部分组成:

  • alert:告警规则的名称
  • expr:基于PromQL表达式告警触发条件,用于计算是否有时间序列满足该条件
  • for:评估等待时间,可选参数。用于表示只有当触发条件持续一段时间后才发送告警。在等待期间新产生告警的状态为pending
  • labels:自定义标签,允许用户指定要附加到告警上的一组附加标签(注:如果自定义的标签名与prometheus.yml下内置的或配置的标签名一样,则会以这里设置的标签为主)
    注:labels下标签 = prometheus.yml下设置的标签(scrape_configs.job_name[].static_configs.labels[]) + rule文件中用户设置的标签(groups.rules.alert[].labels[])
    注:labels下默认有这些标签
    • alertname:告警规则的名称(即:alert指定的名称)
    • device:机器设备
    • fstype:文件系统类型
    • mountpoint:挂载点
    • job:采集任务名。(即:当前预警所属采集任务名,假设prometheus.yml如下所示,采集项aliyun-node预警了,那么这里对应的job值为:xxx)
    • instance:采集对象。(即:当前预警所属采集项地址,假设prometheus.yml如下所示,采集项aliyun-node预警了,那么这里对应的instance值为:47.105.39.189:9100)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      global:
      。。。省略
      alerting:
      。。。省略
      rule_files:
      。。。省略
      scrape_configs:
      # 采集任务
      - job_name: 'xxx'
      static_configs:
      - targets: ['47.105.39.189:9100']
      # 设置采集任务标签 (注:如果预警规则里面设置有同名标签的话,预警时则会覆盖此标签)
      labels:
      env: prod
      name: justrydeng
      instance: xxx-instance
      group: 'ds'
  • annotations:用于指定一组附加信息,比如用于描述告警详细信息的文字等,annotations的内容在告警产生时会一同作为参数发送到Alertmanager
    占位符,用于取值xxx对应的值
  • 如:,取当前规则文件下,instance标签的值
  • 如:在annotations中,使用取触发当前预警的预警值
    检查预警规则文件是否正确
    1
    2
    3
    4
    5
    6
    # 进入容器
    # docker exec -it {容器id 或 容器名} /bin/sh
    docker exec -it prometheus /bin/sh
    # 使用promtool 工具,执行check指令
    # promtool check rules {规则文件,后缀名随意都可以}
    promtool check rules /prometheus/rules/os.rules

第三步:使得最新的prometheus配置生效

因为这里启用了alertmanager,为保险起见,本人这里选择重启prometheus(而不是使用prometheus的热加载)来使生效

1
2
3
4
# 重启容器prometheus
docker restart prometheus
# 查看日志
docker logs --tail=50 prometheus

第四步:验证预警生效

访问prometheus,查看预警规则是否有了
image-20250222173622393

预警状态说明:

  • Inactive:未触发预警
  • Pending:满足预警规则里面的预警表达式expr了,但是持续时间不满足预警规则里面的for,尚未发送预警信息
  • Firing:触发预警且已发送预警信息

查看邮箱,发现收到了预警消息
image-20250222173728233
注:因为本人后来优化了上面的rule规则的配置内容,所以这里email里面的截图和上面的配置有点出入

7、常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 触发热加载配置
# 前提条件:启动prometheus时,启用了web.enable-lifecycle
# 发送post请求到prometheus的/-/reload下触发热加载配置
curl -X POST http://192.168.12.218:9090/-/reload

# 进入容器
# docker exec -it {容器id 或 容器名} /bin/sh
docker exec -it prometheus /bin/sh
# 使用promtool 工具,执行check指令
# promtool check rules {规则文件,后缀名随意都可以}
promtool check rules /prometheus/rules/os.rules

# docekr 实时查看日志
docker logs --tail=1000 -f ./prometheus

8、Web 地址

1
2
3
4
5
6
7
#prometheus
http://192.168.12.218:9090/query

#grafana
http://192.168.12.218:3000
#admin/admin
admin/123abcABC

9、问题记录

遗留问题

1
2
3
告警内容的连接信息不正确 
192.168.12.218 alertmanager
192.168.12.218 prometheus

问题1:Docker compose mysql_exporter start error

  • 详细信息日志:

    1
    2
    time=2025-02-20T02:58:58.997Z level=ERROR source=config.go:141 msg="failed to validate config" section=client err="no user specified in section or parent"
    time=2025-02-20T02:58:58.997Z level=INFO source=mysqld_exporter.go:244 msg="Error parsing host config" file=.my.cnf err="no configuration found"
  • mysqld-exporter 文件配置信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
version: '3'

networks:
monitor:
driver: bridge

services:
mysql_xporter:
image: prom/mysqld-exporter:v0.16.0
container_name: mysql-exporter
hostname: mysql-exporter
restart: always
ports:
- "9104:9104"
environment:
DATA_SOURCE_NAME: 'exporter:123456_abc@(192.168.12.174:3306)/'
networks:
- monitor
  • 调整后即可
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    version: '3'

    networks:
    monitor:
    driver: bridge

    services:
    mysql_xporter:
    image: prom/mysqld-exporter:v0.16.0
    container_name: mysql-exporter
    hostname: mysql-exporter
    restart: always
    ports:
    - "9104:9104"
    command:
    - "--mysqld.username=exporter:123456_abc"
    - "--mysqld.address=192.168.12.174:3306"
    networks:
    - monitor
  • 重新生成doker 容器
    1
    2
    3
    4
    5
    6
    7
      # docker 日志 
    #部署 docker
    docker-compose -f ./docker-compose.yml up -d

    time=2025-02-20T03:04:40.454Z level=INFO source=mysqld_exporter.go:252 msg="Scraper enabled" scraper=info_schema.query_response_time
    time=2025-02-20T03:04:40.455Z level=INFO source=tls_config.go:347 msg="Listening on" address=[::]:9104
    time=2025-02-20T03:04:40.455Z level=INFO source=tls_config.go:350 msg="TLS is disabled." http2=false address=[::]:9104

问题2:AlertManager 中国移动 193 邮箱 邮件发送失败的问题 establish TLS connection to server: EOF

中国移动 193 邮箱,能够正常发送邮件配置

1
2
3
4
5
6
7
8
9
10
11
12
13
global:
resolve_timeout: 5m
# 发件人
smtp_from: '13520642397@139.com'
# 邮箱服务器的 POP3/SMTP 主机配置 smtp.qq.com 端口为 465 或 587
smtp_smarthost: 'smtp.139.com:25'
# 用户名
smtp_auth_username: '13520642397@139.com'
# 授权码 或 密码
smtp_auth_password: '授权码'
# smtp_auth_secret: '授权码'
smtp_require_tls: false
smtp_hello: '139.com'

附详细调试过程如下:
异常1:establish TLS connection to server: EOF
alertManager 的 193 邮箱,配置如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#查询配置文件命令:cat /opt/alertmanager/config/alertmanager.yml 
#告警邮件配置信息
global:
resolve_timeout: 5m
# 发件人
smtp_from: '135****2397@139.com'
# 邮箱服务器的 POP3/SMTP 主机配置 smtp.qq.com 端口为 465 或 587
smtp_smarthost: 'smtp.139.com:465'
# 用户名
smtp_auth_username: '135****2397@139.com'
# 授权码 或 密码
#smtp_auth_password: '授权码'
smtp_auth_secret: '授权码'
smtp_require_tls: true
smtp_hello: '139.com'

告警邮件未发送,查看 alertManager 的异常信息如下:

1
2
3
4
5
6
#查看日志命令: 
`docker logs --tail=200 -f alertmanager `
#异常详细日志
... ...
time=2025-02-20T12:04:21.135Z level=WARN source=notify.go:866 msg="Notify attempt failed, will retry later" component=dispatcher receiver=justrydengKeendataMail integration=email[0] aggrGroup="{}/{alarmClassify=~\"^(?:normal)$\"}:{alertname=\"网络(出)\"}" attempts=1 err="establish TLS connection to server: EOF"
time=2025-02-20T12:09:20.981Z level=ERROR source=dispatch.go:360 msg="Notify for alerts failed" component=dispatcher num_alerts=1 err="justrydengKeendataMail/email[0]: notify retry canceled after 18 attempts: establish TLS connection to server: EOF"

根据提示信息 TLS 问题,关闭 TLS 配置,调整配置为

1
2
#告警邮件配置信息
smtp_require_tls: false

重启 alertManger 容器 ,docker restart alertmanager;
再次测试,发送告警邮件,异常信息发生变化。
异常2: missing password for LOGIN auth mechanism; missing password for PLAIN auth mechanism
详细异常信息如下

1
time=2025-02-20T12:16:51.246Z level=WARN source=notify.go:866 msg="Notify attempt failed, will retry later" component=dispatcher receiver=justrydengKeendataMail integration=email[0] aggrGroup="{}/{alarmClassify=~\"^(?:normal)$\"}:{alertname=\"网络(出)\"}" attempts=1 err="find auth mechanism: missing password for LOGIN auth mechanism; missing password for PLAIN auth mechanism"

调整 alertManager 的配置

1
2
3
# 授权码 或 密码
smtp_auth_password: '授权码'
# smtp_auth_secret: '授权码'

可以正常发送邮件,完整配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
global:
resolve_timeout: 5m
# 发件人
smtp_from: '13520642397@139.com'
# 邮箱服务器的 POP3/SMTP 主机配置 smtp.qq.com 端口为 465 或 587
smtp_smarthost: 'smtp.139.com:25'
# 用户名
smtp_auth_username: '13520642397@139.com'
# 授权码 或 密码
smtp_auth_password: '授权码'
# smtp_auth_secret: '授权码'
smtp_require_tls: false
smtp_hello: '139.com'

10、相关资料

  1. docker安装prometheus+grafana安装详细教程
  2. AlertManager简介与告警模板
  3. 本文已被收录进*《程序员成长笔记》* ,笔者JustryDeng
  4. docker-compose 搭建 Prometheus+Grafana监控系统
  5. Docker compose mysql_exporter starterror
  6. Node Exporter Dashboard EN 20201010-StarsL.cn
  7. Prometheus之Alertmanager钉钉报警配置
  8. Alertmanager配置钉钉+邮件同时告警

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

[TOC]

一、系统环境

  1. 操作系统:CentOS Linux release 7.7.1908 (Core) x64

二、问题描述

在Linux系统中,我们经常用free命令来查看系统内存的使用状态。在一个RHEL6的系统上,free命令的显示内容大概是这样一个状态:
Explore-CentOS7-Available-Memory-1.png

其实:buffers/cache占用的较多,说明系统中有进程曾经读写过文件,但是不要紧,这部分内存是当空闲来用的
Linux内核会在内存将要耗尽的时候,触发内存回收的工作,以便释放出内存给急需内存的进程使用。一般情况下,这个操作中主要的内存释放都来自于对buffer/cache的释放。尤其是被使用更多的cache空间。既然它主要用来做缓存,只是在内存够用的时候加快进程对文件的读写速度,那么在内存压力较大的情况下,当然有必要清空释放cache,作为free空间分给相关进程使用。所以一般情况下,我们认为buffer/cache空间可以被释放,这个理解是正确的。
但是这种清缓存的工作也并不是没有成本。理解cache是干什么的就可以明白清缓存必须保证cache中的数据跟对应文件中的数据一致,才能对cache进行释放。所以伴随着cache清除的行为的,一般都是系统IO飙高。因为内核要对比cache中的数据和对应硬盘文件上的数据是否一致,如果不一致需要写回,之后才能回收。

三、解决办法

在系统中除了内存将被耗尽的时候可以清缓存以外,我们还可以使用下面这个文件来人工触发缓存清除的操作:

1
2
3
4
5
6
7
8
9
10
echo 1 > /proc/sys/vm/drop_caches
echo 2 > /proc/sys/vm/drop_caches
echo 3 > /proc/sys/vm/drop_caches

# 表示清除pagecache。
echo 1 > /proc/sys/vm/drop_caches
# 表示清除回收slab分配器中的对象(包括目录项缓存和inode缓存)。slab分配器是内核中管理内存的一种机制,其中很多缓存数据实现都是用的pagecache。
echo 2 > /proc/sys/vm/drop_caches
# 表示清除pagecache和slab分配器中的缓存对象。
echo 3 > /proc/sys/vm/drop_caches

四、参考资料

README.md

hello world.