https://github.com/prometheus/alertmanager#install

二进制部署

  1. ./alertmanager --config.file=config.yml

k8s部署

alertmanager.yml配置文件格式:

  1. $ cat alertmanager-config.yml
  2. apiVersion: v1
  3. kind: ConfigMap
  4. metadata:
  5. name: alertmanager
  6. namespace: monitor
  7. data:
  8. config.yml: |
  9. global:
  10. # 当alertmanager持续多长时间未接收到告警后标记告警状态为 resolved
  11. resolve_timeout: 5m
  12. # 配置邮件发送信息
  13. smtp_smarthost: 'smtp.163.com:25'
  14. smtp_from: '123321163@163.com'
  15. smtp_auth_username: '123321163@163.com'
  16. smtp_auth_password: 'qzpm10'
  17. smtp_require_tls: false
  18. # 所有报警信息进入后的根路由,用来设置报警的分发策略
  19. route:
  20. # 接收到的报警信息里面有许多alertname=NodeLoadHigh 这样的标签的报警信息将会批量被聚合到一个分组里面
  21. group_by: ['alertname']
  22. # 当一个新的报警分组被创建后,需要等待至少 group_wait 时间来初始化通知,如果在等待时间内当前group接收到了新的告警,这些告警将会合并为一个通知向receiver发送
  23. group_wait: 30s
  24. # 相同的group发送告警通知的时间间隔
  25. group_interval: 30s
  26. # 如果一个报警信息已经发送成功了,等待 repeat_interval 时间来重新发送
  27. repeat_interval: 10m
  28. # 默认的receiver:如果一个报警没有被一个route匹配,则发送给默认的接收器
  29. receiver: default
  30. # 上面所有的属性都由所有子路由继承,并且可以在每个子路由上进行覆盖。
  31. routes:
  32. - {}
  33. # 配置告警接收者的信息
  34. receivers:
  35. - name: 'default'
  36. email_configs:
  37. - to: '123456789@qq.com'
  38. send_resolved: true # 接受告警恢复的通知

主要配置的作用:

  • global: 全局配置,包括报警解决后的超时时间、SMTP 相关配置、各种渠道通知的 API 地址等等。
  • route: 用来设置报警的分发策略,它是一个树状结构,按照深度优先从左向右的顺序进行匹配。
  • receivers: 配置告警消息接受者信息,例如常用的 email、wechat、slack、webhook 等消息通知方式。

配置文件:

  1. $ kubectl create -f alertmanager-config.yml

其他资源清单文件:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: alertmanager
  5. namespace: monitor
  6. labels:
  7. app: alertmanager
  8. spec:
  9. selector:
  10. matchLabels:
  11. app: alertmanager
  12. template:
  13. metadata:
  14. labels:
  15. app: alertmanager
  16. spec:
  17. volumes:
  18. - name: config
  19. configMap:
  20. name: alertmanager
  21. containers:
  22. - name: alertmanager
  23. image: prom/alertmanager:v0.21.0
  24. imagePullPolicy: IfNotPresent
  25. args:
  26. - "--config.file=/etc/alertmanager/config.yml"
  27. - "--log.level=debug"
  28. ports:
  29. - containerPort: 9093
  30. name: http
  31. volumeMounts:
  32. - mountPath: "/etc/alertmanager"
  33. name: config
  34. resources:
  35. requests:
  36. cpu: 100m
  37. memory: 256Mi
  38. limits:
  39. cpu: 100m
  40. memory: 256Mi
  41. ---
  42. apiVersion: v1
  43. kind: Service
  44. metadata:
  45. name: alertmanager
  46. namespace: monitor
  47. spec:
  48. type: ClusterIP
  49. ports:
  50. - port: 9093
  51. selector:
  52. app: alertmanager
  53. ---
  54. apiVersion: extensions/v1beta1
  55. kind: Ingress
  56. metadata:
  57. name: alertmanager
  58. namespace: monitor
  59. spec:
  60. rules:
  61. - host: alertmanager.luffy.com
  62. http:
  63. paths:
  64. - path: /
  65. backend:
  66. serviceName: alertmanager
  67. servicePort: 9093

