05、基于Alertmanager发送报警到多个接收方(上)

目录

一、配置 Alertmanager 发送报警到 qq 邮箱

1、 1设置163邮箱;

1、 2创建alertmanager配置文件;

1、 3创建prometheus告警规则配置文件;

1、 4安装prometheus和alertmanager;

1、 5部署alertmanager的service;

1、 6浏览器访问Prometheus和alertmanager;

二、配置 alertmanager 发送报警到钉钉

1、 1创建钉钉机器人;

2、 2设置webhook;

2、 3查看钉钉群;

三、Prometheus 查询语言 PromQL 介绍

3、 1数据类型;

3、 2瞬时向量选择器;

3、 3区间向量选择器;

3、 4偏移向量选择器;

3、 5聚合操作符;

3、 6函数;


本篇文章所用到的资料文件下载地址:alertmanager报警发送资料-kubernetes文档类资源-CSDN下载

一、配置 Alertmanager 发送报警到 qq 邮箱

  • 报警:指 prometheus 将监测到的异常事件发送给 alertmanager
  • 通知:alertmanager 将报警信息发送到邮件、微信、钉钉等

1.1 设置 163 邮箱

*

根据提示步骤开启 POP3/SMTP/IMAP 服务,并自行保存授权码,下面需要用到授权码:

*

1.2 创建 alertmanager 配置文件

[root@k8s-master1 prometheus]# vim alertmanager-cm.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: alertmanager
  namespace: monitor-sa
data:
  alertmanager.yml: |-
    global:
      resolve_timeout: 1m
      smtp_smarthost: 'smtp.163.com:25'           # 163 邮箱的 SMTP 服务器地址+端口
      smtp_from: '13620xxx@163.com'               # 这是指定从哪个邮箱发送报警,写你自己的 163 邮箱
      smtp_auth_username: '13620xxx@163.com'      # 这是发送邮箱的认证用户,即邮箱账号
      smtp_auth_password: 'TJULxxx'               # 这是发送邮箱的授权码而不是邮箱登录密码,上面生成的授权码
      smtp_require_tls: false
    route:                                        # 用于配置告警分发策略
      group_by: [alertname]                       # alertmanager 会根据 group_by 配置将 Alert 分组 
      group_wait: 10s                             # 分组告警等待时间。也就是告警产生后等待 10s,如果有同组告警一起发出
      group_interval: 10s                         # 上下两组发送告警的间隔时间
      repeat_interval: 10m                        # 重复发送告警的时间,减少相同邮件的发送频率,默认是 1h
      receiver: default-receiver                  # 定义谁来收告警
    receivers:
    - name: 'default-receiver'
      email_configs:
      - to: '8651xxx@qq.com'                      # 指定发送到哪个邮箱,我发送到我的 qq 邮箱,大家需要写自己的邮箱地址,不应该跟 smtp_from 的邮箱名字重复
        send_resolved: true

[root@k8s-master1 prometheus]# kubectl apply -f alertmanager-cm.yaml 

[root@k8s-master1 prometheus]# kubectl get configmaps -n monitor-sa alertmanager 
NAME           DATA   AGE
alertmanager   1      10s

Prometheus 一条告警的触发流程、等待时间如下:

1、 PrometheusServer监控目标主机上暴露的http接口(这里假设接口A),通过Promethes配置的'scrape_interval'定义的时间间隔,定期采集目标主机上监控数据;
2、 当接口A不可用的时候,Server端会持续的尝试从接口中取数据,直到"scrape_timeout"时间后停止尝试,这时候把接口的状态变为“DOWN”;
3、 Prometheus同时根据配置的"evaluation_interval"的时间间隔,定期(默认1min)的对AlertRule进行评估;当到达评估周期的时候,发现接口A为DOWN,即UP=0为真,激活Alert,进入“PENDING”状态,并记录当前active的时间;
4、 当下一个alertrule的评估周期到来的时候,发现UP=0继续为真,然后判断警报Active的时间是否已经超出rule里的‘for’持续时间,如果未超出,则进入下一个评估周期;如果时间超出,则alert的状态变为“FIRING”;同时调用Alertmanager接口,发送相关报警数据;
5、 AlertManager收到报警数据后,会将警报信息进行分组,然后根据alertmanager配置的“group_wait”时间先进行等待等wait时间过后再发送报警信息;
6、 属于同一个AlertGroup的警报,在等待的过程中可能进入新的alert,如果之前的报警已经成功发出,那么间隔“group_interval”的时间间隔后再重新发送报警信息比如配置的是邮件报警,那么同属一个group的报警信息会汇总在一个邮件里进行发送;
7、 如果AlertGroup里的警报一直没发生变化并且已经成功发送,等待‘repeat_interval’时间间隔之后再重复发送相同的报警邮件;如果之前的警报没有成功发送,则相当于触发第6条条件,则需要等待group_interval时间间隔后重复发送;

