Prometheus学习笔记五-钉钉加签报警

钉钉加签报警示例
首先需要的是自定义机器人唯一的 webhook,可以通过电脑端的钉钉申请,申请完成后记录下该机器人的 webhook。如图:
在这里插入图片描述
点击添加机器人,选择 “自定义机器人”
在这里插入图片描述
在这里插入图片描述
自定义功能名称:
在这里插入图片描述
完成必要的安全设置(至少选择一种),重置我已阅读并同意《自定义机器人服务及免责条款》,单击“完成”。安全设置目前有 3 种方式,设置说明见介绍。
在这里插入图片描述
完成安全设置后,复制出机器人的 Webhook 地址,可用于向这个群发送消息,格式如下:

https://oapi.dingtalk.com/robot/send?access_token=XXXXXX

注意:请保管好此 Webhook 地址,不要公布在外部网站上,避免后有安全风险。

安全设置
安全设置目前有 3 种方式:

方式一,自定义关键词
最多可以设置 10 个关键字,消息中至少包含其中 1 个关键字才可以发送成功。

例如:添加了一个自定义关键字:监控报警

则这个机器人所发送的消息,必须包含监控报警 这个词,才能发送成功。

方式二,加签
首先,把 timestamp +“ \ n” + 密钥当做签名密钥,使用 HmacSHA256 算法计算签名,然后进行 Base64 编码,最后再把签名参数再进行 urlEncode,得到最终的签名(需要使用 UTF-8 字符集)。
在这里插入图片描述
签名计算代码示例(Java)

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import java.net.URLEncoder;

public class Test {
    
    
    public static void main(String[] args) throws Exception {
    
    
        Long timestamp = System.currentTimeMillis();
        String secret = "this is secret替换为密钥";

        String stringToSign = timestamp + "\n" + secret;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
        String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)),"UTF-8");
        System.out.println(sign);
    }

}

签名计算代码示例(Python)

#python 3.8 
import time
import hmac
import hashlib
import base64
import urllib.parse

timestamp = str(round(time.time() * 1000))
secret = 'this is secret'
secret_enc = secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
print(timestamp)
print(sign)
#python 2.7
import time
import hmac
import hashlib
import base64
import urllib

timestamp = long(round(time.time() * 1000))
secret = 'this is secret'
secret_enc = bytes(secret).encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, secret)
string_to_sign_enc = bytes(string_to_sign).encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.quote_plus(base64.b64encode(hmac_code))
print(timestamp)
print(sign)

第二步,把 timestamp 和第一步得到的签名值分割到 URL 中。
在这里插入图片描述

https://oapi.dingtalk.com/robot/send?access_token=XXXXXX×&tamp=XXX&sign=XXX

方式三,IP 地址(段)
设定后,只有来自 IP 地址范围内的请求才会被正常处理。支持两种设置方式:IP,IP 段,暂不支持 IPv6 的地址白名单,格式如下:
在这里插入图片描述
注意:安全设置的上述三种方式,需要至少设置其中一种,以进行安全保护。校正不通过的消息将会发送失败,错误如下:

1 //消息内容中不包含任何关键词
 2 {
    
    
 3   “ERRCODE”:310000,
 4   “ERRMSG”: “关键字不是在内容”
 5 }
 6 
7 //时间戳无效
 8 {
    
    
 9   “ERRCODE”:310000,
 10   “ ERRMSG “:”无效时间戳“
 11 }
 12 
13 //签名不匹配
 14 {
    
    
 15   ”ERRCODE“:310000,
 16   ”ERRMSG“: ”符号不匹配“
 17 }
 18 
19 // IP地址不在白名单
 20 {
    
    
 21   ” ERRCODE“:310000,
 22  “ errmsg”:“ ip XXXX不在白名单中”
 23 }

python加签命令行测试

扫描二维码关注公众号,回复: 11884020 查看本文章
#钉钉收到消息即发送成功!
curl 'https://oapi.dingtalk.com/robot/send?access_token=XXXXXX&timestamp=XXXXXX&sign=XXXXXX' -H 'Content-Type: application/json' -d '{"msgtype": "text","text": {"content": " 我就是我, 不一样的烟火"}}'

使用docker运行

$ docker run -p 5000:5000 --name -e ROBOT_TOKEN=<钉钉机器人TOKEN> -e ROBOT_SECRET=<钉钉机器人安全SECRET> -e LOG_LEVEL=debug -e PROME_URL=prometheus.local dingtalk-hook -d cnych/alertmanager-dingtalk-hook:v0.3.5

环境变量配置:

ROBOT_TOKEN:钉钉机器人 TOKEN PROME_URL:手动指定跳转后的 Promethues 地址,默认会是 Pod 的地址
LOG_LEVEL:日志级别,设置成 debug 可以看到 AlertManager WebHook
发送的数据,方便调试使用,不需调试可以不设置该环境变量
ROBOT_SECRET:为钉钉机器人的安全设置密钥,机器人安全设置页面,加签一栏下面显示的 SEC 开头的字符串

