我们之前讲过,一个完整的监控流程应该是:数据采集(exporter)、采集到数据之后,做数据的可视化(grafana)、然后是监控告警部分,基本上是一个完整的流程。
Prometheus 扮演的角色是,数据的采集,存储、定制告警规则;数据展示则是基于grafana、告警则是借助Alertmanager来实现。

告警工作过程

在Prometheus Server中定义告警规则以及产生告警,Alertmanager组件则用于处理这些由Prometheus产生的告警。Alertmanager即Prometheus体系中告警的统一处理中心。

Alertmanager提供了多种内置第三方告警通知方式,同时还提供了对Webhook通知的支持,通过Webhook用户可以完成对告警更多个性化的扩展。

prometheus触发一条告警的过程:
prometheus—->触发阈值—->超出持续时间—->alertmanager—->分组|抑制|静默—->媒体类型—->邮件|钉钉|微信等。
image.png

AlertManager特性

Alertmanager除了提供基本的告警通知能力以外,还主要提供了如:分组、抑制以及静默等告警特性:

分组:

分组机制可以将详细的告警信息合并成一个通知。在某些情况下,比如由于系统宕机导致大量的告警被同时触发,在这种情况下分组机制可以将这些被触发的告警合并为一个告警通知,避免一次性接受大量的告警通知,而无法对问题进行快速定位。

抑制:

当警报发出后,停止重复发送由此警报引发的其他警报。可以消除冗余告警。

静默:

是一种简单的特定时间静音的机制。例如:服务器要升级维护可以先设置这个时间段告警静默。类似zabbix的维护功能。

Alertmanager部署

1 下载安装

  1. [admin@localhost prometheus-download]$ wget https://github.com/prometheus/alertmanager/releases/download/v0.21.0/alertmanager-0.21.0.linux-amd64.tar.gz
  2. [admin@localhost prometheus-download]$ tar -xf alertmanager-0.21.0.linux-amd64.tar.gz
  3. [admin@localhost prometheus-download]$ cd alertmanager-0.20.0.linux-amd64
  4. [admin@localhost alertmanager-0.21.0.linux-amd64]$ ll
  5. total 51652
  6. -rwxr-xr-x. 1 admin admin 28871879 Jun 17 16:54 alertmanager
  7. -rw-r--r--. 1 admin admin 842 Nov 26 23:01 alertmanager.yml
  8. -rwxr-xr-x. 1 admin admin 23987848 Jun 17 16:55 amtool
  9. drwxrwxr-x. 2 admin admin 4096 Nov 25 17:19 data
  10. -rw-r--r--. 1 admin admin 11357 Jun 17 17:34 LICENSE
  11. -rw-r--r--. 1 admin admin 457 Jun 17 17:34 NOTICE
  12. drwxrwxr-x. 2 admin admin 4096 Nov 25 23:08 template