配置Prometheus与Alertmanager对话

Alertmanager - 图1
是否告警是由Prometheus进行判断的,若有告警产生,Prometheus会将告警push到Alertmanager,因此,需要在Prometheus端配置alertmanager的地址:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: prometheus-config
  5. namespace: monitor
  6. data:
  7. prometheus.yml: |
  8. global:
  9. scrape_interval: 30s
  10. evaluation_interval: 30s
  11. alerting:
  12. alertmanagers:
  13. - static_configs:
  14. - targets:
  15. - alertmanager:9093
  16. ...

更新configmap

  1. $ kubectl apply -f prometheus-configmap.yaml

现在已经有监控数据了,因此使用prometheus提供的reload的接口,进行服务重启
# 查看配置文件是否已经自动加载到pod中

  1. $ kubectl -n monitor get po -o wide
  2. prometheus-dcb499cbf-pljfn 1/1 Running 0 47h 10.244.1.167
  3. $ kubectl -n monitor exec -ti prometheus-dcb499cbf-pljfn cat /etc/prometheus/prometheus.yml |grep alertmanager
  4. # 使用软加载的方式,
  5. $ curl -X POST 10.244.1.167:9090/-/reload

配置报警规则

目前Prometheus与Alertmanager已经连通,接下来我们可以针对收集到的各类指标配置报警规则,一旦满足报警规则的设置,则Prometheus将报警信息推送给Alertmanager,进而转发到我们配置的邮件中。
在哪里配置?同样是在prometheus-configmap中:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: prometheus-config
  5. namespace: monitor
  6. data:
  7. prometheus.yml: |
  8. global:
  9. scrape_interval: 30s
  10. evaluation_interval: 30s
  11. alerting:
  12. alertmanagers:
  13. - static_configs:
  14. - targets:
  15. - alertmanager:9093
  16. # Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
  17. rule_files:
  18. - /etc/prometheus/alert_rules.yml
  19. # - "first_rules.yml"
  20. # - "second_rules.yml"
  21. scrape_configs:
  22. - job_name: 'prometheus'
  23. static_configs:
  24. - targets: ['localhost:9090']
  25. ...

rules.yml我们同样使用configmap的方式挂载到prometheus容器内部,因此只需要在已有的configmap中加一个数据项目

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: prometheus-config
  5. namespace: monitor
  6. data:
  7. prometheus.yml: |
  8. global:
  9. scrape_interval: 30s
  10. evaluation_interval: 30s
  11. alerting:
  12. alertmanagers:
  13. - static_configs:
  14. - targets:
  15. - alertmanager:9093
  16. # Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
  17. rule_files:
  18. - /etc/prometheus/alert_rules.yml
  19. # - "first_rules.yml"
  20. # - "second_rules.yml"
  21. scrape_configs:
  22. - job_name: 'prometheus'
  23. static_configs:
  24. - targets: ['localhost:9090']
  25. ... # 省略中间部分
  26. alert_rules.yml: |
  27. groups:
  28. - name: node_metrics
  29. rules:
  30. - alert: NodeLoad
  31. expr: node_load15 < 1
  32. for: 2m
  33. annotations:
  34. summary: "{{$labels.instance}}: Low node load detected"
  35. description: "{{$labels.instance}}: node load is below 1 (current value is: {{ $value }}"

