DevOps之prometheus实现优雅的告警

2020-07-07  本文已影响0人  OrangeLoveMilan

1、简介

目前prometheus的告警,常用的有grafana自带的告警和prometheus插件alertmanger的告警两种,这里测试下alertmanger的告警功能。

2、两种告警方案的比较

综合考虑,配合上prometheus operator,使用alertmanger,能够使监控告警这块的工作更加devops。

3、Alertmanger在prometheus operator中的实现

prometheus operator 在k8s中引入了自定义资源定义(CRSs)Prometheus、ServiceMonitor、PrometheusRule和Alertmanager。

所以在k8s中搭建好prometheus operator后,当我们需要监控一个项目时,我们的配置顺序是配置ServiceMonitor获取监控数据,配置PrometheusRule获取告警阈值,配置Alertmanager制定告警发送方式

如果我们已经完成了ServerMonitor的对象的编写,下面就要将监控好的重要数据,设置阈值,触发告警。

3.1、配置PrometheusRule

这里用spark 服务cpu使用率为例,介绍下PrometheusRule的写法

##Spark cpu负载 > 0.9   持续:5min 高级别告警

apiVersion: monitoring.coreos.com/v1     ##apiversion 按照官网来,切随意变动
kind: PrometheusRule                     ##prometheus operator的kind规范,切随意变动
metadata:
  name: spark-server-status              ##自定义,告警资源对象的名称
  namespace: monitoring                  ##自定义,自定义,需要与prometheus资源对象的namespace保持一致,不然匹配不到这个rule,因为promethes资源对象的选择器并没有namespace
  labels:
    prometheus: k8s                      ##自定义,需要与prometheus资源对象里面的ruleSelector的label保持一致
    role: alert-rules                    ##自定义,需要prometheus资源对象里面的ruleSelector的label保持一致
spec:
  groups:
    - name: spark-server-status.rules    ##自定义,告警组的名称
      rules:
        - alert: SparkCpuUsage           ##自定义,告警项的名称
          expr: sum(rate(container_cpu_usage_seconds_total{pod=~"^xxx.*"}[1m])) by (pod) / sum(container_spec_cpu_quota{pod=~"^xxx.*"} /100000) by (pod) > 0.9                              ##自定义,promsql获取数据,与告警阈值比较,这里是pod的cpu使用率大于0.9就触发告警
          for: 5m                        ##自定义,持续时长,即满足告警条件后,持续的时长到5m,prometheus的监控值由pending转为firing状态,触发告警
          labels:
            severity: critical           ##自定义,这里自定义了一个label,高级别的告警,后面用来抑制低级别告警
          annotations:                   ##自定义,告警的内容,可使用变量,即promsql里面可使用的变量,用来描述告警
            summary: "Instance {{ $labels.instance }} Spark cpu useage is high"
            description: "{{ $labels.instance }} of job {{ $labels.job }} cpu used more than 90% last more than 5 minutes."

这样我们就完成一个PrometheusRule 资源对象的编写了,那么prometheus是怎么识别这个告警规则的呢。

我们先查看下prometheus的资源对象

kubectl get prometheus/k8s -n monitoring -o yaml

.......
  ruleSelector:
    matchLabels:
      prometheus: k8s
      role: alert-rules
.......

可以看到,prometheus会自动匹配标签为prometheus=k8s 和 role=alert-rules的prometheusRule的资源对象,这里我们可以体会到prometheus operator自动发现的魅力,我们只需要编写相应的告警规则yaml文件,然后apply一下,便可以制定告警。

kubectl apply -f Spark_alert.yml

在prometheus界面上面查看刚刚制定的告警规则

告警规则

3.2、配置告警方式

对于告警通知,需要考虑以下几点

及时性:邮件通知有时候不会注意,尤其是不在电脑面前,所以这里我们选择工作中使用的企业微信作为告警消息推送方式
简洁性:如果服务器性能等到达了一个warning值,会有很多相关的告警全部触发,所以这里我们需要配置分组、静默、抑制方案
容灾性:如果alermanger或者prometheus本身挂掉了,发不出告警怎么办,一般会采用另一个监控来监控prometheus,或者自定义一个持续不断的告警通知,哪一天这个告警通知不发了,说明监控出现问题了。很棒的一点是,prometheus operator已经考虑了这一点,本身携带一个watchdog,作为对自身的监控

创建一个alertmanger配置文件

