美文网首页云原生
十八 Alertmanager告警实战

十八 Alertmanager告警实战

作者: 負笈在线 | 来源:发表于2022-06-11 09:48 被阅读0次

    https://github.com/dotbalo/k8s/blob/master/prometheus-operator/alertmanager.yaml
    https://prometheus.io/docs/alerting/latest/configuration/
    https://github.com/prometheus/alertmanager/blob/main/doc/examples/simple.yml

    (一) Alertmanager配置文件解析

    首先看一下一个简单的Alertmanager的配置示例:

    global:
      resolve_timeout: 5m
      ...
    https://alert.victorops.com/integrations/generic/20131114/alert/
    route:
      receiver: Default
      group_by:
      - namespace
      - job
      - alertname
      routes:
      - receiver: Watchdog
        match:
          alertname: Watchdog
      - receiver: Critical
        match:
          severity: critical
      group_wait: 30s
      group_interval: 5m
      repeat_interval: 10m
    inhibit_rules:
    - source_match:
        severity: critical
      target_match_re:
        severity: warning|info
      equal:
      - namespace
      - alertname
    - source_match:
        severity: warning
      target_match_re:
        severity: info
      equal:
      - namespace
      - alertname
    receivers:
    - name: Default
      email_configs:
      - send_resolved: true
        to: kubernetes_guide@163.com
        from: kubernetes_guide@163.com
        hello: 163.com
        smarthost: smtp.163.com:465
        auth_username: kubernetes_guide@163.com
        auth_password: <secret>
        headers:
          From: kubernetes_guide@163.com
          Subject: '{{ template "email.default.subject" . }}'
          To: kubernetes_guide@163.com
        html: '{{ template "email.default.html" . }}'
        require_tls: false
    - name: Watchdog
    - name: Critical
    templates: []
    

    Alertmanager的配置主要分为五大块:

    Global:全局配置,主要用来配置一些通用的配置,比如邮件通知的账号、密码、SMTP服务器、微信告警等。Global块配置下的配置选项在本配置文件内的所有配置项下可见,但是文件内其它位置的子配置可以覆盖Global配置;
    Templates:用于放置自定义模板的位置;
    Route:告警路由配置,用于告警信息的分组路由,可以将不同分组的告警发送给不同的收件人。比如将数据库告警发送给DBA,服务器告警发送给OPS;
    Inhibit_rules:告警抑制,主要用于减少告警的次数,防止“告警轰炸”。比如某个宿主机宕机,可能会引起容器重建、漂移、服务不可用等一系列问题,如果每个异常均有告警,会一次性发送很多告警,造成告警轰炸,并且也会干扰定位问题的思路,所以可以使用告警抑制,屏蔽由宿主机宕机引来的其他问题,只发送宿主机宕机的消息即可;
    Receivers:告警收件人配置,每个receiver都有一个名字,经过route分组并且路由后需要指定一个receiver,就是在此位置配置的。

    了解完Alertmanager主要的配置块后,接下来需要对Alertmanager比较重要的Route进行单独讲解,其它配置会在实践中进行补充。

    (二) Alertmanager路由规则

    route配置:

    route:
      receiver: Default
      group_by:
      - namespace
      - job
      - alertname
      routes:
      - receiver: Watchdog
        match:
          alertname: Watchdog
      - receiver: Critical
        match:
          severity: critical
      group_wait: 30s
      group_interval: 5m
      repeat_interval: 10m
    

    Ø receiver:告警的通知目标,需要和receivers配置中name进行匹配。需要注意的是route.routes下也可以有receiver配置,优先级高于route.receiver配置的默认接收人,当告警没有匹配到子路由时,会使用route.receiver进行通知,比如上述配置中的Default;
    Ø group_by:分组配置,值类型为列表。比如配置成['job', 'severity'],代表告警信息包含job和severity标签的会进行分组,且标签的key和value都相同才会被分到一组;
    Ø continue:决定匹配到第一个路由后,是否继续后续匹配。默认为false,即匹配到第一个子节点后停止继续匹配;
    Ø match:一对一匹配规则,比如match配置的为job: mysql,那么具有job=mysql的告警会进入该路由;
    Ø match_re:和match类似,只不过是match_re是正则匹配;
    Ø group_wait:告警通知等待,值类型为字符串。若一组新的告警产生,则会等group_wait后再发送通知,该功能主要用于当告警在很短时间内接连产生时,在group_wait内合并为单一的告警后再发送,防止告警过多,默认值30s;
    Ø group_interval:同一组告警通知后,如果有新的告警添加到该组中,再次发送告警通知的时间,默认值为5m;
    Ø repeat_interval:如果一条告警通知已成功发送,且在间隔repeat_interval后,该告警仍然未被设置为resolved,则会再次发送该告警通知,默认值4h。

    (三) Alertmanager邮件通知

    找到Alertmanager的配置文件:

    [root@k8s-master01 kube-prometheus]# cd manifests/
    [root@k8s-master01 manifests]# ls alertmanager-secret.yaml
    alertmanager-secret.yaml
    # cat alertmanager-secret.yaml 
    apiVersion: v1
    kind: Secret
    metadata:
      labels:
        alertmanager: main
        app.kubernetes.io/component: alert-router
        app.kubernetes.io/name: alertmanager
        app.kubernetes.io/part-of: kube-prometheus
        app.kubernetes.io/version: 0.21.0
      name: alertmanager-main
      namespace: monitoring
    stringData:
      alertmanager.yaml: |-
        "global":
          "resolve_timeout": "5m"
    ...
    

    之后在alertmanager-secret.yaml文件的global添加配置如下:

    alertmanager.yaml: |-
        "global":
          "resolve_timeout": "5m"
          smtp_from: "kubernetesxxx@163.com"
          smtp_smarthost: "smtp.163.com:465"
          smtp_hello: "163.com"
          smtp_auth_username: "kubernetesxxx@163.com"
          smtp_auth_password: "QJUYMWJXXX"
          smtp_require_tls: false
    

    之后将名称为Default的receiver配置更改为邮件通知,修改alertmanager-secret.yaml文件的receivers配置如下:

        "receivers":
        - "name": "Default"
          "email_configs":
          - to: "notification@163.com"
            send_resolved: true
        - "name": "Watchdog"
        - "name": "Critical"
    

    Ø email_configs:代表使用邮件通知;
    Ø to:收件人,此处为notification@163.com,可以配置多个,逗号隔开;
    Ø send_resolved:告警如果被解决是否发送解决通知。

    接下来分析一下路由规则(默认分组只有namespace,在此添加上job和alertname,当然不添加也是可以的):

        "route":
          "group_by":
          - "namespace"
          - "job"
          - "alertname"
          "group_interval": "5m"
          "group_wait": "30s"
          "receiver": "Default"
          "repeat_interval": "10m"
          "routes":
          - "match":
              "alertname": "Watchdog"
            "receiver": "Watchdog"
          - "match":
              "severity": "critical"
            "receiver": "Critical"
    

    可以通过Alertmanager提供的Web UI查看分组信息,和Prometheus一致,将Alertmanager的Service更改为NodePort:

    # kubectl edit svc -n monitoring alertmanager-main
    

    查看监听的端口号:

    # kubectl get svc -n monitoring alertmanager-main
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    alertmanager-main NodePort 192.168.92.94 <none> 9093:**30409**/TCP 10d
    

    将更改好的Alertmanager配置加载到Alertmanager:

    # kubectl replace -f alertmanager-secret.yaml
    secret/alertmanager-main replaced
    

    稍等几分钟即可在Alertmanager的Web界面看到更改的配置(Status):



    也可以查看分组信息:



    此时Default receiver配置的邮箱会收到两者的告警信息,如下所示:

    (四) Alertmanager企业微信通知

    https://work.weixin.qq.com/

    1.企业微信配置

    注册完成后进行登录,登录后点击我的企业:



    在页面的最下面找到企业ID(corp_id)并记录,稍后会用到:



    之后创建一个部门,用于接收告警通知:

    输入Prom告警,之后点击确定:



    之后在Prom告警子部门添加相关的人员即可,在此不再演示:

    查看该部门ID(to_party)并记录:

    之后创建机器人应用,首先点击应用管理à应用创建:

    选择一个logo,输入应用名称和选择可见范围即可:


    创建完成后,查看AgentId和Secret(api_secret)并记录:



    点击查看Secret,企业微信会将Secret发送至企业微信:

    点击查看并记录即可。

    2.Alertmanager配置

    修改Alertmanager配置文件,添加企业微信告警。首先修改Global,添加一些通用配置,wechat_api_url是固定配置,corp_id为企业ID:

        "global":
          "resolve_timeout": "5m"
         ...
          wechat_api_url: "https://qyapi.weixin.qq.com/cgi-bin/" 
          wechat_api_corp_id: "wef86a30xxxxxxxxxxxxx"
    

    Receivers添加微信通知:

        "receivers":
        - name: wechat-ops
          wechat_configs:
          - send_resolved: true
            to_party: 3
            to_user: '@all'
            agent_id: 1000006
            api_secret: "3bB350Sxxxxxxxxxxxxxxxxxxxxxxx"
        - "name": "Default"
          "email_configs": 
          - to: "xxxxx@163.com"
            send_resolved: true
    

    此处配置的receiver名字为wechat-ops,to_user为@all,代表发送给所有人,也可以只发送给部门的某一个人,只需要将此处改为USER_ID即可:



    更改路由配置,将Watchdog的告警发送给该部门:

        "route":
          "group_by":
          - "namespace"
          - "job"
          - "alertname"
          "group_interval": "5m"
          "group_wait": "30s"
          "receiver": "Default"
          "repeat_interval": "2h"
          "routes":
          - "match":
              "alertname": "Watchdog"
            "receiver": "wechat-ops"
            "repeat_interval": "10m"
        ...
    

    之后更新Alertmanager的配置:

    # kubectl replace -f alertmanager-secret.yaml
    secret/alertmanager-main replaced
    

    等待几分钟后,可以在Alertmanager Web UI看到新配置,并且企业微信可以收到Watchdog的告警:


    (五) 自定义告警模板

    首先修改alertmanager-secret.yaml添加自定义模板:

     app.kubernetes.io/part-of: kube-prometheus
    
     app.kubernetes.io/version: 0.21.0
    
     name: alertmanager-main
    
     namespace: monitoring
    
    stringData:
    
     **wechat.tmpl: |-**
    
     **{{ define "wechat.default.message" }}**
    
     **{{- if gt (len .Alerts.Firing) 0 -}}**
    
     **{{- range $index, $alert := .Alerts -}}**
    
     **{{- if eq $index 0 }}**
    
     **==========****异常告警==========**
    
    **告警类型: {{ $alert.Labels.alertname }}**
    
    **告警级别: {{ $alert.Labels.severity }}**
    
    **告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}};{{$alert.Annotations.summary}}**
    
    **故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}**
    
     **{{- if gt (len $alert.Labels.instance) 0 }}**
    
    **实例信息: {{ $alert.Labels.instance }}**
    
     **{{- end }}**
    
     **{{- if gt (len $alert.Labels.namespace) 0 }}**
    
    **命名空间: {{ $alert.Labels.namespace }}**
    
     **{{- end }}**
    
     **{{- if gt (len $alert.Labels.node) 0 }}**
    
    **节点信息: {{ $alert.Labels.node }}**
    
     **{{- end }}**
    
     **{{- if gt (len $alert.Labels.pod) 0 }}**
    
    **实例名称: {{ $alert.Labels.pod }}**
    
     **{{- end }}**
    
     **============END============**
    
     **{{- end }}**
    
     **{{- end }}**
    
     **{{- end }}**
    
     **{{- if gt (len .Alerts.Resolved) 0 -}}**
    
     **{{- range $index, $alert := .Alerts -}}**
    
     **{{- if eq $index 0 }}**
    
     **==========****异常恢复==========**
    
    **告警类型: {{ $alert.Labels.alertname }}**
    
    **告警级别: {{ $alert.Labels.severity }}**
    
    **告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}};{{$alert.Annotations.summary}}**
    
    **故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}**
    
    **恢复时间: {{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}**
    
     **{{- if gt (len $alert.Labels.instance) 0 }}**
    
    **实例信息: {{ $alert.Labels.instance }}**
    
     **{{- end }}**
    
     **{{- if gt (len $alert.Labels.namespace) 0 }}**
    
    **命名空间: {{ $alert.Labels.namespace }}**
    
     **{{- end }}**
    
     **{{- if gt (len $alert.Labels.node) 0 }}**
    
    **节点信息: {{ $alert.Labels.node }}**
    
     **{{- end }}**
    
     **{{- if gt (len $alert.Labels.pod) 0 }}**
    
    **实例名称: {{ $alert.Labels.pod }}**
    
     **{{- end }}**
    
     **============END============**
    
     **{{- end }}**
    
     **{{- end }}**
    
     **{{- end }}**
    
     **{{- end }}**
    
     alertmanager.yaml: |-
    
     "global":
    
     "resolve_timeout": "5m"
    

    在templates字段添加模板位置:

        templates:
        - '/etc/alertmanager/config/*.tmpl'
        "inhibit_rules":
    

    配置wechat-ops receiver使用该模板:

        "receivers":
        - name: wechat-ops
          wechat_configs:
          - send_resolved: true
            to_party: 3
            ...
            message: '{{ template "wechat.default.message" . }}'
    

    注意
    {{ template "wechat.default.message" . }}配置的wechat.default.message,是模板文件define定义的名称:{{ define "wechat.default.message" }},并非文件名称。

    将配置更新至Alertmanager:

    # kubectl replace -f alertmanager-secret.yaml
    secret/alertmanager-main replaced
    

    更新完成后,可以在Secret中查看该配置:

    # kubectl describe secret alertmanager-main -n monitoring
    Name: alertmanager-main
    Namespace: monitoring
    Labels: alertmanager=main
     app.kubernetes.io/component=alert-router
     app.kubernetes.io/name=alertmanager
     app.kubernetes.io/part-of=kube-prometheus
     app.kubernetes.io/version=0.21.0
    Annotations: <none>
    Type: Opaque
    Data
    ====
    alertmanager.yaml: 1438 bytes
    wechat.tmpl: 1823 bytes
    

    等待几分钟后,可以在alertmanager的Pod中看到该模板:

    # kubectl exec alertmanager-main-0 -n monitoring -c alertmanager -- ls /etc/alertmanager/config
    alertmanager.yaml
    wechat.tmpl
    

    之后再次收到告警,即为自定义告警模板:


    相关文章

      网友评论

        本文标题:十八 Alertmanager告警实战

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