一、Prometheus的警报
Prometheus中的警报分为两部分,首先由prometheus服务器根据警报规则将警报发送到alertmanager,然后alertmanager管理这些警报,包括静音(silencing)、抑制(inhibition)、聚合(aggregation)和通知(电子邮件、聊天平台等)。
设置警报和通知的主要步骤如下:
- 设置和配置alertmanager
- 配置alertmanager和prometheus对话
- 在prometheus中创建警报规则
二、alertmanager介绍
Alertmanager处理由 Prometheus 服务器等客户端应用程序发送的警报。它负责对它们进行重复数据删除、分组并将它们路由到正确的接收器集成,例如电子邮件、PagerDuty 或 OpsGenie。它还负责警报的静音和抑制。
分组
分组将类似性质的警报分类为单个通知。当许多系统同时发生故障并且可能同时触发数百到数千个警报时,这在较大的中断期间特别有用。
示例:发生网络分区时,集群中正在运行数十或数百个服务实例。您的一半服务实例无法再访问数据库。Prometheus 中的警报规则配置为在每个服务实例无法与数据库通信时发送警报。因此,数百个警报被发送到 Alertmanager。
作为用户,您只想获得一个页面,同时仍然能够准确查看哪些服务实例受到了影响。因此,可以将 Alertmanager 配置为按其集群和警报名称对警报进行分组,以便发送单个紧凑通知。
警报的分组、分组通知的时间以及这些通知的接收者由配置文件中的路由树配置。
抑制
抑制是在某些其他警报已经触发时抑制某些警报通知的概念。
示例:正在触发通知整个集群不可访问的警报。如果该特定警报正在触发,Alertmanager 可以配置为静音有关此集群的所有其他警报。这可以防止通知与实际问题无关的数百或数千个触发警报。
抑制是通过 Alertmanager 的配置文件配置的。
沉默
静音是在给定时间内简单地将警报静音的简单方法。静音是基于匹配器配置的,就像路由树一样。检查传入警报是否匹配活动静音的所有相等或正则表达式匹配器。如果他们这样做,则不会针对该警报发送任何通知。
静音在 Alertmanager 的 Web 界面中配置。
客户行为
Alertmanager 对其客户的行为有特殊要求。这些仅与 Prometheus 不用于发送警报的高级用例相关。
高可用性
Alertmanager 支持配置以创建集群以实现高可用性。这可以使用--cluster-*标志进行配置。
重要的是不要在 Prometheus 和它的 Alertmanagers 之间对流量进行负载均衡,而是将 Prometheus 指向所有 Alertmanagers 的列表。
三、安装和配置
在prometheus官网可以获取下载地址
// 在装prometheus的主机安装即可
cd /packages
wget https://github.com/prometheus/alertmanager/releases/download/v0.23.0/alertmanager-0.23.0.linux-amd64.tar.gz
tar xvfz alertmanager-0.23.0.linux-amd64.tar.gz
mv alertmanager-0.23.0.linux-amd64 alertmanager
配置用systemd启动及加入开机自启
vim /etc/systemd/system/alertmanager.service
// 文件内容开始
[Unit]
Description=alertmanager
Documentation=zi ji qu cha github
[Service]
ExecStart=/packages/alertmanager/alertmanager \
--config.file=/packages/alertmanager/alertmanager.yml
Restart=on-failure
[Install]
WantedBy=multi-user.target
// 文件内容结束
systemctl daemon-reload
systemctl start alertmanager
systemctl enable alertmanager
systemctl status alertmanager
// 设置防火墙开放端口,alertmanager默认会占用9093端口
firewall-cmd --zone=public --add-port=9093/tcp --permanent
firewall-cmd --reload
在prometheus.yml中添加一段关于alertmanager的配置,这里指定了一个alertmanager_rules的文件,里面用来定义满足什么条件,会触发alert
vim /packages/prometheus/prometheus.yml
// 正文内容
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
rule_files:
- "/packages/prometheus/rules/alertmanager_rules.yml"
配置规则文件
vim /packages/prometheus/rules/alertmanager_rules.yml
// 正文内容
groups:
- name: node-alert
rules:
- alert: 主机停止运行
expr: up{job="node_info"} == 0
for: 15s
labels:
severity: 1
nodename: "{{ $labels.app }}"
annotations:
summary: "{{ $labels.app }}已停止运行超过15s!"
description: ""
- alert: 主机内存使用率过高
expr: (1 - (node_memory_MemAvailable_bytes / (node_memory_MemTotal_bytes))) * 100 > 90
for: 10s # 告警持续时间,超过这个时间才会发送给alertmanager
labels:
severity: warning
nodename: "{{ $labels.app }}"
annotations:
summary: "服务器实例 {{ $labels.app }}内存使用率过高"
description: "{{ $labels.app }}的内存使用率超过90%,当前使用率[{{ $value }}]."
- alert: 主机cpu使用率过高
expr: 100-avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by(instance)*100 > 80
for: 1m
labels:
severity: warning
nodename: "{{ $labels.app }}"
annotations:
summary: "服务器实例 {{ $labels.app }} cpu使用率过高"
description: "{{ $labels.app }}的cpu使用率超过80%,当前使用率[{{ $value }}]."
- alert: 主机磁盘使用率过高
expr: 100 - node_filesystem_avail_bytes{fstype=~"ext4|xfs",mountpoint="/"} * 100 / node_filesystem_size_bytes{fstype=~"ext4|xfs",mountpoint="/"} > 80
for: 1m
labels:
severity: warning
nodename: "{{ $labels.app }}"
annotations:
summary: "服务器实例 {{ $labels.app }} 磁盘使用率过高"
description: "{{ $labels.app }}的disk使用率超过80%,当前使用率[{{ $value }}]."
这里我们设置了一个名为node-alert的告警规则组,里面又有4个细项,上面提到过,分组会将同类的告警合并为单个通知,避免邮箱被挤爆了。
可以看到,rules里面的每个alert代表一种告警。
- expr表示监控的数据达到什么条件会触发告警。
- for表示告警持续时间,也就是当这种异常情况持续多久时,才会把告警发送给alertmanager。
- labels里面定义一些键值对,serverity是告警级别,还可以自定义一些内容,在邮件模板中可以使用到。
这个配置可以是prometheus将异常通知给alertmanager,alertmanager将会汇总这些信息,然后通知给用户。
vim /packages/alertmanager/alertmanager.yml
// 正文部分
global:
resolve_timeout: 5m
smtp_from: 'wangyanfengyyds@qq.com'
smtp_smarthost: 'smtp.qq.com:465'
smtp_auth_username: 'wangyanfengyyds@qq.com'
# 需在qq邮箱设置-> 账户 -> 开启POP3/SMTP服务,此时会弹出授权码
smtp_auth_password: '授权码'
smtp_require_tls: false
smtp_hello: 'qq.com'
templates:
- "/packages/alertmanager/tmpl/*.tmpl"
route:
group_by: ['alertname']
group_wait: 5s
group_interval: 5s
repeat_interval: 5m
receiver: 'email'
receivers:
- name: 'email'
email_configs:
- to: '{{ template "email.to" .}}'
html: '{{ template "email.to.html" .}}'
headers: { Subject: "[WARNING]Prometheus告警邮件" }
send_resolved: true
inhibit_rules:
- source_match: # 源标签警报触发时抑制含有目标标签的警报
severity: 'critical' # 此处的抑制匹配一定在最上面的route中配置不然,会提示找不key。
target_match:
severity: 'warning' # 目标标签值正则匹配,可以是正则表达式如: ".*MySQL.*"
equal: ['alertname', 'dev', 'instance'] # 确保这个配置下的标签内容相同才会抑制,也就是说警报中必须有这三个标签值才会被抑制。
global模块填写通知渠道的配置信息,上面我配置的是qq邮箱。
templates里配置通知模板
route里配置路由规则
receivers里配置接收方信息,可以配置发给谁、邮件主题等
inhibit_rules里面配置抑制规则
告警模板使用go template编写
vim /packages/alertmanager/tmpl/email.tmpl
// 正文部分
{{ define "email.from" }}wangyanfengyyds@qq.com{{ end }}
{{ define "email.to" }}wangyanfengyyds@qq.com{{ end }}
{{ define "email.to.html" }}
{{ range .Alerts }}
告警级别:{{ .Labels.severity }} 级 <br>
告警类型:{{ .Labels.alertname }} <br>
故障主机:{{ .Labels.app }} <br>
告警主体:{{ .Annotations.summary }} <br>
告警详情:{{ .Annotations.description }} <br>
触发时间:{{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }} <br>
{{ end }}
{{ end }}
这样,整个alertmanager的配置就结束了,当故障发生时,会发邮件给我。
测试
我们关闭第二台服务器,上面启动了node_exporter。过一分钟,会收到它停止运行的告警邮件。