最后至于警报信息具体发给谁,满足什么样的条件下指定警报接收人,设置不同报警发送频率,这里由 alertmanager 的 route 路由规则进行配置。

1.3 创建 prometheus 告警规则配置文件

在k8s 的控制节点生成一个 prometheus-alertmanager-cfg.yaml 文件,prometheus-alertmanager-cfg.yaml 文件(里面的内容很多)在前面的下载地址里,上传到 k8s 的 master1 节点:

# 手动修改 prometheus-alertmanager-cfg.yaml 文件下面内容:
[root@k8s-master1 prometheus]# vim prometheus-alertmanager-cfg.yaml 
******
    - job_name: 'kubernetes-etcd'
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/ca.crt
        cert_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/server.crt
        key_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/server.key
      scrape_interval: 5s
      static_configs:
      - targets: ['192.168.78.143:2379']    # 修改为 master 节点 ip
******

# 把上一篇文章讲解的 Prometheus 时创建的 configmap 删除
[root@k8s-master1 prometheus]# kubectl delete -f prometheus-cfg.yaml 

[root@k8s-master1 prometheus]# kubectl apply -f prometheus-alertmanager-cfg.yaml 

1.4 安装 prometheus 和 alertmanager

需要把alertmanager.tar.gz 镜像包上传的 k8s 的各个工作节点,手动解压:

[root@k8s-node1 ~]# docker load -i alertmanager.tar.gz 
[root@k8s-node2 ~]# docker load -i alertmanager.tar.gz 

[root@k8s-master1 prometheus]# vim prometheus-alertmanager-deploy.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus-server
  namespace: monitor-sa
  labels:
    app: prometheus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
      component: server
    #matchExpressions:
    #- {key: app, operator: In, values: [prometheus]}
    #- {key: component, operator: In, values: [server]}
  template:
    metadata:
      labels:
        app: prometheus
        component: server
      annotations:
        prometheus.io/scrape: 'false'
    spec:
      nodeName: k8s-node1
      serviceAccountName: monitor
      containers:
      - name: prometheus
        image: prom/prometheus:v2.2.1
        imagePullPolicy: IfNotPresent
        command:
        - "/bin/prometheus"
        args:
        - "--config.file=/etc/prometheus/prometheus.yml"
        - "--storage.tsdb.path=/prometheus"
        - "--storage.tsdb.retention=24h"
        - "--web.enable-lifecycle"
        ports:
        - containerPort: 9090
          protocol: TCP
        volumeMounts:
        - mountPath: /etc/prometheus
          name: prometheus-config
        - mountPath: /prometheus/
          name: prometheus-storage-volume
        - name: k8s-certs
          mountPath: /var/run/secrets/kubernetes.io/k8s-certs/etcd/
      - name: alertmanager
        image: prom/alertmanager:v0.14.0
        imagePullPolicy: IfNotPresent
        args:
        - "--config.file=/etc/alertmanager/alertmanager.yml"
        - "--log.level=debug"
        ports:
        - containerPort: 9093
          protocol: TCP
          name: alertmanager
        volumeMounts:
        - name: alertmanager-config
          mountPath: /etc/alertmanager
        - name: alertmanager-storage
          mountPath: /alertmanager
        - name: localtime
          mountPath: /etc/localtime
      volumes:
        - name: prometheus-config
          configMap:
            name: prometheus-config
        - name: prometheus-storage-volume
          hostPath:
           path: /data
           type: Directory
        - name: k8s-certs
          secret:
           secretName: etcd-certs
        - name: alertmanager-config
          configMap:
            name: alertmanager
        - name: alertmanager-storage
          hostPath:
           path: /data/alertmanager
           type: DirectoryOrCreate
        - name: localtime
          hostPath:
           path: /usr/share/zoneinfo/Asia/Shanghai

注意:配置文件指定了 nodeName: k8s-node1,这个位置要写你自己环境的 k8s 的 node 节点名字。

# 生成一个 etcd-certs,这个在部署 prometheus 时需要
[root@k8s-master1 prometheus]# kubectl -n monitor-sa create secret generic etcd-certs --from-file=/etc/kubernetes/pki/etcd/server.key  --from-file=/etc/kubernetes/pki/etcd/server.crt --from-file=/etc/kubernetes/pki/etcd/ca.crt

# 先删除上一篇文章创建的 Prometheus
[root@k8s-master1 prometheus]# kubectl delete -f prometheus-deploy.yaml 

[root@k8s-master1 prometheus]# kubectl apply -f prometheus-alertmanager-deploy.yaml 

