Prometheus告警简介
告警能力在Prometheus的架构中被划分成两个独立的部分。如下所示,通过在Prometheus中定义AlertRule(告警规则),Prometheus会周期性的对告警规则进行计算,如果满足告警触发条件就会向Alertmanager发送告警信息。
在Prometheus中一条告警规则主要由以下几部分组成:
告警名称:用户需要为告警规则命名,当然对于命名而言,需要能够直接表达出该告警的主要内容
告警规则:告警规则实际上主要由PromQL进行定义,其实际意义是当表达式(PromQL)查询结果持续多长时间(During)后出发告警
在Prometheus中,还可以通过Group(告警组)对一组相关的告警进行统一定义。当然这些定义都是通过YAML文件来统一管理的。
Alertmanager作为一个独立的组件,负责接收并处理来自Prometheus Server(也可以是其它的客户端程序)的告警信息。Alertmanager可以对这些告警信息进行进一步的处理,比如当接收到大量重复告警时能够消除重复的告警信息,同时对告警信息进行分组并且路由到正确的通知方,Prometheus内置了对邮件,Slack等多种通知方式的支持,同时还支持与Webhook的集成,以支持更多定制化的场景。例如,目前Alertmanager还不支持钉钉,那用户完全可以通过Webhook与钉钉机器人进行集成,从而通过钉钉接收告警信息。同时AlertManager还提供了静默和告警抑制机制来对告警通知行为进行优化。
Alertmanager特性
Alertmanager除了提供基本的告警通知能力以外,还主要提供了如:分组、抑制以及静默等告警特性:
分组:
分组机制可以将详细的告警信息合并成一个通知。在某些情况下,比如由于系统宕机导致大量的告警被同时触发,在这种情况下分组机制可以将这些被触发的告警合并为一个告警通知,避免一次性接受大量的告警通知,而无法对问题进行快速定位。
例如,当集群中有数百个正在运行的服务实例,并且为每一个实例设置了告警规则。假如此时发生了网络故障,可能导致大量的服务实例无法连接到数据库,结果就会有数百个告警被发送到Alertmanager。
而作为用户,可能只希望能够在一个通知中中就能查看哪些服务实例收到影响。这时可以按照服务所在集群或者告警名称对告警进行分组,而将这些告警内聚在一起成为一个通知。
告警分组,告警时间,以及告警的接受方式可以通过Alertmanager的配置文件进行配置。
抑制:
抑制是指当某一告警发出后,可以停止重复发送由此告警引发的其它告警的机制。
例如,当集群不可访问时触发了一次告警,通过配置Alertmanager可以忽略与该集群有关的其它所有告警。这样可以避免接收到大量与实际问题无关的告警通知。
抑制机制同样通过Alertmanager的配置文件进行设置。
静默:
静默提供了一个简单的机制可以快速根据标签对告警进行静默处理。如果接收到的告警符合静默的配置,Alertmanager则不会发送告警通知。
静默设置需要在Alertmanager的Werb页面上进行设置。
自定义Prometheus告警规则
Prometheus中的告警规则允许你基于PromQL表达式定义告警触发条件,Prometheus后端对这些触发规则进行周期性计算,当满足触发条件后则会触发告警通知。默认情况下,用户可以通过Prometheus的Web界面查看这些告警规则以及告警的触发状态。当Promthues与Alertmanager关联之后,可以将告警发送到外部服务如Alertmanager中并通过Alertmanager可以对这些告警进行进一步的处理。
定义告警规则
在告警规则文件中,我们可以将一组相关的规则设置定义在一个group下。在每一个group中我们可以定义多个告警规则(rule)。一条告警规则主要由以下几部分组成:
# 告警规则配置完成后,需要注意,还要在prometheus.yml中配置alertmanager的地址:
vim first_rules.yml
groups:
- name: node-up
rules:
- alert: node-up
expr: up == 0
for: 15s
labels:
severity: 1
team: node
annotations:
summary: "{{$labels.instance}}Instance has been down for more than 5 minutes"
# alert:告警规则的名称。
# expr:基于PromQL表达式告警触发条件,用于计算是否有时间序列满足该条件。
# for:评估等待时间,可选参数。用于表示只有当触发条件持续一段时间后才发送告警。在等待期间新产生告警的状态为pending。
# labels:自定义标签,允许用户指定要附加到告警上的一组附加标签。
# annotations:用于指定一组附加信息,比如用于描述告警详细信息的文字等,annotations的内容在告警产生时会一同作为参数发送到Alertmanager。
# summary描述告警的概要信息,description用于描述告警的详细信息。
# 同时Alertmanager的UI也会根据这两个标签值,显示告警信息。
vim prometheus.yml
8 alerting:
9 alertmanagers:
10 - static_configs:
11 - targets:
12 - 127.0.0.1:9093
13
14 #Load rules once and periodically evaluate them according to the globa l 'evaluation_interval'.
15 rule_files:
16 - "first_rules.yml"
17 # - "second_rules.yml"
为了能够让Prometheus能够启用定义的告警规则,我们需要在Prometheus全局配置文件中通过__rule_files__指定一组告警规则文件的访问路径,Prometheus启动后会自动扫描这些路径下规则文件`中定义的内容,并且根据这些规则计算是否向外部发送通知:
rule_files:
[ - <filepath_glob> ... ]
默认情况下Prometheus会每分钟对这些告警规则进行计算,如果用户想定义自己的告警计算周期,则可以通过evaluation_interval来覆盖默认的计算周期:
global:
[ evaluation_interval: <duration> | default = 1m ]
模板化
一般来说,在告警规则文件的annotations中使用
summary
描述告警的概要信息,description
用于描述告警的详细信息。同时Alertmanager的UI也会根据这两个标签值,显示告警信息。为了让告警信息具有更好的可读性,Prometheus支持模板化label和annotations的中标签的值。
通过
$labels.变量可以访问当前告警实例中指定标签的值。$value则可以获取当前PromQL表达式计算的样本值
# To insert a firing element's label values:
{{ $labels.<labelname> }}
# To insert the numeric expression value of the firing element:
{{ $value }}
例如,可以通过模板化优化sumary以及description的内容可读性:
groups:
- name: example
rules:
# Alert for any instance that is unreachable for >5 minutes.
- alert: InstanceDown
expr: up == 0
for: 5m
labels:
severity: page
annotations:
summary: "Instance {{ $labels.instance }} down"
description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."
# Alert for any instance that has a median request latency >1s.
- alert: APIHighRequestLatency
expr: api_http_request_latencies_second{quantile="0.5"} > 1
for: 10m
annotations:
summary: "High request latency on {{ $labels.instance }}"
description: "{{ $labels.instance }} has a median request latency above 1s (current value: {{ $value }}s)"
修改配置文件、报警文件记得重启服务才会生效
查看告警状态
如下所示,用户可以通过Prometheus WEB界面中的Alerts菜单查看当前Prometheus下的所有告警规则,以及其当前所处的活动状态。
Alertmanager安装和配置
alertmanager是用来接收prometheus发出的告警,然后按照配置文件的要求,将告警用对应的方式发送出去。将告警集中到alertmanager,可以对告警进行更细致的管理。
5.1 alertmanager的安装和启动
wget https://github.com/prometheus/alertmanager/releases/download/v0.19.0/alertmanager-0.19.0.linux-amd64.tar.gz
下载解压Alertmanager包
# 从官网下载好包后我们可以对他进行解压
tar xvf alertmanager-0.19.0.linux-amd64.tar.gz -C /usr/local/
启动访问Alertmanager
cd /usr/local/alertmanager-0.19.0.linux-amd64/
./alertmanager &>/dev/null &
# 接下来我们访问http://172.19.0.51:9093/#/alerts,就可以打开alertmanager的页面,
编辑Alertmanager.yml
# 接下来我们编辑alertmanager.yml文件,配置邮箱账号授权码相关配置
cat alertmanager.yml
global: # 全局配置,报警策略,报警渠道等.
smtp_smarthost: 'smtp.163.com:25'
smtp_from: '18621048481@163.com'
smtp_auth_username: '18621048481@163.com'
smtp_auth_password: 'ZHOUjian22' # 邮箱授权码
smtp_require_tls: false
route: # 分发策略
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 5m
receiver: 'email'
receivers: # 接受者
- name: 'email'
email_configs:
- to: '18621048481@163.com' # 接受的邮箱
send_resolved: true
inhibit_rules: # 抑制策略,当存在另一组匹配的警报,抑制规则将禁止与另一组匹配的警报.
- source_match:
serverity: 'critical'
宕掉一台node_exporter
# 接下来我们重启一下服务使配置生效,然后宕掉一台节点的node_exporter
# 将alertmanager加入到systemd服务
vim /usr/lib/systemd/system/alertmanager.service
[Unit]
Description=Alertmanager
After=network.target
[Service]
Type=simple
User=prometheus
ExecStart=/usr/local/alertmanager-0.19.0.linux-amd64/alertmanager
--config.file=/usr/local/alertmanager-0.19.0.linux-amd64/alertmanager.yml
--storage.path=/usr/local/alertmanager-0.19.0.linux-amd64/data
Restart=on-failure
[Install]
WantedBy=multi-user.target
systemctl restart node_exporter
systemctl restart alertmanager
systemctl restart prometheus
# 如果服务启动失败报错,可以先systemctl daemon-reload,再重启
# 接下来我们将node_export停掉两台,然后去查看prometheus的控制面板
如果觉得这个报警界面太丑,可以自定义模板的
自定义报警信息模板
如果不知道怎么写模板,可以下载官方的模板,基于上面做修改
wget https://raw.githubusercontent.com/prometheus/alertmanager/master/template/default.tmpl
# 我这里写一个简单的模板例子,需要修改两个配置文件,然后重启服务
cat alertmanager.yml
global:
smtp_smarthost: 'smtp.163.com:25'
smtp_from: '18621048481@163.com'
smtp_auth_username: '18621048481@163.com'
smtp_auth_password: 'ZHOUjian21'
smtp_require_tls: false
templates:
- '/usr/local/alertmanager-0.19.0.linux-amd64/template/*.tmpl'
route:
group_by: ['alertname','cluster','service']
group_wait: 30s
group_interval: 5m
repeat_interval: 5m
receiver: 'email'
receivers:
- name: 'email'
email_configs:
- to: '18621048481@163.com'
html: '{{ template "email.mengyuan.html" . }}'
headers: { Subject: "[WARN] 报警邮件 test" }
send_resolved: true
inhibit_rules:
- source_match:
serverity: 'critical'
cat template/default.tmpl {{ define "email.mengyuan.html" }}
<table>
<tr><td>报警名</td><td>开始时间</td></tr>
{{ range $i, $alert := .Alerts }}
<tr><td>{{ index $alert.Labels "alertname" }}</td><td>{{ $alert.StartsAt }}</td></tr>
{{ end }}
</table>
{{ end }}
systemctl restart alertname
systemctl restart prometheus
# 接下来我们模拟一台节点宕机了,然后去邮箱查看,突然发现其实服务自带的模板挺好看的.