在Kubernetes集群中运行
第一步建议将钉钉机器人TOKEN创建成Secret资源对象:

$ kubectl create secret generic dingtalk-secret --from-literal=token=<钉钉群聊的机器人TOKEN> --from-literal=secret=<钉钉群聊机器人的SECRET> -n kube-ops
secret "dingtalk-secret" created

然后定义Deployment和Service资源对象:(dingtalk-hook.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dingtalk-hook
  namespace: kube-ops
spec:
  selector:
    matchLabels:
      app: dingtalk-hook
  template:
    metadata:
      labels:
        app: dingtalk-hook
    spec:
      containers:
      - name: dingtalk-hook
        image: cnych/alertmanager-dingtalk-hook:v0.3.6
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5000
          name: http
        env:
        - name: PROME_URL
          value: prometheus.local
        - name: LOG_LEVEL
          value: debug
        - name: ROBOT_TOKEN
          valueFrom:
            secretKeyRef:
              name: dingtalk-secret
              key: token
        - name: ROBOT_SECRET
          valueFrom:
            secretKeyRef:
              name: dingtalk-secret
              key: secret
        resources:
          requests:
            cpu: 50m
            memory: 100Mi
          limits:
            cpu: 50m
            memory: 100Mi

---
apiVersion: v1
kind: Service
metadata:
  name: dingtalk-hook
  namespace: kube-ops
spec:
  selector:
    app: dingtalk-hook
  ports:
  - name: hook
    port: 5000
    targetPort: http

直接创建上面的资源对象即可:

$ kubectl create -f dingtalk-hook.yaml
deployment.apps "dingtalk-hook" created
service "dingtalk-hook" created
$ kubectl get pods -n kube-ops
NAME                            READY     STATUS      RESTARTS   AGE
dingtalk-hook-c4fcd8cd6-6r2b6   1/1       Running     0          45m
......

最后在AlertManager中 webhook 地址直接通过 DNS 形式访问即可:

receivers:
- name: 'webhook'
  webhook_configs:
  - url: 'http://dingtalk-hook.kube-ops.svc.cluster.local:5000'
    send_resolved: true

Alertmanager报警模板详解
默认情况下Alertmanager使用了系统自带的默认通知模板,模板源码可以从https://github.com/prometheus/alertmanager/blob/master/template/default.tmpl获得。
Alertmanager的通知模板基于Go的模板系统。Alertmanager也支持用户定义和使用自己的模板,一般来说有两种方式可以选择。
**第一种,基于模板字符串。**用户可以直接在Alertmanager的配置文件中使用模板字符串,例如:

receivers:
- name: 'slack-notifications'
  slack_configs:
  - channel: '#alerts'
    text: 'https://internal.myorg.net/wiki/alerts/{
    
    { .GroupLabels.app }}/{
    
    { .GroupLabels.alertname }}'

**第二种方式,自定义可复用的模板文件。**例如,可以创建自定义模板文件custom-template.tmpl,如下所示:

{
    
    {
    
     define "slack.myorg.text" }}https://internal.myorg.net/wiki/alerts/{
    
    {
    
     .GroupLabels.app }}/{
    
    {
    
     .GroupLabels.alertname }}{
    
    {
    
     end}}

通过在Alertmanager的全局设置中定义templates配置来指定自定义模板的访问路径:

# Files from which custom notification template definitions are read.
# The last component may use a wildcard matcher, e.g. 'templates/*.tmpl'.
templates:
  [ - <filepath> ... ]

在设置了自定义模板的访问路径后,用户则可以直接在配置中使用该模板:

receivers:
- name: 'slack-notifications'
  slack_configs:
  - channel: '#alerts'
    text: '{
    
    { template "slack.myorg.text" . }}'

templates:
- '/etc/alertmanager/templates/myorg.tmpl'

Alertmanager抑制及优化
Alertmanager提供了方式可以帮助用户控制告警通知的行为,包括预先定义的抑制机制和临时定义的静默规则。
抑制机制
Alertmanager的抑制机制可以避免当某种问题告警产生之后用户接收到大量由此问题导致的一系列的其它告警通知。例如当集群不可用时,用户可能只希望接收到一条告警,告诉他这时候集群出现了问题,而不是大量的如集群中的应用异常、中间件服务异常的告警通知。
在Alertmanager配置文件中,使用inhibit_rules定义一组告警的抑制规则

inhibit_rules:
  [ - <inhibit_rule> ... ]

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

target_match:
  [ <labelname>: <labelvalue>, ... ]
target_match_re:
  [ <labelname>: <regex>, ... ]