# 查看 prometheus 是否部署成功
[root@k8s-master1 prometheus]# kubectl get pods -n monitor-sa | grep prometheus
prometheus-server-bf4569646-tvk6k   2/2     Running   0             22s

1.5 部署 alertmanager 的 service

[root@k8s-master1 prometheus]# vim alertmanager-svc.yaml
---
apiVersion: v1
kind: Service
metadata:
  labels:
    name: prometheus
    kubernetes.io/cluster-service: 'true'
  name: alertmanager
  namespace: monitor-sa
spec:
  ports:
  - name: alertmanager
    nodePort: 30066
    port: 9093
    protocol: TCP
    targetPort: 9093
  selector:
    app: prometheus
  sessionAffinity: None
  type: NodePort

[root@k8s-master1 prometheus]# kubectl apply -f alertmanager-svc.yaml 

# 查看 service 在物理机映射的端口
[root@k8s-master1 prometheus]# kubectl get svc -n monitor-sa 
NAME           TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
alertmanager   NodePort   10.96.7.204      <none>        9093:30066/TCP   7s
prometheus     NodePort   10.108.228.243   <none>        9090:30812/TCP   41h

上面可以看到 prometheus 的 service 在物理机映射的端口是 30812,alertmanager 的 service 在物理机映射的端口是 30066。

1.6 浏览器访问 Prometheus 和 alertmanager

点击status -> targets,可看到如下:

*

点击Alerts,可看到如下:

*

kubernetes-etcd (1 active) 展开,可看到如下:

*

FIRING 表示 prometheus 已经将告警发给 alertmanager,在 Alertmanager 中可以看到有一个 alert。

*

这样在我的 qq 邮箱就可以收到报警了,如下:*

二、配置 alertmanager 发送报警到钉钉

1.1 创建钉钉机器人

注意:钉钉机器人只能在 PC 端应用创建!

PC端钉钉中 -> 选择右上角 "+" 号 -> 发起群聊 -> 面对面进群 -> 在群设置里找到“智能群助手” -> 添加机器人 -> 选择“自定义” -> 添加 -> 自定义“机器人名字” -> 勾选“自定义关键词” -> 输入关键词:cluster1 -> 完成。

*

保存好生成的 webhook,如果没保存的童鞋可以重新在智能群助手中找到刚刚创建的机器人,可以看到 webhook。

2.2 设置 webhook

在k8s 的控制节点 master1 安装钉钉的 webhook 插件:

# 上传 prometheus-webhook-dingtalk-0.3.0.linux-amd64.tar.gz 文件
[root@k8s-master1 ~]# tar -zxvf prometheus-webhook-dingtalk-0.3.0.linux-amd64.tar.gz 
[root@k8s-master1 ~]# cd prometheus-webhook-dingtalk-0.3.0.linux-amd64/

# 启动钉钉报警插件
[root@k8s-master1 prometheus-webhook-dingtalk-0.3.0.linux-amd64]# nohup ./prometheus-webhook-dingtalk --web.listen-address="0.0.0.0:8060" --ding.profile="cluster1=https://oapi.dingtalk.com/robot/send?access_token=9f03aa13d7ec4274806c4f0e2398e9277712bf3a27d808ef37de5d01dd5e3d62" &

# 上述 cluster1 为创建机器人时的关键词;url 为 webhook。

# 对原来的 alertmanager-cm.yaml 文件做备份
[root@k8s-master1 prometheus]# cp alertmanager-cm.yaml alertmanager-cm.yaml.bak
[root@k8s-master1 prometheus]# cat > alertmanager-cm.yaml <<EOF
kind: ConfigMap
apiVersion: v1
metadata:
  name: alertmanager
  namespace: monitor-sa
data:
  alertmanager.yml: |-
    global:
      resolve_timeout: 1m
      smtp_smarthost: 'smtp.163.com:25'
      smtp_from: '13620xxx@163.com'
      smtp_auth_username: '13620xxx@163.com'
      smtp_auth_password: 'TJULUxxx'
      smtp_require_tls: false
    route:
      group_by: [alertname]
      group_wait: 10s
      group_interval: 10s
      repeat_interval: 10m
      receiver: cluster1        # 创建机器人的关键词
    receivers:
    - name: cluster1            # 创建机器人的关键词
      webhook_configs:
      - url: 'http://192.168.78.143:8060/dingtalk/cluster1/send'    # 安装 webhook 插件的节点 ip
        send_resolved: true
EOF

[root@k8s-master1 prometheus]# kubectl apply -f alertmanager-cm.yaml 

[root@k8s-master1 prometheus]# kubectl delete -f prometheus-alertmanager-deploy.yaml 
[root@k8s-master1 prometheus]# kubectl apply -f prometheus-alertmanager-deploy.yaml 