告警规则的几个要素:

  • group.name:告警分组的名称,一个组下可以配置一类告警规则,比如都是物理节点相关的告警
  • alert:告警规则的名称
  • expr:是用于进行报警规则 PromQL 查询语句,expr通常是布尔表达式,可以让Prometheus根据计算的指标值做 true or false 的判断
  • for:评估等待时间(Pending Duration),用于表示只有当触发条件持续一段时间后才发送告警,在等待期间新产生的告警状态为pending,屏蔽掉瞬时的问题,把焦点放在真正有持续影响的问题上
  • labels:自定义标签,允许用户指定额外的标签列表,把它们附加在告警上,可以用于后面做路由判断,通知到不同的终端,通常被用于添加告警级别的标签
  • annotations:指定了另一组标签,它们不被当做告警实例的身份标识,它们经常用于存储一些额外的信息,用于报警信息的展示之类的

规则配置中,支持模板的方式,其中:

  • {{$labels}}可以获取当前指标的所有标签,支持{{$labels.instance}}或者{{$labels.job}}这种形式
  • {{ $value }}可以获取当前计算出的指标值

更新配置并软重启,并查看Prometheus报警规则。
一个报警信息在生命周期内有下面3种状态:

  • inactive: 表示当前报警信息处于非活动状态,即不满足报警条件
  • pending: 表示在设置的阈值时间范围内被激活了,即满足报警条件,但是还在观察期内
  • firing: 表示超过设置的阈值时间被激活了,即满足报警条件,且报警触发时间超过了观察期,会发送到Alertmanager端

对于已经 pending 或者 firing 的告警,Prometheus 也会将它们存储到时间序列ALERTS{}中。当然我们也可以通过表达式去查询告警实例:
ALERTS{}
image.png
image.png
查看Alertmanager日志:
level=warn ts=2020-07-28T13:43:59.430Z caller=notify.go:674 component=dispatcher receiver=email integration=email[0] msg=”Notify attempt failed, will retry later” attempts=1 err=”*email.loginAuth auth: 550 User has no permission”
说明告警已经推送到Alertmanager端了,但是邮箱登录的时候报错,这是因为邮箱默认没有开启第三方客户端登录。因此需要登录163邮箱设置SMTP服务允许客户端登录。

自定义企业微信实现告警消息的推送

其他Label的动态告警处理,添加了gkwr: restart 键值对,用于匹配告警路由

  1. alert_rules.yml: |
  2. groups:
  3. - name: node_metrics
  4. rules:
  5. - alert: PodRestart
  6. expr: changes(kube_pod_container_status_restarts_total[30m])>0 #最近30分钟pod重启
  7. for: 3s
  8. labels:
  9. gkwr: restart
  10. annotations:
  11. summary: 'Container: {{ $labels.container }} pod重启'
  12. description: 'namespace: {{ $labels.namespace }}, pod: {{ $labels.pod }} restart {{ $value }} times'

添加告警路由

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: alertmanager
  5. namespace: monitor
  6. data:
  7. config.yml: |
  8. global:
  9. # 当alertmanager持续多长时间未接收到告警后标记告警状态为 resolved
  10. resolve_timeout: 5m
  11. # 配置邮件发送信息
  12. smtp_smarthost: 'smtp.qq.com:25'
  13. smtp_from: '1234464@qq.com'
  14. smtp_auth_username: '1234557@qq.com'
  15. smtp_auth_password: '123456'
  16. smtp_require_tls: false
  17. #告警模板
  18. templates:
  19. - '/etc/alertmanager/wechat.tmpl'
  20. # 所有报警信息进入后的根路由,用来设置报警的分发策略
  21. route:
  22. # 接收到的报警信息里面有许多alertname=NodeLoadHigh 这样的标签的报警信息将会批量被聚合到一个分组里面
  23. group_by: ['alertname']
  24. group_wait: 30s
  25. # 相同的group发送告警通知的时间间隔
  26. group_interval: 30s
  27. # 如果一个报警信息已经发送成功了,等待 repeat_interval 时间来重新发送
  28. repeat_interval: 10m
  29. # 默认的receiver:如果一个报警没有被一个route匹配,则发送给默认的接收器
  30. receiver: default
  31. # 上面所有的属性都由所有子路由继承,并且可以在每个子路由上进行覆盖。
  32. routes:
  33. - receiver: wechat
  34. group_wait: 2s
  35. match:
  36. gkwr: restart
  37. # 配置告警接收者的信息
  38. #邮件告警
  39. receivers:
  40. - name: 'default'
  41. email_configs:
  42. - to: '123456@qq.com'
  43. send_resolved: true # 接受告警恢复的通知
  44. #企业微信告警
  45. - name: 'wechat'
  46. wechat_configs:
  47. - corp_id: 'ww11111111111da'
  48. agent_id: '1000000'
  49. api_secret: 'Kn123142345235235235234_pBa-chNVk-u4'
  50. to_user: 'OuBa'
  51. send_resolved: true