2 定义一下分组和路由

  1. cat alertmanager.yml
  2. # 全局配置项
  3. global:
  4. resolve_timeout: 5m
  5. smtp_smarthost: 'smtp.163.com:25' #使用163邮箱
  6. smtp_from: 'monitoring2020@163.com' #邮箱名称
  7. smtp_auth_username: 'monitoring2020@163.com' #登录邮箱名称
  8. smtp_auth_password: 'NHGJPAVAGO00000000' #授权码,不是登陆密码
  9. smtp_require_tls: false
  10. #wechat_api_url: 'https://qyapi.weixin.qq.com/cgi-bin/' # 企业微信地址
  11. # 定义模板信心
  12. templates:
  13. - 'template/*.tmpl' #模板路径
  14. route: #默认路由
  15. group_by: ['instance','job'] #根据instance和job标签分组,同标签下的告警会在一个邮件中展现
  16. group_wait: 30s # 最初即第一次等待多久时间发送一组警报的通知
  17. group_interval: 5m # 在发送新警报前的等待时间
  18. repeat_interval: 10h #重复告警间隔
  19. receiver: email #默认接收者的名称,以下receivers name的名称
  20. routes: #子路由,不满足子路由的都走默认路由
  21. - receiver: leader
  22. match: #普通匹配
  23. severity: critical #报警规则中定义的报警级别
  24. - receiver: support_team
  25. match_re: #正则匹配
  26. severity: ^(warn|critical)$
  27. receivers: #定义三个接受者,和上面三个路由对应
  28. - name: 'email'
  29. email_configs:
  30. - to: 'jordan@163.com'
  31. - name: 'leader'
  32. email_configs:
  33. - to: 'jordan@wicre.com'
  34. - name: 'support_team'
  35. email_configs:
  36. - to: 'mlkdesti@163.com'
  37. html: '{{ template "test.html" . }}' # 设定邮箱的内容模板
  38. headers: { Subject: "[WARN] 报警邮件"} # 接收邮件的标题
  39. send_resolved: true #恢复的时候发送告警消息
  40. webhook_configs: # webhook配置
  41. - url: 'http://127.0.0.1:5001'
  42. send_resolved: true
  43. wechat_configs: # 企业微信报警配置
  44. - send_resolved: true
  45. to_party: '1' # 接收组的id
  46. agent_id: '1000002' # (企业微信-->自定应用-->AgentId)
  47. corp_id: '******' # 企业信息(我的企业-->CorpId[在底部])
  48. api_secret: '******' # 企业微信(企业微信-->自定应用-->Secret)
  49. message: '{{ template "test_wechat.html" . }}' # 发送消息模板的设定
  50. # 一个inhibition规则是在与另一组匹配器匹配的警报存在的条件下,使匹配一组匹配器的警报失效的规则。两个警报必须具有一组相同的标签。
  51. inhibit_rules:
  52. - source_match:
  53. severity: 'critical'
  54. target_match:
  55. severity: 'warning'
  56. equal: ['alertname', 'dev', 'instance']

注:
1)repeat_interval配置项,对于email来说,此项不可以设置过低,否则将会由于邮件发送太多频繁,被smtp服务器拒绝
2)企业微信注册地址:https://work.weixin.qq.com

3 检查一下配置文件相关语法信息

  1. [admin@localhost alertmanager-0.21.0.linux-amd64]$ ./amtool check-config alertmanager.yml
  2. Checking 'alertmanager.yml' SUCCESS
  3. Found:
  4. - global config
  5. - route
  6. - 0 inhibit rules
  7. - 3 receivers
  8. - 0 templates

4 添加到启动项,并且启动、默认监听9093端口

  1. # cat alertmanager.service
  2. [Unit]
  3. Description=alertmanager
  4. After=network.target
  5. [Service]
  6. Type=simple
  7. ExecStart=/data01/prometheus-download/alertmanager-0.21.0.linux-amd64/alertmanager --config.file=/data01/prometheus-download/alertmanager-0.21.0.linux-amd64/alertmanager.yml
  8. ExecReload=/bin/kill -HUP $MAINPID
  9. ExecStop=/bin/kill -KILL $MAINPID
  10. KillMode=control-group
  11. Restart=on-failure
  12. RestartSec=3s
  13. [Install]
  14. WantedBy=multi-user.target

5 启动

  1. systemctl enable alertmanager
  2. systemctl start alertmanager
  3. systemctl stop alertmanager
  4. systemctl reload alertmanager

6 端口9093

image.png

配置 prometheus 规则与alert

1 配置prometheus.yml文件中的alerting部分

修改prometheus.yml文件中的alerting部分,让alertmanger能与Prometheus通信

  1. #Alertmanager configuration
  2. alerting:
  3. alertmanagers:
  4. - static_configs:
  5. - targets:
  6. - 127.0.0.1:9093

2 定义告警文件

  1. #Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
  2. rule_files:
  3. - "rules/*.yml"

3 告警规则定义

