美文网首页
DevOps之prometheus实现优雅的告警

DevOps之prometheus实现优雅的告警

作者: OrangeLoveMilan | 来源:发表于2020-07-07 09:10 被阅读0次

    1、简介

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

    2、两种告警方案的比较

    • 告警通知的渠道:为了更即时的收到告警信息,打算采用企业微信推送告警信息。grafana目前不支持企业微信推送告警通知,github上有人提交过pr,不过至今还没有merge到master上,只能通过修改源码来实现企业微信告警,不够灵活。alertmanger官方支持企业微信告警。
    • 告警规则的创建:grafana可以直接在界面上面创建告警规则,添加注释,测试规则,存储到数据库里。alertmager的话,在prometheus operator中,可以通过yml文件来创建告警规则,这样维护起来更有效率。
    • 告警的功能:grafana的告警功能方面比较简单。而alertmanager具备更强大的分组、静默、抑制等功能,可以使告警更加优雅

    综合考虑,配合上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页面下用户将不会看到该规则匹配到的告警信息,微信机器人也不会发送响应的告警消息

    相关文章

      网友评论

          本文标题:DevOps之prometheus实现优雅的告警

          本文链接:https://www.haomeiwen.com/subject/rugoqktx.html