添加告警模版

还是通过configmap挂载到Alertmanager中

  1. ...
  2. wechat.tmpl: |
  3. {{ define "wechat.default.message" }}
  4. {{- if gt (len .Alerts.Firing) 0 -}}
  5. {{- range $index, $alert := .Alerts -}}
  6. ======== 异常告警 ========
  7. 告警名称:{{ $alert.Labels.alertname }}
  8. 告警级别:{{ $alert.Labels.severity }}
  9. 故障命名空间:{{ $alert.Labels.namespace }}
  10. 故障POD名: {{ $alert.Labels.pod}}
  11. 告警详情:{{ $alert.Annotations.summary }}
  12. 告警时间:{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
  13. ========== END ==========
  14. {{- end }}
  15. {{- end }}
  16. {{- if gt (len .Alerts.Resolved) 0 -}}
  17. {{- range $index, $alert := .Alerts -}}
  18. ======== 告警恢复 ========
  19. 告警名称:{{ $alert.Labels.alertname }}
  20. 告警级别:{{ $alert.Labels.severity }}
  21. 故障命名空间:{{ $alert.Labels.namespace }}
  22. 故障POD名: {{ $alert.Labels.pod}}
  23. 告警详情:{{ $alert.Annotations.summary }}
  24. 告警时间:{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
  25. 恢复时间:{{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
  26. ========== END ==========
  27. {{- end }}
  28. {{- end }}
  29. {{- end }}

重新加载alertmanager-config.yml 重启alertmanager pod

  1. kubectl apply -f alertmanager-config.yml
  2. kubectl exec alertmanager-796996c79f-f9w2g -n monitor kill 1

在alertmeanager 网页上可以看到

image.png

企业微信收到告警

image.png

配置钉钉机器人消息推送

添加钉钉机器人

image.png
测试消息推送

  1. curl -X POST "Webhook" -H 'Content-Type:application/json' -d '{"msgtype" : "text", "text": {"content": "1"}}'

image.png
image.png

安装webhook-dingtalk

安装并配置webhook-dingtalk

  1. wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v2.1.0/prometheus-webhook-dingtalk-2.1.0.linux-amd64.tar.gz
  2. tar -xf prometheus-webhook-dingtalk-2.1.0.linux-amd64.tar.gz
  3. mv prometheus-webhook-dingtalk-2.1.0.linux-amd64 /data/dingtalk/
  4. cd /data/dingtalk/
  5. cp config.example.yml config.yml
  6. vim config.yml
  7. ...
  8. targets:
  9. webhook1:
  10. url: # 此处填写钉钉webhook
  11. ...
  12. # 编写systemctl控制配置文件
  13. vim /etc/systemd/system/prometheus-webhook-dingtalk.service
  14. [Unit]
  15. Description=prometheus-webhook-dingtalk
  16. After=network-online.target
  17. [Service]
  18. Restart=on-failure
  19. ExecStart=/data/dingtalk/prometheus-webhook-dingtalk --config.file=/data/dingtalk/config.yml
  20. [Install]
  21. WantedBy=multi-user.target
  22. systemctl daemon-reload
  23. systemctl start prometheus-webhook-dingtalk.service
  24. systemctl enable prometheus-webhook-dingtalk.service

配置alermanager

  1. vim /data/alertmanager/alertmanager.yml
  2. route:
  3. group_by: ['alertname']
  4. group_wait: 10s
  5. group_interval: 30s
  6. repeat_interval: 30m
  7. receiver: xc_online
  8. routes:
  9. - match:
  10. alertname: XCOnline
  11. receiver: xc_online
  12. receivers:
  13. - name: 'xc_online'
  14. webhook_configs:
  15. - url: 'http://localhost:8060/dingtalk/webhook1/send' # 填写webhook-dingtalk生成的url
  16. inhibit_rules:
  17. - source_match:
  18. severity: 'critical'
  19. target_match:
  20. severity: 'warning'
  21. equal: ['alertname', 'dev', 'instance']
  22. systemctl restart alertmanager

检查报警

image.pngimage.png

抑制和静默

前面我们知道,告警的group(分组)功能通过把多条告警数据聚合,有效的减少告警的频繁发送。除此之外,Alertmanager还支持Inhibition(抑制) 和 Silences(静默),帮助我们抑制或者屏蔽报警。

Inhibition 抑制

抑制是当出现其它告警的时候压制当前告警的通知,可以有效的防止告警风暴。
比如当机房出现网络故障时,所有服务都将不可用而产生大量服务不可用告警,但这些警告并不能反映真实问题在哪,真正需要发出的应该是网络故障告警。当出现网络故障告警的时候,应当抑制服务不可用告警的通知。
在Alertmanager配置文件中,使用inhibit_rules定义一组告警的抑制规则:

  1. inhibit_rules:
  2. [ - <inhibit_rule> ... ]

每一条抑制规则的具体配置如下:

  1. target_match:
  2. [ <labelname>: <labelvalue>, ... ]
  3. target_match_re:
  4. [ <labelname>: <regex>, ... ]
  5. source_match:
  6. [ <labelname>: <labelvalue>, ... ]
  7. source_match_re:
  8. [ <labelname>: <regex>, ... ]
  9. [ equal: '[' <labelname>, ... ']' ]

当已经发送的告警通知匹配到target_match或者target_match_re规则,当有新的告警规则如果满足source_match或者定义的匹配规则,并且已发送的告警与新产生的告警中equal定义的标签完全相同,则启动抑制机制,新的告警不会发送。
例如,定义如下抑制规则:

  1. - source_match:
  2. alertname: NodeDown
  3. severity: critical
  4. target_match:
  5. severity: critical
  6. equal:
  7. - node
  1. 如当集群中的某一个主机节点异常宕机导致告警NodeDown被触发,同时在告警规则中定义了告警级别severity=critical。由于主机异常宕机,该主机上部署的所有服务,中间件会不可用并触发报警。根据抑制规则的定义,如果有新的告警级别为severity=critical,并且告警中标签node的值与NodeDown告警的相同,则说明新的告警是由NodeDown导致的,则启动抑制机制停止向接收器发送通知。<br />演示:实现如果 NodeMemoryUsage 报警触发,则抑制NodeLoad指标规则引起的报警。
  1. inhibit_rules:
  2. - source_match:
  3. alertname: NodeMemoryUsage
  4. severity: critical
  5. target_match:
  6. severity: normal
  7. equal:
  8. - instance

Silences: 静默

  1. 简单直接的在指定时段关闭告警。静默通过匹配器(Matcher)来配置,类似于路由树。警告进入系统的时候会检查它是否匹配某条静默规则,如果是则该警告的通知将忽略。 静默规则在Alertmanager Web 界面里配置。<br /> 一条告警产生后,还要经过 Alertmanager 的分组、抑制处理、静默处理、去重处理和降噪处理最后再发送给接收者。这个过程中可能会因为各种原因会导致告警产生了却最终没有进行通知,可以通过下图了解整个告警的生命周期:<br />[https://github.com/liyongxin/prometheus-webhook-wechat](https://github.com/liyongxin/prometheus-webhook-wechat)<br />[<br />](https://github.com/liyongxin/prometheus-webhook-wechat)