这里简单的从主机down机简单写起:

  1. # cat node_monitor.yml
  2. - name: 主机状态-监控告警 #告警分组,一个组下的告警会整合在一个邮件中
  3. rules:
  4. - alert: 主机状态 #监控项名称
  5. expr: up == 0 #正则表达式,up{job:"linux"} 可以在prometheus查询,自己定义监控状态
  6. for: 1m #for选项定义表达式持续时长,0的话代表一满足就触发
  7. labels:
  8. severity: critical #定义了一个报警级别的标签,告警发送给不同组的,是基于这个标签进行路由
  9. annotations: #邮件中告警内容,可引用变量
  10. summary: "{{$labels.instance}}:服务器宕机"
  11. description: "{{$labels.instance}}:服务器延时超过5分钟,请及时查看"

说明:

  1. Prometheus支持使用变量来获取指定标签中的值。比如$labels.<labelname>变量可以访问当前告警实例中指定标签的值。$value可以获取当前PromQL表达式计算的样本值。
  2. 在创建规则文件时,建议为不同的监控对象建立不同的告警文件,比如monitoring_redis.yml、monitoring_mysql.yml,这里我们监控主机状态,我们使用monitoring_node.yml
  3. expr是我们比较关注的内容,可以根据promql来写查询表达式:

image.png

4 保存退出。重启一下prometheus

我们重启一下prometheus server的配置,然后测试一下关闭某台主机的监控:

  1. [root@host-10-10-2-62 ~]# systemctl stop node_exporter

image.png

5 查看alstermanager的状态

image.png

6 查看prometheus状态

image.png
image.png

状态说明 Prometheus Alert 告警状态有三种状态:Inactive、Pending、Firing。

Inactive:非活动状态,表示正在监控,但是还未有任何警报触发。 Pending:表示这个警报必须被触发。由于警报可以被分组、压抑/抑制或静默/静音,所以等待验证,一旦所有的验证都通过,则将转到 Firing 状态。 Firing:将警报发送到 AlertManager,它将按照配置将警报的发送给所有接收者。一旦警报解除,则将状态转到 Inactive,如此循环。

7 收到告警信息

image.png

定义告警模板

然所有核心的信息已经包含了,但是邮件格式内容可以更优雅直观一些,那么,AlertManager 也是支持自定义邮件模板配置,

1 首先新建一个模板文件

  1. [admin@localhost alertmanager-0.21.0.linux-amd64]$ cat test.tmpl
  2. {{ define "email.to.html" }}
  3. {{ range .Alerts }}
  4. =========start==========<br>
  5. 告警程序: prometheus_alert <br>
  6. 告警级别: {{ .Labels.severity }} <br>
  7. 告警类型: {{ .Labels.alertname }} <br>
  8. 故障主机: {{ .Labels.instance }} <br>
  9. 告警主题: {{ .Annotations.summary }} <br>
  10. 告警详情: {{ .Annotations.description }} <br>
  11. 触发时间: {{ .StartsAt }} <br>
  12. =========end==========<br>
  13. {{ end }}
  14. {{ end }}

文中定义了一个变量,test.html这个变量,可以在配置中引用:

2 修改配置文件,使用模板

  1. global:
  2. resolve_timeout: 5m
  3. smtp_smarthost: 'smtp.163.com:25'
  4. smtp_from: 'monitoring2020@163.com'
  5. smtp_auth_username: 'monitoring2020@163.com'
  6. smtp_auth_password: 'NHGJPAVAGOAZSJZD'
  7. smtp_require_tls: false
  8. # 定义模板信心
  9. templates:
  10. - 'template/*.tmpl' #引用模板
  11. route:
  12. group_by: ['instance']
  13. group_wait: 30s
  14. group_interval: 5m
  15. repeat_interval: 10h
  16. receiver: email
  17. routes:
  18. - receiver: leader
  19. match:
  20. severity: critical
  21. - receiver: support_team
  22. match_re:
  23. severity: ^(warn|critical)$
  24. receivers: #定义三个接受者,和上面三个路由对应
  25. - name: 'email'
  26. email_configs:
  27. - to: 'jordan@163.com'
  28. html: '{{ template "test.html" . }}' # 设定邮箱的内容模板
  29. - name: 'leader'
  30. email_configs:
  31. - to: 'jordan@wicre.com'
  32. html: '{{ template "test.html" . }}' # 设定邮箱的内容模板
  33. - name: 'support_team'
  34. email_configs:
  35. - to: 'mlkdesti@163.com'
  36. html: '{{ template "test.html" . }}' # 设定邮箱的内容模板
  37. headers: { Subject: "[WARN] 报警邮件"} # 接收邮件的标题

