以上是prometheus架构图,一个完整的监控流程是数据采集(exporter),采集到数据之后,做数据可视化(grafana),然后是监控告警部分。promethues的角色是数据的采集,存储,定制告警规则,数据的展示是grafna,告警则是借助alertmanger来实现。
详细参考官方网站
https://prometheus.io/docs/alerting/latest/notifications/
告警的过程
prometheus server定义告警规则以及产生的告警,alertmanger组件用于处理这些产生的告警,它是prometheus体系中告警的统一处理中心。
alertmanger提供了多种内置的第三方告警通知方式,同时还提供了对webhook通知的支持,通过webhook用户可以完成对告警的更多个性化扩展。
触发一条告警的过程:
prometheus-->触发阈值-->超出持续时间-->alertmanager-->分组|抑制|静默-->媒体类型-->邮件|钉钉|微信等
Alertmanger部署
wget https://github.com/prometheus/alertmanager/releases/download/v0.20.0/alertmanager-0.20.0.linux-amd64.tar.gz
tar -xvf alertmanager-0.20.0.linux-amd64.tar.gz
ls
mv alertmanager-0.20.0.linux-amd64 /usr/local/
mv alertmanager-0.20.0.linux-amd64.tar.gz /usr/local/alertmanager
定义分组和路由
在alertmanager目录下定义alertmanager.yml
global: #定义全局配置
#定义邮箱
resolve_timeout: 5m
smtp_smarthost: 'stmp.qq.com:465' #使用qq邮箱
smtp_from: '[email protected]' #邮箱名称
smtp_auth_username: '[email protected]' #登录邮箱名称
smtp_auth_password: 'tygowyeqpjprbebd' #授权码
smtp_require_tls: false #不使用https
templates:
- '/usr/local/aletmanager/email.tmpl' #引用告警模板
route: #默认路由
group_by: ['instance','job'] #根据instance和job标签分组,同标签下的告警会在一个邮件中展现
group_wait: 30s
group_interval: 5m
repeat_interval: 4h #重复告警间隔
receiver: 'email' #默认接受者
routes: #子路由,不满足子路由的都走默认路由
- match: #普通匹配
severity: critical
receiver: leader
- match_re: #正则匹配
severity: ^(warning|critical)$
receiver: ops
receivers: #定义三个接受者,和上面三个路由对应
- name: 'email'
email_configs:
- to: '[email protected]'
html: '{{template "email.to.html" .}}' #使用告警模板
send_resolved: true #恢复通知
- name: 'leader'
email_configs:
- to: '[email protected]'
html: '{{template "email.to.html" .}}'
send_resolved: true
- name: 'ops'
email_configs:
- to: '[email protected]'
html: '{{template "email.to.html" .}}'
send_resolved: true
检查配置语法
cd /usr/local/alertmanager
./amtool check-config alertmanager.yml
添加启动项
cat < EOF >> /etc/systemd/system/alertmanager.service
[Unit]
Description=alertmanagerSystem
[Service]
WorkingDirectory=/usr/local/
ExecStart=/usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/alertmanager.yml
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable alertmanager && systemctl start alertmanager && systemctl status alertmanager
配置prometheus规则与alert
修改prometheus.yml的alerting部分
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
- 192.168.33.130:9093
定义告警文件
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
- "rules/*.yml"
定义告警规则
编写一个主机down机的告警规则定义,告警规则文件为/usr/local/prometheus/rules/node_monitor.yml
groups:
- name: node-up #告警分组,一个组下的告警会整合在一个邮件中
rules:
- alert: node-up #监控项名称
expr: up{job="linux-wuhan"} == 0 #正则表达式,up{job:"linux"} 可以在prometheus查询,自己定义监控状态
for: 15s #for选项定义表达式持续时长,0的话代表一满足就触发
labels:
severity: critical #定义了一个标签,因为上面我们是基于标签进行路由
annotations: #邮件注释内存,可引用变量
summary: "{{ $labels.instance }} 已停止运行超过 15s!"
说明:
- prometheus支持使用变量来获取指定标签中的值,如value可以获取当前PromQL表达计算的样本值
- 在创建规则文件的时候,建议为不同的对象建立不同的文件
- expr是根据promql来写查询表达式
测试
重启prometheus server,关闭某台主机监控
可以看到告警生效了
prometheus alert告警状态有三种
- Inactive: 非活动状态,表示正在监控,但是还未有仁恒报警触发
- Pending:表示这个告警必须被触发,由于警报可以被分组,压抑/抑制或者静默,等待验证,一旦所有的验证都通过,则将转入到Firing状态
- Firing: 将警报发送到AlertManager,它将按照配置将警报发送给素有接收者,一旦警报解除,则状态转到Inactive,如此循环
查看alertmanger
配置邮件模板
编写email.tmpl,告警邮件通知模板
{{ define "email.to.html" }}
{{ if gt (len .Alerts.Firing) 0 }}{{ range .Alerts }}
@告警
告警程序: prometheus_alert <br>
告警级别: {{ .Labels.severity }} 级 <br>
告警类型: {{ .Labels.alertname }} <br>
故障主机: {{ .Labels.instance }} <br>
告警主题: {{ .Annotations.summary }} <br>
告警详情: {{ .Annotations.description }} <br>
触发时间: {{ .StartsAt }} <br>
{{ end }}
{{ end }}
{{ if gt (len .Alerts.Resolved) 0 }}{{ range .Alerts }}
@恢复:
告警主机:{{ .Labels.instance }} <br>
告警主题:{{ .Annotations.summary }} <br>
恢复时间: {{ .EndsAt }} <br>
{{ end }}
{{ end }}
{{ end }}
企业微信告警
Alertmanager的企业微信告警和邮件配置类似,在配置微信告警前需要准备一个企业微信号,创建自己的告警应用,并准备一些参数,配置如下
wechat_api_url: ''#(默认),根据实际情况查询
to_party: '部门id' #或者发送到个人to_user
agent_id: '应用id'
corp_id: '微信企业号ID'
api_secret: '自己创建应用的 secret'
alertmanger配置
编辑alertmanger.yml
route:
group_by: ['alertname']
receiver: 'wechat'
receivers:
- name: 'wechat'
wechat_configs:
- corp_id: 'ww953305'
to_party: '1'
agent_id: '1000006'
api_secret: 'ROw18-U8fa2Lpe2G9RPLqOvcMlI0'
配置微信告警模板
编写wechat.tmpl
{{ define "wechat.tmpl" }}
{{- if gt (len .Alerts.Firing) 0 -}}{{ range .Alerts }}
@警报
实例: {{ .Labels.instance }}
信息: {{ .Annotations.summary }}
详情: {{ .Annotations.description }}
时间: {{ .StartsAt }}
{{ end }}{{ end -}}
{{- if gt (len .Alerts.Resolved) 0 -}}{{ range .Alerts }}
@恢复
实例: {{ .Labels.instance }}
信息: {{ .Annotations.summary }}
时间: {{ .StartsAt }}
恢复: {{ .EndsAt }}
{{ end }}{{ end -}}
{{- end }}
配置文件中添加模板
route:
group_by: ['alertname'] #组名
receiver: 'wechat' #接收人,由于我们是分组告警,所以不添加正则匹配
group_wait: 10s #组等待时间
group_interval: 10s #发送前等等时间
repeat_interval: 1h #重启周期,1小时后发送
templates: #模板路径
- '/usr/local/src/alertmanager-0.20.0.linux-amd64/wechat.tmpl'
receivers:
- name: 'wechat'
wechat_configs:
- send_resolved: true #恢复后发送消息
corp_id: 'ww95330520c7' #企业id
to_party: '1' #部门id
agent_id: '1000006' #应用id
api_secret: 'ROw18-lI0' #应用密钥
message: '{{ template "wechat.tmpl" . }}' #消息模板
常用的告警规则编写
常用promql表达式
CPU收集监控:
①收集CPU利用率:使用irate的函数,用于计算距离向量中时间序列的每秒瞬时增长率。我们在node_cpu_seconds_total度量上使用irate函数。
irate(node_cpu_seconds_total{job="node-exporter"}[5m])
②使用avg求出这段时间的算数平均值,现在我们需要使用聚合运算符avg封装irate函数,并添加了一个by子句,该子句通过实例标签聚合。这将产生三个新的指标,使用来自所有CPU和所有模式的值来平均主机的CPU使用情况。之后再使用mode=”idle”,只查询空闲数据,将其乘以100,得出每5分钟平均空闲的百分比数值。
avg(irate(node_cpu_seconds_total{job="node-exporter",mode="idle"}[5m])) by (instance) * 100
③现在我们得到了每台主机每5分钟平均空闲的CPU百分比,用100减去它,那么就是已经使用的百分比了。
100 - avg(irate(node_cpu_seconds_total{job="node-exporter",mode="idle"}[5m])) by (instance) * 100
④使用round函数求出四舍五入的正整数值。
round(100 - avg(irate(node_cpu_seconds_total{job="node-exporter",mode="idle"}[5m])) by (instance) * 100 )
⑤当我们发现使用率大于80的时候就告警,表达式如下:
round(100 - avg(irate(node_cpu_seconds_total{job="node-exporter",mode="idle"}[5m])) by (instance) * 100 ) > 80
收集内存使用率
我们需要收集node_memory度量的一些子集,以计算利用率度量:
node_memory_MemTotal_bytes - 主机上的总内存
node_memory_MemFree_bytes - 主机上的空闲内存
node_memory_Buffers_bytes_bytes - 缓冲区缓存中的内存
node_memory_Cached_bytes_bytes - 页面缓存中的内存
①计算使用内存的百分比:(总内存-(空余内存+缓存+缓冲))/总内存 * 100
round((node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Cached_bytes + node_memory_Buffers_bytes)) / node_memory_MemTotal_bytes * 100)
②告警表达式:当内存使用率超过80的时候就告警:
round((node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Cached_bytes + node_memory_Buffers_bytes)) / node_memory_MemTotal_bytes * 100) > 80
磁盘使用率
4、磁盘的使用率:
①和内存类似,我们使用 (空闲的空间)/总空间 * 100 得出空闲空间的百分比
node_filesystem_free_bytes{mountpoint="/",device="rootfs"} / node_filesystem_size_bytes{mountpoint="/",device="rootfs"} * 100
②然后使用100 减去空闲的百分比,就得到磁盘使用的百分比,由于可能有多个磁盘空间,所以我们这里使用正则表达式,表示所有分区:
100-(node_filesystem_free_bytes{fstype=~"ext4|xfs"}/node_filesystem_size_bytes {fstype=~"ext4|xfs"}*100)
③使用round函数求整数值, 并且当使用率大于百分之八十的时候告警,得到如下表达式:
round(100-(node_filesystem_free_bytes{fstype=~"ext4|xfs"}/node_filesystem_size_bytes {fstype=~"ext4|xfs"}*100)) > 80
磁盘IO使用率
5、磁盘IO使用率
①先求出5m之内磁盘IO的增长率:
irate(node_disk_io_time_seconds_total[5m])
②根据avg行数求出这个时间段的平均值,也就是这个时间段的IO:
avg(irate(node_disk_io_time_seconds_total[5m])) by (instance) * 100
③100减去这个磁盘的IO使用率,就得到磁盘IO得空闲百分比,跟60相比较就得到如下表达式:
100-(avg(irate(node_disk_io_time_seconds_total[1m])) by(instance)* 100) < 60
网络流入流量表达式
round(irate(node_network_receive_bytes_total{instance!~"data.*",device!~'tap.*|veth.*|br.*|docker.*|vir.*|lo.*|vnet.*'}[1m])/1024) > 2048
并发会话连接数表达式:
node_netstat_Tcp_CurrEstab > 500
alertmanager 表达式:
根据以上的告警规则,就能写 alertmanger的表达式了
groups:
- name: node-up #告警分组,一个组下的告警会整合在一个邮件中
rules:
- alert: node-up #监控项名称
expr: up{job="node-exporter"} == 0 #正则表达式,up{job:"linux"} 可以在prometheus查询,自己定义监控状态
for: 15s #for选项定义表达式持续时长,0的话代表一满足就触发
labels:
severity: critical #定义了一个标签,因为上面我们是基于标签进行路由
annotations: #邮件注释内存,可引用变量
summary: "{{ $labels.instance }} 已停止运行超过 15s!"
- alert: "内存使用率过高"
expr: round((node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Cached_bytes + node_memory_Buffers_bytes)) / node_memory_MemTotal_bytes * 100) > 80
for: 1m
labels:
severity: warning
annotations:
summary: "内存使用率过高"
description: "当前使用率{{ $value }}%"
- alert: "CPU使用率过高"
expr: round(100 - avg(irate(node_cpu_seconds_total{job="node-exporter",mode="idle"}[5m])) by (instance) * 100 ) > 80
for: 2m
labels:
severity: warning
annotations:
summary: "CPU使用率过高"
description: "当前使用率{{ $value }}%"
- alert: "磁盘使用率过高"
expr: round(100-(node_filesystem_free_bytes{fstype=~"ext4|xfs"}/node_filesystem_size_bytes {fstype=~"ext4|xfs"}*100)) > 80
for: 15s
labels:
severity: warning
annotations:
summary: "磁盘使用率过高"
description: "当前磁盘{{$labels.mountpoint}} 使用率{{ $value }}%"
- alert: "IO使用率过高"
expr: 100-(avg(irate(node_disk_io_time_seconds_total[1m])) by(instance)* 100) < 60
for: 15s
labels:
severity: warning
annotations:
summary: "IO使用率过高"
description: "当前使用率{{ $value }}%"
- alert: "网络流出速率过高"
expr: round(irate(node_network_receive_bytes_total{instance!~"data.*",device!~'tap.*|veth.*|br.*|docker.*|vir.*|lo.*|vnet.*'}[1m])/1024) > 2048
for: 1m
labels:
severity: warning
annotations:
summary: "网络流出速率过高"
description: "当前速率{{ $value }}KB/s"
- alert: "会话链接数过高"
expr: node_netstat_Tcp_CurrEstab > 500
for: 1m
labels:
severity: warning
annotations:
summary: "当前会话连接数过高"
description: "当前连接数{{ $value }}"
重启prometheus,验证 rules
标签:node,alertmanager,memory,bytes,prometheus,alertmanger,100,告警 From: https://blog.51cto.com/u_11555417/6333894