source_match:
  [ <labelname>: <labelvalue>, ... ]
source_match_re:
  [ <labelname>: <regex>, ... ]

[ equal: '[' <labelname>, ... ']' ]

当已经发送的告警通知匹配到target_match和target_match_re规则,当有新的告警规则如果满足source_match或者定义的匹配规则,并且已发送的告警与新产生的告警中equal定义的标签完全相同,则启动抑制机制,新的告警不会发送。PS:简单明了的意思就是在少发精细.
例如,定义如下抑制规则:

- source_match:
    alertname: NodeDown
    severity: critical
  target_match:
    severity: critical
  equal:
    - node

例如:当集群中的某一个主机节点异常宕机导致告警NodeDown被触发,同时在告警规则中定义了告警级别severity=critical。由于该主机异常宕机,该主机上部署的所有服务,中间件会不可用并触发报警。根据抑制规则的定义,如果有新的告警级别为severity=critical,并且告警中的标签node的值与NodeDown告警的相同,则说明新的告警是由NodeDown导致的,则启动抑制机制停止向接收器发送通知。

临时静默
除了基于抑制机制可以控制告警通知的行为以外,用户或者管理员还可以直接通过Alertmanager的UI临时屏蔽特定的告警通知。通过定义标签的匹配规则(字符串或者正则表达式),如果新的告警通知满足静默规则的设置,则停止向receiver发送通知。
进入Alertmanager UI,点击"New Silence"显示如下内容:
在这里插入图片描述
用户可以通过该UI定义新的静默规则的开始时间以及持续时间,通过Matchers部分可以设置多条匹配规则(字符串匹配或者正则匹配)。填写当前静默规则的创建者以及创建原因后,点击"Create"按钮即可。

通过"Preview Alerts"可以查看预览当前匹配规则匹配到的告警信息。静默规则创建成功后,Alertmanager会开始加载该规则并且设置状态为Pending,当规则生效后则进行到Active状态。
在这里插入图片描述
当静默规则生效以后,从Alertmanager的Alerts页面下用户将不会看到该规则匹配到的告警信息。
在这里插入图片描述
对于已经生效的规则,用户可以通过手动点击”Expire“按钮使当前规则过期。

使用Recoding Rules优化性能
通过PromQL可以实时对Prometheus中采集到的样本数据进行查询,聚合以及其它各种运算操作。而在某些PromQL较为复杂且计算量较大时,直接使用PromQL可能会导致Prometheus响应超时的情况。这时需要一种能够类似于后台批处理的机制能够在后台完成这些复杂运算的计算,对于使用者而言只需要查询这些运算结果即可。Prometheus通过Recoding Rule规则支持这种后台计算的方式,可以实现对复杂查询的性能优化,提高查询效率。
定义Recoding rules
在Prometheus配置文件中,通过rule_files定义recoding rule规则文件的访问路径。

rule_files:
  [ - <filepath_glob> ... ]

每一个规则文件通过以下格式进行定义:

groups:
  [ - <rule_group> ]

一个简单的规则文件可能是这个样子的:

groups:
  - name: example
    rules:
    - record: job:http_inprogress_requests:sum
      expr: sum(http_inprogress_requests) by (job)

rule_group的具体配置项如下所示:

# The name of the group. Must be unique within a file.
name: <string>

# How often rules in the group are evaluated.
[ interval: <duration> | default = global.evaluation_interval ]

rules:
  [ - <rule> ... ]

与告警规则一致,一个group下可以包含多条规则rule。

# The name of the time series to output to. Must be a valid metric name.
record: <string>

# The PromQL expression to evaluate. Every evaluation cycle this is
# evaluated at the current time, and the result recorded as a new set of
# time series with the metric name as given by 'record'.
expr: <string>

# Labels to add or overwrite before storing the result.
labels:
  [ <labelname>: <labelvalue> ]

根据规则中的定义,Prometheus会在后台完成expr中定义的PromQL表达式计算,并且将计算结果保存到新的时间序列record中。同时还可以通过labels为这些样本添加额外的标签。

这些规则文件的计算频率与告警规则计算频率一致,都通过global.evaluation_interval定义:

global:
  [ evaluation_interval: <duration> | default = 1m ]

参考文献:
https://github.com/cnych/alertmanager-dingtalk-hook/tree/116a3ea281a0ee35cd1065def202b52f22116a5e
https://open-doc.dingtalk.com/microapp/serverapi2/qf2nxq
https://www.qikqiak.com/k8s-book/docs/57.AlertManager%E7%9A%84%E4%BD%BF%E7%94%A8.html
使用Golang创建webhook服务
https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/alert/alert-manager-use-receiver/alert-manager-extension-with-webhook

猜你喜欢

转载自blog.csdn.net/ZhanBiaoChina/article/details/108523533