3 测试发送效果

image.png

4 恢复告警通知

在上面的时候,发生告警的时候,会送邮件,那么当恢复的时候,我们需要发送邮件恢复正常邮件,只要在配置的时候,加上:send_resolved: true

  1. 5、添加恢复消息:
  2. receivers: #定义三个接受者,和上面三个路由对应
  3. - name: 'email'
  4. email_configs:
  5. - to: 'jordan@163.com'
  6. html: '{{ template "test.html" . }}' # 设定邮箱的内容模板
  7. send_resolved: true #恢复的时候发送告警消息
  8. - name: 'leader'
  9. email_configs:
  10. - to: 'jordan@wicre.com'
  11. html: '{{ template "test.html" . }}' # 设定邮箱的内容模板
  12. send_resolved: true #恢复的时候发送告警消息
  13. - name: 'support_team'
  14. email_configs:
  15. - to: 'mlkdesti@163.com'
  16. html: '{{ template "test.html" . }}' # 设定邮箱的内容模板
  17. headers: { Subject: "[WARN] 报警邮件"} # 接收邮件的标题
  18. send_resolved: true #恢复的时候发送告警消息

5 修改模板,添加恢复消息

  1. #####cat test.tmpl
  2. {{ define "test.html" }}
  3. {{ if gt (len .Alerts.Firing) 0 }}{{ range .Alerts }}
  4. @故障告警:<br>
  5. 告警程序: prometheus_alert <br>
  6. 告警级别: {{ .Labels.severity }} <br>
  7. 告警类型: {{ .Labels.alertname }} <br>
  8. 故障主机: {{ .Labels.instance }} <br>
  9. 告警主题: {{ .Annotations.summary }} <br>
  10. 告警详情: {{ .Annotations.description }} <br>
  11. 触发时间: {{ .StartsAt }} <br>
  12. {{ end }}
  13. {{ end }}
  14. {{ if gt (len .Alerts.Resolved) 0 }}{{ range .Alerts }}
  15. @故障恢复:<br>
  16. 告警主机:{{ .Labels.instance }} <br>
  17. 告警主题:{{ .Annotations.summary }} <br>
  18. 恢复时间: {{ .EndsAt }} <br>
  19. {{ end }}
  20. {{ end }}
  21. {{ end }}

6 邮件详情

image.png

告警收敛(分组,抑制,静默)

1 分组(group)

将类似性质的警报合并为单个通知。

  1. group_by: ['alertname'] # 以标签作为分组依据
  2. group_wait: 10s # 分组报警等待时间
  3. group_interval: 10s # 发送组告警间隔时间
  4. repeat_interval: 1h # 重复告警发送间隔时间

2 抑制(inhibition)

当警报发出后,停止重复发送由此警报引发的其他警报。可以消除冗余告警

  1. inhibit_rules:
  2. - source_match: # 当此告警发生,其他的告警被抑制
  3. severity: 'critical'
  4. target_match: # 被抑制的对象
  5. severity: 'warning'
  6. equal: ['id', 'instance']

当同时发生warning和critical告警时候,会抑制掉warning的告警,只发送critical的信息。

3 静默(silences)

是一种简单的特定时间静音的机制。例如:服务器要升级维护可以先设置这个时间段告警静默。(类似zabbix 的维护周期):

可以看到我们没有添加告警静默的时候,这个时候是会收到多个消息。

在alertmanager添加静默:
image.png

创建:
image.png

当然你也可以用new silence来进行添加,不过这个需要自己手动去匹配,用上面的方式是最方便的。维护结束后,直接删除即可。