2.3 查看钉钉群

*

三、Prometheus 查询语言 PromQL 介绍

PromQL(Prometheus Query Language)是 Prometheus 自己开发的表达式语言,语言表现力很丰富,内置函数也很多。使用它可以对时序数据进行筛选和聚合。

3.1 数据类型

PromQL 表达式计算出来的值有以下几种类型:

  • 瞬时向量 (Instant vector):一组时序,每个时序只有一个采样值。
  • 区间向量 (Range vector):一组时序,每个时序包含一段时间内的多个采样值。
  • 标量数据 (Scalar):一个浮点数。
  • 字符串 (String):一个字符串,暂时未用。

3.2 瞬时向量选择器

瞬时向量选择器用来选择一组时序在某个采样点的采样值。最简单的情况就是指定一个度量指标,选择出所有属于该度量指标的时序的当前采样值。比如下面的表达式:

apiserver_request_total

*

可以通过在后面添加用大括号包围起来的一组标签键值对来对时序进行过滤。比如下面的表达式筛选出了 job 为 kubernetes-apiservers,并且 resource为 pod 的时序:

apiserver_request_total{job="kubernetes-apiserver",resource="pods"}

*

匹配标签值时可以是等于,也可以使用正则表达式。总共有下面几种匹配操作符:

  • = :完全相等
  • != :不相等
  • =~ :正则表达式匹配
  • !~ :正则表达式不匹配

下面的表达式筛选出了 container 是 kube-scheduler 或 kube-proxy 或 kube-apiserver 的时序数据

container_processes{container=~"kube-scheduler|kube-proxy|kube-apiserver"}

*

3.3 区间向量选择器

区间向量选择器类似于瞬时向量选择器,不同的是它选择的是过去一段时间的采样值。可以通过在瞬时向量选择器后面添加包含在 [] 里的时长来得到区间向量选择器。

比如下面的表达式选出了所有度量指标为 apiserver_request_total 且 resource 是 pod 的时序在过去 1 分钟的采样值:

apiserver_request_total{job="kubernetes-apiserver",resource="pods"}[1m]

*

时长的单位可以是下面几种之一:

  • s :seconds
  • m :minutes
  • h :hours
  • d :days
  • w :weeks
  • y :years

3.4 偏移向量选择器

前面介绍的选择器默认都是以当前时间为基准时间,偏移修饰器用来调整基准时间,使其往前偏移一段时间。偏移修饰器紧跟在选择器后面,使用 offset 来指定要偏移的量。

比如下面的表达式选择度量名称为 apiserver_request_total 的所有时序在 5 分钟前的采样值:

apiserver_request_total{job="kubernetes-apiserver",resource="pods"} offset 5m

下面的表达式选择 apiserver_request_total 度量指标在 1 周前的这个时间点过去 5 分钟的采样值:

apiserver_request_total{job="kubernetes-apiserver",resource="pods"} [5m] offset 1w

3.5 聚合操作符

PromQL 的聚合操作符用来将向量里的元素聚合得更少。总共有下面这些聚合操作符:

  • sum:求和
  • min:最小值
  • max:最大值
  • avg:平均值
  • stddev:标准差
  • stdvar:方差
  • count:元素个数
  • count_values:等于某值的元素个数
  • bottomk:最小的 k 个元素
  • topk:最大的 k 个元素
  • quantile:分位数

1、 计算k8s-master1节点所有容器总计内存:;

sum(container_memory_usage_bytes{instance=~"k8s-master1"})/1024/1024/1024

2、 计算k8s-master1节点最近1m所有容器cpu使用率:;

sum (rate (container_cpu_usage_seconds_total{instance=~"k8s-master1"}[1m])) / sum (machine_cpu_cores{ instance =~"k8s-master1"}) * 100

3、 计算最近1m所有容器cpu使用率:;

sum (rate (container_cpu_usage_seconds_total{id!="/"}[1m])) by (id)

*

3.6 函数

Prometheus 内置了一些函数来辅助计算,下面介绍一些典型的:

  • abs():绝对值
  • sqrt():平方根
  • exp():指数计算
  • ln():自然对数
  • ceil():向上取整
  • floor():向下取整
  • round():四舍五入取整
  • delta():计算区间向量里每一个时序第一个和最后一个的差值
  • sort():排序

上一篇文章:【Kubernetes 企业项目实战】02、基于 Prometheus 和 K8s 构建智能化监控告警系统(下)_Stars.Sky的博客-CSDN博客

下一篇文章:【Kubernetes 企业项目实战】03、基于 Alertmanager 发送报警到多个接收方(下)_Stars.Sky的博客-CSDN博客