美文网首页
Prometheus监控神器-Alertmanager篇(2)

Prometheus监控神器-Alertmanager篇(2)

作者: 青牛踏雪御苍穹 | 来源:发表于2020-08-06 13:15 被阅读0次

    本章主要对如何使用开源组件和Alertmanager组件集成警报通知。Kubernetes的警报集成后续会直接在配置文件讲解,原理大同小异,此处仅对相关警报通知做集成。

    警报通知接收器

    前面一直是在Web UI 查看警报信息,现在开始使用接收器与Alertmanager集成,发送警报信息到 Email企业微信钉钉机器人,对于警报要求比较高的同学,可以根据下面提到的开源组件 【PrometheusAlert全家桶】 配置飞书、短信、语音电话等警报。

    Email

    前面已经讲过,Alertmanager默认支持配置Email,也是最普通的方式,在Alertmanager组件中内置了SMTP协议。直接可以把前面的Alertmanager.yml中的SMTP部分截取出来,然后进行调整与配置

    global:
      resolve_timeout: 5m
      # smtp配置
      smtp_from: "1234567890@qq.com" # 发送邮件主题
      smtp_smarthost: 'smtp.qq.com:465' # 邮箱服务器的SMTP主机配置
      smtp_auth_username: "1234567890@qq.com" # 登录用户名
      smtp_auth_password: "auth_pass" # 此处的auth password是邮箱的第三方登录授权密码,而非用户密码,尽量用QQ来测试。
      smtp_require_tls: false # 有些邮箱需要开启此配置,这里使用的是163邮箱,仅做测试,不需要开启此功能。
    route:
      receiver: ops
      group_wait: 30s # 在组内等待所配置的时间,如果同组内,30秒内出现相同报警,在一个组内出现。
      group_interval: 5m # 如果组内内容不变化,合并为一条警报信息,5m后发送。
      repeat_interval: 24h # 发送报警间隔,如果指定时间内没有修复,则重新发送报警。
      group_by: [alertname]  # 报警分组
      routes:
          - match:
              team: operations
            group_by: [env,dc]
            receiver: 'ops'
          - receiver: ops # 路由和标签,根据match来指定发送目标,如果 rule的lable 包含 alertname, 使用 ops 来发送
            group_wait: 10s
            match:
              team: operations
    # 接收器指定发送人以及发送渠道
    receivers:
    # ops分组的定义
    - name: ops
      email_configs:
      - to: '9935226@qq.com,xxxxx@qq.com' # 如果想发送多个人就以 ','做分割,写多个邮件人即可。
        send_resolved: true
        headers:
          from: "警报中心"
          subject: "[operations] 报警邮件"
          to: "小煜狼皇"
    

    配置完成后,直接重启Alertmanager组件,使配置生效,然后使用前面内存阈值触发一次警报来看下发送结果。

    收到的警报信息:

    邮件警报信息

    当警报接触以后收到的恢复信息。

    邮件恢复信息

    企业微信

    首先你要具有企业微信管理员的权限,如果没有可以自己注册一个,进行测试,我这里有自行注册的企业微信

    第一步登录进入以后,在应用管理中新建应用。

    企业微信应用

    第二步,创建应用,信息填写如下,上传应用logo随意。

    企业微信应用信息

    创建成功以后如下图。

    微信应用信息

    这时候需要把 AgentIdSecret 记录下来,对于你的这种Secret信息,最好管理好,我的用过就会删除,所以不用担心安全隐患。

    ID key
    AgentId 1000004
    Secret F-fzpgsabmfiFt7_4QRQwWEl8eyx7evO12sRYe_Q5vA

    第三步,现在我们来用新建的企业微信应用在Alertmanager配置,可以配置全局,也可以对单独需要发送的接收器,因为警报需要分级,所以需要单独处理,在这里使用的的单独的配置,需要知道 企业ID ,以及 部门ID

    企业ID 通过

    企业ID

    部门ID 通过通讯录获取

    部门ID
    # 企业微信配置
      wechat_configs:
      - corp_id: 'wwxxxxx' # 企业ID是唯一标识
        api_url: 'https://qyapi.weixin.qq.com/cgi-bin/' # 企业微信api接口,统一定义
        send_resolved: true # 设置发送警报恢复信息
        to_party: '2' # 部门id,比如我的叫警报组,因此显示的是2,如果你DB组,就可能会是3,WEB组就是4,依次类推,另外需要接收警报的相关人员必须在这个部门里。
        agent_id: '1000004' # 新建应用的agent_id
        api_secret: 'F-fzpgsabmfiFt7_4QRQwWEl8eyx7evO12sRYe_Q5vA' # 新建应用的Secret
    

    这时候我们重启Alertmanager,然后使用之前的方式来触发模拟警报,看看发送是不是已经没有问题了,这时我们的企业微信中、Email都可以收到警报了,这里的警报已经被我用模块处理过了。可读性会更高。

    cat wechat.tmpl
    ## wechat模板
    {{ define "wechat.default.message" }}
    {{ if gt (len .Alerts.Firing) 0 -}}
    Alerts Firing:
    {{ range .Alerts }}
    警报级别:{{ .Labels.status }}
    
    警报类型:{{ .Labels.alertname }}
    
    故障主机: {{ .Labels.instance }}
    
    警报主题: {{ .Annotations.summary }}
    
    警报详情: {{ .Annotations.description }}
    
    ⏱ : {{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
    {{- end }}
    {{- end }}
    
    {{ if gt (len .Alerts.Resolved) 0 -}}
    Alerts Resolved:
    {{ range .Alerts }}
    警报级别:{{ .Labels.status }}
    
    警报类型:{{ .Labels.alertname }}
    
    故障主机: {{ .Labels.instance }}
    
    警报主题: {{ .Annotations.summary }}
    
    警报详情: {{ .Annotations.description }}
    
    ⏱ : {{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
    ⏲ : {{ (.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
    {{- end }}
    {{- end }}
    {{- end }}
    

    Firing警报:

    企业微信警报信息

    下面是Resolve的警报:

    企业恢复信息

    钉钉机器人(Webhook)

    对于钉钉大家都已经很熟悉了,大部分企业都已经启用钉钉办公了,同时其推出的免费的webhook机器人也很受大家的欢迎。我们这里讲一下借助第三方开源组件如何对钉钉集成警报功能。

    首先需要在钉钉创建机器人,然后在白名单中添加关键字信息与ip限制等安全设置,这个只要你有群,你就可以在群里面建,非常简单,这里就不做演示了

    先把Prometheus-webhook-Dingtalk组件装好。

    mkdir -p /etc/prometheus-webhook-dingtalk/template/
    cd /etc/prometheus-webhook-dingtalk/
    wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v1.4.0/prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz
    tar xf prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz
    mv prometheus-webhook-dingtalk-1.4.0.linux-amd64/* /etc/prometheus-webhook-dingtalk/
    mv prometheus-webhook-dingtalk /bin/
    cat <<EOF> /lib/systemd/system/prometheus-webhook-dingtalk.service 
    [Unit]
    Description=prometheus-webhook-dingding
    Documentation=https://prometheus.io/
    After=network.target
    
    [Service]
    Type=simple
    User=prometheus
    ExecStart=/bin/prometheus-webhook-dingtalk --web.listen-address=":8070" --web.enable-ui --config.file="/etc/prometheus-webhook-dingtalk/config.yml"
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    EOF
    ## 启动服务
    systemctl enable prometheus-webhook-dingtalk.service
    systemctl start prometheus-webhook-dingtalk.service
    

    配置文件

    ## Request timeout
    # timeout: 5s
    
    ## Customizable templates path
    ## Customizable templates path
    templates:
            # - contrib/templates/legacy/template.tmpl
      # 自定义模板路径
      - /etc/prometheus-webhook-dingtalk/template/default.tmpl
    
    ## 你还可以使用' default_message '覆盖默认模板
    ## 下面的示例使用v0.3.0中的“legacy”模板
    # default_message:
    #   title: '{{ template "legacy.title" . }}'
    #   text: '{{ template "legacy.content" . }}'
    
    ## Targets, previously was known as "profiles"
    # 定义的webhook,钉钉创建的webhook token
    targets:
    # 如果有多个分组就可以在这里定义多个接口
      ops:
        url: https://oapi.dingtalk.com/robot/send?access_token=a4feed2322222222222222222222222
      web:
        url: https://oapi.dingtalk.com/robot/send?access_token=a4feed2325c1333333333333333333333
    

    定义模板:

    cd /etc/prometheus-webhook-dingtalk/template
    cat default.tmpl
    {{ define "__subject" }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join " " }} {{ if gt (len .CommonLabels) (len .GroupLabels) }}({{ with .CommonLabels.Remove .GroupLabels.Names }}{{ .Values | join " " }}{{ end }}){{ end }}{{ end }}
    {{ define "__alertmanagerURL" }}{{ .ExternalURL }}/#/alerts?receiver={{ .Receiver }}{{ end }}
    
    {{ define "__text_alert_list" }}{{ range . }}
    **Labels**
    {{ range .Labels.SortedPairs }}> - {{ .Name }}: {{ .Value | markdown | html }}
    {{ end }}
    **Annotations**
    {{ range .Annotations.SortedPairs }}> - {{ .Name }}: {{ .Value | markdown | html }}
    {{ end }}
    **Source:** [{{ .GeneratorURL }}]({{ .GeneratorURL }})
    {{ end }}{{ end }}
    
    {{/* Firing */}}
    
    {{ define "default.__text_alert_list" }}{{ range . }}
    
    **Trigger Time:** {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}
    
    **Summary:** {{ .Annotations.summary }}
    
    **Description:** {{ .Annotations.description }}
    
    **Graph:** [📈 ]({{ .GeneratorURL }})
    
    **Details:**
    {{ range .Labels.SortedPairs }}{{ if and (ne (.Name) "severity") (ne (.Name) "summary") }}> - {{ .Name }}: {{ .Value | markdown | html }}
    {{ end }}{{ end }}
    {{ end }}{{ end }}
    
    {{/* Resolved */}}
    
    {{ define "default.__text_resolved_list" }}{{ range . }}
    
    **Trigger Time:** {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}
    
    **Resolved Time:** {{ dateInZone "2006.01.02 15:04:05" (.EndsAt) "Asia/Shanghai" }}
    
    **Summary:** {{ .Annotations.summary }}
    
    **Graph:** [📈 ]({{ .GeneratorURL }})
    
    **Details:**
    {{ range .Labels.SortedPairs }}{{ if and (ne (.Name) "severity") (ne (.Name) "summary") }}> - {{ .Name }}: {{ .Value | markdown | html }}
    {{ end }}{{ end }}
    {{ end }}{{ end }}
    
    {{/* Default */}}
    {{ define "default.title" }}{{ template "__subject" . }}{{ end }}
    {{ define "default.content" }}#### \[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}\] **[{{ index .GroupLabels "alertname" }}]({{ template "__alertmanagerURL" . }})**
    {{ if gt (len .Alerts.Firing) 0 -}}
    
    ![Firing-img](https://is3-ssl.mzstatic.com/image/thumb/Purple20/v4/e0/23/cf/e023cf56-0623-0cdf-afce-97ae90eabfda/mzl.uplmrpgi.png/320x0w.jpg)
    
    **Alerts Firing**
    {{ template "default.__text_alert_list" .Alerts.Firing }}
    {{- end }}
    {{ if gt (len .Alerts.Resolved) 0 -}}
    
    ![Resolved-img](https://is3-ssl.mzstatic.com/image/thumb/Purple18/v4/41/72/99/4172990a-f666-badf-9726-6204a320c16e/mzl.dypdixoy.png/320x0w.png)
    
    **Alerts Resolved**
    {{ template "default.__text_resolved_list" .Alerts.Resolved }}
    {{- end }}
    {{- end }}
    
    {{/* Legacy */}}
    {{ define "legacy.title" }}{{ template "__subject" . }}{{ end }}
    {{ define "legacy.content" }}#### \[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}\] **[{{ index .GroupLabels "alertname" }}]({{ template "__alertmanagerURL" . }})**
    {{ template "__text_alert_list" .Alerts.Firing }}
    {{- end }}
    
    {{/* Following names for compatibility */}}
    {{ define "ding.link.title" }}{{ template "default.title" . }}{{ end }}
    {{ define "ding.link.content" }}{{ template "default.content" . }}{{ end }}
    

    在Aertmanager中配置警报

    # 接收器指定发送人以及发送渠道
    receivers:
    # ops分组的定义
    - name: ops
      email_configs:
      - to: '9935226@qq.com,10000@qq.com'
        send_resolved: true
        headers: { Subject: "[operations] 报警邮件"} # 接收邮件的标题
      # 钉钉配置
      webhook_configs:
      - url: http://localhost:8070/dingtalk/ops/send # 这里是在钉钉开源组件中的接口,如果单独定义的receiver需要对应你的分组与钉钉机器人的webhook token
        # 企业微信配置
      wechat_configs:
      - corp_id: 'ww5421dksajhdasjkhj'
        api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
        send_resolved: true
        to_party: '2'
        agent_id: '1000002'
        api_secret: 'Tm1kkEE3RGqVhv5hO-khdakjsdkjsahjkdksahjkdsahkj'
    # web
    - name: web
      email_configs:
      - to: '9935226@qq.com'
        send_resolved: true
        headers: { Subject: "[web] 报警邮件"} # 接收邮件的标题
      webhook_configs:
      - url: http://localhost:8070/dingtalk/web/send
    

    继续使用上面的触发模拟警报,此时会同时让三个警报都接受到警报信息,我们这里只是为了调试,往往一个警报通知就可以满足需求了,对于重要业务还是需要使用电话以及短信提醒。

    钉钉Firing警报:

    钉钉警报信息

    钉钉Resolve警报:

    钉钉恢复信息

    警报通知模板

    Prometheus 创建警报转发给 Alertmanager,Alertmanager会根据不同的 Label 向不同的 Receiver 发送警报通知,如Email、钉钉、企业微信、飞书、短信等等。所有 Receiver都一个接收模板,然后通过模板格式化以后发送警报信息给 Receiver。
    Alertmanager 自带的模板是基于 Go 语言的 template 模板,用户可以根据自己的需求去定义自己需要的模板,上面我给出的模板已经足够大家的基础使用了。

    下面介绍下通常自定义模板中会需要用到的一些参数说明

    名称 数据类型 描述
    Receiver string 接受警报通知的接收器名称
    Status string 警报状态,例如:Firing或Resolved的通知
    Alert Alert 警报通知的真实内容,警报中的所有列表
    GroupLables KV 包含警报通知的组标签
    CommandLabels KV 所有警报的公共标签,包含GroupLabels的所有标签
    CommandAnnotations KV 注释,比如自定义的一些字符串
    ExternalURL string 警报信息中的Alertmanager地址

    上面说的KV类型是一组使用不标示标签与注释的Key/Value字符串对,可以在Alertmanager中的默认模板中看到其定义。 default.tmpl

    其中邮件中所显示的 View In AlertManager ,Receiver 与 ExternalURL的定义其实就是模板中的 .ExternalURL.Receiver

    {{ define "__alertmanager" }}AlertManager{{ end }}
    
    {{ define "__alertmanagerURL" }}{{ .ExternalURL }}/#/alerts?receiver={{ .Receiver | urlquery }}{{ end }}
    ...
    

    在收到的邮箱警报中可以看到 View In AlertManager 的链接地址是:http://192.168.1.220:19093/#/alerts?receiver=ops

    对于Alert的类型,警报列表的字段还包含了如下参数与定义、描述

    名称 数据类型 描述
    Status string 定义警报状态是已经解决或处于触发状态
    Label KV 包含警报中的标签
    Annotations KV 警报的一组注释
    StartsAt time.Time 警报触发时间
    EndsAt time.Time 警报结束时间,只在警报结束的时间时设置
    GeneratorURL string 警报规则的连接URL,也就是Prometheus中的Rules查询地址

    对于警报中的通知模板首先要熟悉go语言的template语法以及HTML简单的基础知识,然后把上面相关的元数据的一些信息了解清楚,就可以自己调整模板了,如果你实在懒的改,我调整好的模板可以直接拿去用,把对应的指标、标签名字改一下就可以用了。

    以下是我自己修改了一下的模板警报格式,大家可以看看,这个是通过官方的 default.tmpl 修改的。

    Email模板警报信息

    开源警报组件推荐

    一个开源的第三方警报插件,针对钉钉机器人 webhook 做集成,Go语言编写,现在迭代的已经很不错了,可能有一些功能还是有些限制,比如针对 Markdown @某个人无法实现,原因是因钉钉自身API没有支持这个功能。

    这个开源组件是将Alertmanger Webhook 消息转换为可以接收消息的企业微信机器人,也是go语言编写,Alertmanager 默认已经集成企业微信配置,如果有特殊需求,需要使用企业微信机器人的可以看看这个。

    如果有对短信、电话警报等其他需求的同学,推荐这个开源警报组件,Go语言编写,Web框架是 Beego ,支持将收到的这些消息发送到钉钉,微信,飞书,腾讯短信,腾讯电话,阿里云短信,阿里云电话,华为短信,容联云电话等,这里就不细讲了,如果配置有问题可以随时咨询我。

    PrometheusAlert wecaht

    相关文章

      网友评论

          本文标题:Prometheus监控神器-Alertmanager篇(2)

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