自学内容网 自学内容网

Grafana系列之面板接入Prometheus Alertmanager

关于Grafana的仪表板Dashboard,以及面板Panel,参考Grafana系列之Dashboard。可以直接在面板上创建Alert,即所谓的Grafana Alert,参考Grafana系列之Grafana Alert。除了Grafana Alert外,面板也可接入Prometheus Alertmanager。

Alertmanager

关于Alertmanager的讲解,网上有很多不错的资料。

在这里插入图片描述

配置文件

alertmanager.yaml配置文件如下:

global:
  resolve_timeout: 10m # 10分钟内不再产生告警,则表示告警恢复
inhibit_rules:
- equal:
  - namespace
  - alertname
  source_matchers:
  - severity = critical
  target_matchers:
  - severity =~ warning|info
- equal:
  - namespace
  - alertname
  source_matchers:
  - severity = warning
  target_matchers:
  - severity = info
- equal:
  - namespace
  source_matchers:
  - alertname = InfoInhibitor
  target_matchers:
  - severity = info
- target_matchers:
  - alertname = InfoInhibitor
receivers:
- name: web.hook.promalert.feishu # 飞书群机器人告警通知
  webhook_configs:
  - url: http://prometheus-alert-center:8080/prometheusalert?type=fs&tpl=fs-tpl-pretty&fsurl=https://open.feishu.cn/open-apis/bot/v2/hook/9234ce69-1111-2222-96ce-f9136e47ac7&split=false # 不要试了,我已经篡改了
    send_resolved: false # 告警恢复后,不发送恢复通知
- name: 'web.hook.promalert.email' # 邮件告警通知
  webhook_configs:
  - url: 'http://prometheus-alert-center:8080/prometheusalert?type=email&tpl=email-tpl-pretty&email=aaa@tesla.com,bbb@tesla.com&split=false'
    send_resolved: false
- name: "null"
route:
  group_by:
  - namespace
  - instance
  - alertname
  - severity
  group_interval: 5m
  group_wait: 30s
  receiver: web.hook.promalert.feishu
  repeat_interval: 60m # 持续产生的告警,每隔1h才发送,避免告警轰炸,默认10m
  routes:
  - receiver: web.hook.promalert.feishu
  - matchers:
    - alertname = "Watchdog"
    receiver: "null"