global:
  resolve_timeout: 5m         ##每5分钟检查下报警是否恢复

inhibit_rules:                ##静默规则:当同一个job内,出现多个告警时,只将高级别告警发送出来
- source_match:               ##发送的告警标签       
    severity: 'critical'
  target_match:               ##被抑制的告警标签
    severity: 'warning'
  equal: ['job']              ##匹配的标签,即当同一个job出现多个告警的时候,会优先发出级别为critical的告警

route:                        ##顶级路由,可以通过制定不同的路由,将不同的告警信息发送给不同的人,这里顶级路由需要匹配所有的告警
  group_by:                   ##分组,需要匹配所有的告警,所以这里可以用监控job分组
  - job
  group_interval: 5m          ## 分组创建多久后才可以发送压缩的警报,也就是初次发警报的延时,这样会确保第一次通知的时候, 有更多的报警被压缩在一起
  group_wait: 30s             
  receiver: 'wxwork'          ## 默认的发送人
  repeat_interval: 3h         ## 告警发送成功后,重复发送的时间,这个时间可以长一点,这样在处理问题的时候就不会出现大量的重复告警了
  routes:                     ##子路由
  - match:
      severity: warning       ## 将warning的告警发送给wxwork工作组
    receiver: 'wxwork'


receivers:
- name: wxwork                ## 企业微信的信息,这里参数需要参考官网的api文档:https://prometheus.io/docs/alerting/latest/configuration/
  wechat_configs:
  - send_resolved: true
    corp_id: 'xxxxxx'
    to_user: 'lugo'
    agent_id: 'xxxxxx'
    api_secret: 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
templates:
- 'wechat.tmpl'               ## 告警模板
wechat.tmpl 告警模板
{{ define "wechat.default.message" }}
{{ if gt (len .Alerts.Firing) 0 -}}
@告警通知
***************************
{{ range $index,$alert := .Alerts }}
告警实例: {{ $alert.Labels.instance }}
告警类型: {{ $alert.Labels.alertname }}
告警级别: {{ $alert.Labels.severity }}
告警信息: {{ $alert.Annotations.summary }}
告警详情: {{ $alert.Annotations.description }}
触发时间: {{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
***************************
{{- end }}
{{- end }}

{{ if gt (len .Alerts.Resolved) 0 -}}
@告警恢复
***************************
{{ range $index,$alert := .Alerts }}
告警实例: {{ $alert.Labels.instance }}
告警类型: {{ $alert.Labels.alertname }}
告警级别: {{ $alert.Labels.severity }}
告警信息: {{ $alert.Annotations.summary }}
告警详情: {{ $alert.Annotations.description }}
触发时间: {{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
恢复时间: {{ $alert.EndsAt.Format "2006-01-02 15:04:05" }}
***************************
{{- end }}
{{- end }}
@告警连接
{{ template "__alertmanagerURL" .}}
{{- end }}

删除之前的secret对象,并且创建新的

kubectl delete secret/alertmanager-main -n monitoring

kubectl create secret generic alertmanager-main --from-file=alertmanager.yaml --from-file=wechat.tmpl -n monitoring

查看企业微信,这个时候会发现已经收到告警信息


watch

这个watchdog便是对prometheus自身的监控。如果有需要,可以制定一条路由,匹配severity为none的告警,然后每24h重复一次,这样可以达到每天监控prometheus本身的效果,哪一天没收到watchdog,便可以知道prometheus挂了。

正常收到的告警信息

正常告警图片

alertmanger也支持webhook告警,但是比如钉钉和企业微信机器人这类对消息头有特殊要求的,如果直接用webhook的话,需要安装一个插件封装下,才可以调用

3.3、临时静默告警

Alertmanager还支持临时静默告警。有时候我们在处理告警,想要临时静默告警消息,或者测试环境中,进行压测,需要临时静默一段时间的告警,我们就可以直接通过Alertmanager的UI临时屏蔽特定的告警通知。通过定义标签的匹配规则(字符串或者正则表达式),如果新的告警通知满足静默规则的设置,则停止向receiver发送通知
目前Alertmanager只支持在UI上面进行临时静默告警

临时静默

当静默规则生效以后,从Alertmanager的Alerts页面下用户将不会看到该规则匹配到的告警信息,微信机器人也不会发送响应的告警消息

上一篇下一篇

猜你喜欢

热点阅读