Prometheus发出告警时分为两部分。首先,Prometheus按告警规则(rule_files配置块)向Alertmanager发送告警(即告警规则是在Prometheus上定义的)。然后,由Alertmanager来管理这些告警,包括去重(Deduplicating)、分组(Grouping)、静音(silencing)、抑制(inhibition)、聚合(aggregation ),最终将面要发出的告警通过电子邮件、webhook等方式将告警通知路由(route)给对应的联系人。
分组:就是将具有相同性质的告警先分类,然后当作单个通知发送出来。比如A和B两台主机的磁盘(CPU/内存)使用率都在告警,则磁盘的告警就可以合并在一个通知中发送出来。可以想像某个服务部署了100个节点,在一次升版后因为bug,日志中均报同样一类错误,如果不合并这类通知,那就是告警风暴。
抑制:就是某些告警触发后,则抑制(禁止)另一些告警。比如收到一条告警提示集群故障无法访问,那么在该集群上的所有其他警告应该被抑制。
静音(默):将某些在预期内的告警设置为静默(即不发送告警)。静默是基于配置匹配规则。Alertmanager会检查从Prometheus推送过来的告警事件,看这些告警事件是否与配置的静默规则能匹配上,如果匹配则不发送任何通知。配置静默方法是在Alertmanager的Web界面中,也可以使用amtool工具。
总之:Alertmanager制定这一系列规则目的只有一个,就是提高告警质量。
配置Alertmanager来做告警通知主要分三个步骤:
一、安装并配置Alertmanager
# tar -xvf alertmanager-0.20.0.linux-amd64.tar.gz
mv alertmanager-0.20.0.linux-amd64 /usr/local/alertmanager
# cat alertmanager.yml
global:
resolve_timeout: 5m
smtp_smarthost: 'smtp.mxhichina.com:465'
smtp_from: 'noreply@demo.com'
smtp_auth_username: 'noreply@demo.com'
smtp_auth_password: '1235698'
smtp_require_tls: false
templates:
- '/usr/local/alertmanager/template/default.tmpl'
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 2m
repeat_interval: 10m
receiver: 'email'
# continue default is false
continue: true
receivers:
- name: 'email'
email_configs:
- to: 'cookingit222@163.com,itcooking222@163.com'
send_resolved: true
html: '{{ template "default.html" . }}'
headers: { Subject: "{{ .GroupLabels.SortedPairs.Values }} [{{ .Status | toUpper }}:{{ .Alerts.Firing | len }}]" }
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
alertmanager配置简要说明:
global:全局配置,主要配置告警方式,如邮件、webhook等。
route:Prometheus的告警先是到达alertmanager的根路由(route),alertmanager的根路由不能包含任何匹配项,因为根路由是所有告警的入口点。另外,根路由需要配置一个接收器(receiver),用来处理那些没有匹配到任何子路由的告警(如果没有配置子路由,则全部由根路由发送告警),即缺省接收器。告警进入到根route后开始遍历子route节点,如果匹配到,则将告警发送到该子route定义的receiver中,然后就停止匹配了。因为在route中continue默认为false,如果continue为true,则告警会继续进行后续子route匹配。如果当前告警仍匹配不到任何的子route,则该告警将从其上一级(匹配)route或者根route发出(按最后匹配到的规则发出邮件)。
group_by:用于分组聚合,对告警通知按标签(label)进行分组,将具有相同标签或相同告警名称(alertname)的告警通知聚合在一个组,然后作为一个通知发送。如果想完全禁用聚合,可以设置为group_by: [...]
group_wait: 当一个新的告警组被创建时,需要等待'group_wait'后才发送初始通知。这样可以确保在发送等待前能聚合更多具有相同标签的告警,最后合并为一个通知发送。
group_interval: 当第一次告警通知发出后,在新的评估周期内又收到了该分组最新的告警,则需等待'group_interval'时间后,开始发送为该组触发的新告警,可以简单理解为,group就相当于一个通道(channel)。
repeat_interval: 告警通知成功发送后,若问题一直未恢复,需再次重复发送的间隔。
查看你的告警路由树,将alertmanager.yml配置文件复制到对话框,然后点击"Draw Routing Tree"
https://www.prometheus.io/webtools/alerting/routing-tree-editor/
修改好配置文件后,可以使用amtool工具检查配置
# ./amtool check-config alertmanager.yml
Checking 'alertmanager.yml' SUCCESS
# cat >/usr/lib/systemd/system/alertmanager.service <<EOF
[Unit]
Description=alertmanager
[Service]
ExecStart=/usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/alertmanager.yml --storage.path=/usr/local/alertmanager/data --web.listen-address=:9093 --data.retention=120h
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
# systemctl enable alertmanager
# systemctl restart alertmanager
alertmanager默认运行端口是:9093
alertmanager也可以同prometheus一样热加载配置
1)向alertmanager进程发送SIGHUP信号,如:kill -SIGHUP alertmanager_pid
2)curl -X POST http://prometheus_ip:9093/-/reload
二、修改prometheus的配置,关联Alertmanager服务,同时添加对alertmanager的监控
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
- monitor01:9093
rule_files:
- "rules/*_rules.yml"
- "rules/*_alerts.yml"
......
- job_name: 'alertmanager'
static_configs:
- targets: ['localhost:9093']
labels:
app: alertmanager
三、修改prometheus的配置,添加记录规则和告警规则。
# cat node_rules.yml
groups:
- name: node_rules
#interval: 15s
rules:
- record: instance:node_cpu_usage
expr: 100 - avg(irate(node_cpu_seconds_total{mode="idle"}[1m])) by (nodename) * 100
labels:
metric_type: CPU_monitor
- record: instance:node_1m_load
expr: node_load1
labels:
metric_type: load1m_monitor
- record: instance:node_mem_usage
expr: 100 - (node_memory_MemAvailable_bytes)/(node_memory_MemTotal_bytes) * 100
labels:
metric_type: Memory_monitor
- record: instance:node_root_partition_predit
expr: round(predict_linear(node_filesystem_free_bytes{device="rootfs",mountpoint="/"}[2h],12*3600)/(1024*1024*1024), 1)
labels:
metric_type: root_partition_monitor
# cat node_alerts.yml
groups:
- name: node_alerts
rules:
- alert: cpu_usage_over_threshold
expr: instance:node_cpu_usage > 80
for: 1m
labels:
severity: warning
annotations:
summary: 主机 {{ $labels.nodename }} 的 CPU使用率持续1分钟超出阈值,当前为 {{humanize $value}} %
- alert: system_1m_load_over_threshold
expr: instance:node_1m_load > 20
for: 1m
labels:
severity: warning
annotations:
summary: 主机 {{ $labels.nodename }} 的 1分负载超出阈值,当前为 {{humanize $value}}
- alert: mem_usage_over_threshold
expr: instance:node_mem_usage > 80
for: 1m
annotations:
summary: 主机 {{ $labels.nodename }} 的 内存 使用率持续1分钟超出阈值,当前为 {{humanize $value}} %
- alert: root_partition_usage_over_threshold
expr: instance:node_root_partition_predit < 60
for: 1m
annotations:
summary: 主机 {{ $labels.nodename }} 的 根分区 预计在12小时使用将达到 {{humanize $value}}GB,超出当前可用空间,请及时扩容!
for 表示告警持续的时长,若持续时长小于该时间就不发给alertmanager了,大于该时间再发。for的值不要小于prometheus中的scrape_interval,例如scrape_interval为30s,for为15s,如果触发告警规则,则再经过for时长后也一定会告警,这是因为最新的度量指标还没有拉取,在15s时仍会用原来值进行计算。另外,要注意的是只有在第一次触发告警时才会等待(for)时长。
例如:10:43:00 触发了集群A中的h1告警;10:43:10又触发了集群A中的h2告警。则在10:44:10后发生一条告警是只包含h1的邮件,在10:44:20时会收到h1和h2聚合后的告警邮件,若h1和h2持续未恢复,则在repeat_interval后仍以聚合方式发送告警。
注:h1和h2告警名相同,只是在不同主机上。
完成上述配置后,主机CPU、负载、内存、磁盘超出阈值时就发触发邮件告警。
上述配置仅是对主机资源做了监控,并且告警只发到了缺省联系人组。设想一下,在实际生产环境中,可能会按产品线或业务功能进行分组来研发,不同的服务出现告警时只发送通知到对应的联系人组,其他不相关的组不需要接告警收通知,这就需要我们修改告警路由规则,而Alertmanager的核心和最复杂的地方就在告警路由规则的设置上。
Prometheus的告警规则在推送给Alertmanager前有的三种状态:
1、没有触发告警阈值时,状态为:inactive
2、触发了告警阈值但未满足告警持续时间(for)时,状态为:pending,如果不配置for或者指定for的值为0,则将跳过pending状态。
3、已触发告警阈值并达到告警持续时间,开始将告警事件推送到Alertmanager,此时状态为:firing。
配置告警静默(silence),用于在预期内的维护升级等操作。
当我们在对系统进行维护升级时,通常不希望触发告警通知;另外,当上游服务出现异常,想让下游的服务不触发告警,Prometheus将用于这种配置称为silence(静默)。silence用于设定一个(维护)时间段,如1小时,也可提前手动触发silence过期,表示维护结束,恢复对应服务的告警通知功能。
设置silence的方式有以下2种:
1、登录到alertmanager的控制台操作
2、通过amtool命令进行操作
配置告警模板
Alertmanager的通知模板是基于Go模板系统,详细可参考官网。
https://golang.org/pkg/text/template/
https://prometheus.io/docs/alerting/latest/notifications/#alert
https://prometheus.io/docs/prometheus/latest/configuration/template_reference/
模板配置步骤:
1、修改alertmanager.yml,配置模板地址,然后在每个receiver引用模板
templates:
- '/usr/local/alertmanager/template/default.tmpl'
...
...
html: '{{ template "default.html" . }}'
headers: { Subject: "{{ .GroupLabels.SortedPairs.Values }} [{{ .Status | toUpper }}:{{ .Alerts.Firing | len }}]" }
2、配置模板
default.tmpl
{{ define "default.html" }}
{{- if gt (len .Alerts.Firing) 0 -}}
[{{ .Status | toUpper }}:{{ .Alerts.Firing | len }}]
{{ range $i, $alert := .Alerts }}
<pre>
告警节点:{{ index $alert.Labels "nodename" }}
告警服务:{{ index $alert.Labels "alertname" }}
报警详情:{{ index $alert.Annotations "summary" }}
开始时间:{{ $alert.StartsAt }}
</pre>
{{ end }}
{{ end }}
{{- if gt (len .Alerts.Resolved) 0 -}}
[{{ .Status | toUpper }}:{{ .Alerts.Resolved | len }}]
{{ range $i, $alert := .Alerts }}
<pre>
恢复节点:{{ index $alert.Labels "nodename" }}
恢复服务:{{ index $alert.Labels "alertname" }}
状 态:{{ index $alert.Status }}
开始时间:{{ $alert.StartsAt }}
恢复时间:{{ $alert.EndsAt }}
</pre>
{{ end }}
{{ end }}
{{- end }}
注:告警模板如果配置有问题,会导致邮件发送失败,注意观察日志。
以下是静默设置步骤:
1、登录到alertmanager控制台(http://IP:9093/#/alerts),点击上方菜单栏中Alerts,可看到当前有2个告警。
2、点击右上角"New Silence",创建Silence任务,具体设置如下,匹配规则支持正则。
注:可按instance或job_name等方式来进行正则匹配。
3、Silence创建成功后,可以看到处于Active状态的Silence
总之,多实践。