templates:
- /etc/alertmanager/config/*.tmpl

配置中一般会包含以下几个主要部分:

  • 全局配置(global):用于定义一些全局的公共参数,如全局的SMTP配置,Slack配置等内容;
  • 模板(templates):用于定义告警通知时的模板,如HTML模板,邮件模板等;
  • 告警路由(route):根据标签匹配,确定当前告警应该如何处理;
  • 接收人(receivers):支持邮箱、微信、Slack、Webhook等,接收人一般配合告警路由使用;
  • 抑制规则(inhibit_rules):合理设置抑制规则可减少垃圾告警的产生

恢复通知

恢复通知到底要不要发送,不同的团队可采用不一样的实践。

这里给出一个绿色的恢复通知的样式:
在这里插入图片描述

分组

一个规则文件下可以配置若干个告警规则,规则文件也可以有若干个。比较好的做法是,关于节点的放在一个文件里,关于pod的放在一个文件里,业务告警规则放在另一个文件里,最后的效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实战

新增一个alert.yaml文件如下:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  labels:
    # labels与Prometheus CRD中match ruleSelector -> matchLabels保持一致。
    release: kube-prom-stack
  name: tesla
spec:
  groups:
  - name: tesla
    rules:
      - alert: "tesla登录耗时大于6s"
        expr: 'round(rate(tesla_login_seconds_sum[1m])/rate(tesla_login_seconds_count[1m]), 0.01) > 6'
        for: 0s
        labels:
          severity: critical
        annotations:
          summary: tesla登录耗时大于6s
          description: "tesla登录耗时大于6s<br> 实际耗时: {{ $value }}s<br> <a href=\"http://grafana.test.tesla.com:8800/d/ce83e684dcqv4c/tesla登录?from=now-5m&to=now&timezone=browser&var-appId={{ $labels.appId }}&var-tenantId={{ $labels.tenantId }}\">查看详情</a>"

      - alert: "接口异常"
        expr: 'round(rate(http_server_requests_seconds_count{status=~"4..|5.."}[1m]), 0.01) > 0'
        for: 0s
        labels:
          severity: critical
        annotations:
          summary: 接口异常
          description: "接口异常<br> 应用: {{ $labels.job }}<br> 方法: {{ $labels.method }}<br> 状态码: {{ $labels.status }}<br> 接口: {{ $labels.uri }}<br> 报错: {{ $labels.exception }}<br> <a href=\"http://grafana.test.tesla.com:8800/d/ee990bqfj9nuoe/api?from=now-1h&to=now&var-job={{ $labels.job }}&var-uri={{ $labels.uri }}&var-status={{ $labels.status }}\">查看详情</a>"

然后执行命令:kubectl apply -f alert.yaml -o observe,或kc apply -f alert.yaml -o observe,kc是kubecolor的缩写。

来到Prometheus Alert页面,会发现新增的告警规则
在这里插入图片描述
Prometheus告警有一个独立的模块,Alertmanager,告警效果如下
在这里插入图片描述
上面直接给出最后的实现效果。

round

分析上面的告警配置,不难发现规则配置的核心自然就是expr表达式。

一开始并没有使用round函数,rate(tesla_login_seconds_sum[1m])/rate(tesla_login_seconds_count[1m]) > 6,给出的告警是这样的:
在这里插入图片描述
小数点后位数太多,不友好。

description里的这个数据对应于{{ $value }},取自于expr表达式的比较操作符的前面那部分。description里不能用round等PromQL函数,于是对expr统一增加round函数。

踩坑:对所有的expr表达式统一加round函数。

round函数不带小数点,也就是没有写成round(0.1)round(0.01)的两个问题:

  • 对API接口的4xx或5xx异常监控:expr表达式为round(rate(http_server_requests_seconds_count{status=~"4..|5.."}[1m])) > 0,意思是过去1分钟内平均值。试想一下,过去1分钟有1次接口异常,rate(http_server_requests_seconds_count{status=~"4..|5.."}[1m])结果是什么?好好想一想,或者去Grafana页面验证一下。正确的结果是1/60=0.0166667,这个数据使用round取整,肯定不满足大于0,也就是说本应该告警的事件,发生漏保。
  • 四舍五入并不精准:比如说某个登录请求耗时是6.2秒,经过round函数处理后,自然变成6。6.2 > 6自然成立,round(6.2) > 6则不成立;本应该告警的事件,因为round使用不当,告警漏报。

如下图,指标数是0.0166667的2倍,过去1分钟发生2次。
在这里插入图片描述
结论:统一调整优化round语法为取两位小数点,也就是一开始给出的规则配置文件。

跳转链接

告警成功发出后,在告警内容里增加该Prometheus Alert对应的Grafana面板链接,这一点很容易想到。

主要说四点:

  • 换行符:兼容邮件和markdown,换行符是<br>,而不是\n
  • 跳转链接:markdown语法[some-url](some-url)支持有限(自己不会),改为使用href方式;
  • 转义字符:description本身是双引号,在里面使用href标签,需要对href标签引入的双引号加以转义处理,否则执行kc apply -f alert.yaml命令失败,报错如下面截图所示。值得一提的是,如果对k8s(的yaml)不熟,死死盯着报错提示的第18行,就会陷入死胡同。kubectl执行yaml文件时,会忽略yaml文件里的注释行;真实的配置错误行,并不是报错提示的那一行。
    在这里插入图片描述
  • 变量定位:配置的跳转地址写成 http://grafana.test.tesla.com:8800/d/ee990bqfj9nuoe/api,当然没有问题。既然是API接口异常,并且Grafana面板里配置有变量,能不能直接跳转到触发告警的异常API呢?当然可以,{{ $labels.job }}即可从标签组里获取到具体的某个标签。写法:http://grafana.test.tesla.com:8800/d/ee990bqfj9nuoe/api?from=now-1h&to=now&var-job={{ $labels.job }}&var-uri={{ $labels.uri }}&var-status={{ $labels.status }}

Markdown

Prometheus Alert提供对Markdown语法的支持,不过需要测试和配置。
在这里插入图片描述
有待进一步学习

模板配置

告警方式有很多,本文暂且只考虑和配置飞书、邮件。不管什么样的通知方式,告警内容都是其中非常核心的一环(也就是上面的配置文件中的templates模块)。

当同时接入邮件、飞书、企业微信、阿里云短信,同一套告警内容如何同时适配多个不同的接收终端?

借助于开源项目(https://github.com/feiyu563/PrometheusAlert),可一定程度上解决上面提出的问题。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
飞书的告警模板:
在这里插入图片描述
可供参考的飞书模板:

{{ $var := .externalURL}}{{range $k,$v:=.alerts}}
{{if eq $v.status "resolved"}}
生产环境(GPU)告警恢复通知
🟡【告警名称】{{$v.labels.alertname}}
🚨【告警级别】{{$v.labels.severity}}
✅【告警状态】{{$v.status}}
🧭【开始时间】{{GetCSTtime $v.startsAt}}
🧭【结束时间】{{GetCSTtime $v.endsAt}}
📝【告警详情】{{$v.annotations.description}}
{{else}}
非生产环境(GPU)告警通知
🟡【告警名称】{{$v.labels.alertname}}
🚨【告警级别】{{$v.labels.severity}}
🔥【告警状态】{{$v.status}}
🧭【开始时间】{{GetCSTtime $v.startsAt}}
📝【告警详情】{{$v.annotations.description}}
{{end}}
{{end}}
{{ $urimsg:=""}}{{range $key,$value:=.commonLabels}}{{$urimsg = print $urimsg $key "%3D%22" $value "%22%2C"}}{{end}}[👉 点我屏蔽该告警 👈](http://alert.test.tesla.com/#/silences/new?filter=%7B{{SplitString $urimsg 0 -3}}%7D)

可供参考的邮件模板:

{{if eq .state "ok"}}
<h1><a href ={{.ruleUrl}}>Grafana恢复信息</a></h1>
<h2>{{.ruleName}}</h2>
<h5>告警级别:严重</h5>
<h5>开始时间:{{GetCSTtime ""}}</h5>
<h3>{{.message}}</h3>
{{else}}
<h1><a href ={{.ruleUrl}}>Grafana恢复信息</a></h1>
<h2>{{.ruleName}}</h2>
<h5>告警级别:严重</h5>
<h5>开始时间:{{GetCSTtime ""}}</h5>
<h3>{{.message}}</h3>
{{end}}
<img src=https://raw.githubusercontent.com/feiyu563/PrometheusAlert/master/doc/alert-center.png />

参考


原文地址:https://blog.csdn.net/lonelymanontheway/article/details/145247509

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!