企业级实战模块五:Prometheus+Grafana企业级监控系统(下)

企业级实战模块五:Prometheus+Grafana企业级监控系统(下)

7 安装并配置Alertmanager发送告警

7.1 创建Alertmanager配置文件

cat <<EOF> alertmanager-cm.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: alertmanager
namespace: monitor-sa
data:
alertmanager.yml: |-
  global:
    resolve_timeout: 1m
    smtp_smarthost: 'smtp.qq.com:25'
    smtp_from: '13669***qq.com'
    smtp_auth_username: '158****98'
    smtp_auth_password: 'pco****oyhaeg'
    smtp_require_tls: false
  route:
    group_by: [alertname]
    group_wait: 10s
    group_interval: 10s
    repeat_interval: 10m
    receiver: default-receiver
  receivers:
  - name: 'default-receiver'
    email_configs:
    - to: '290***@qq.com'
      send_resolved: true
EOF

kubectl apply -f alertmanager-cm.yaml
alertmanager配置文件解释说明:

    smtp_smarthost: 'smtp.qq.com:25'
# 163 邮箱的 SMTP 服务器地址+端口
    smtp_from: '1366***563@163.com'
# 这是指定从哪个邮箱发送报警
    smtp_auth_username: '158****55**'
# 这是发送邮箱的认证用户,不是邮箱名
    smtp_auth_password: 'BGWHYUOSOOHWEUJM'
# 这是发送邮箱的授权码而不是登录密码
    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
# 定义谁来收告警
    email_configs:
     - to: '2900***889@qq.com'
# 后面指定发送到哪个邮箱

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

7.2 报警处理流程如下:

  1. Prometheus Server 监控目标主机上暴露的 http 接口(这里假设接口 A ),通过 Promethes 配置的'scrape_ 定义的时间间隔,定期采集目标主机上监控数据。

  2. 当接口 A 不可用的时候, Server 端会持续的尝试从接口中取数据,直到 "scrape_ 时间后停止尝试。这时候把接口的状态变为 “ 。

  3. Prometheus 同时根据配置的 "evaluation_ 的时间间隔,定期(默认 1min )的对 AlertRule 进行评估;当到达评 估周期的时候,发现接口 A 为 DOWN ,即 UP=0 为真,激活 Alert ,进入“ 状态,并记录当前 active 的时间;

  4. 当下一个 alert rule 的评估周期到来的时候,发现 UP=0 继续为真,然后判断警报 Active 的时间是否已经超出 rule 里的 ‘for’ 持续时间,如果未超出,则进入下一个评估周期;如果时间超出,则 alert 的状态变为 “ FIRING”;同时调用 Alertmanager 接口,发送相关报警数据。

  5. AlertManager 收到报警数据后,会将警报信息进行分组,然后根据 aler tmanager 配置的“group_ 时间先进行等待。等 wait 时间过后再发送报警信息。

  6. 属于同一个 Alert Group 的警报,在等待的过程中可能进入新的 alert ,如果之前的报警已经成功发出,那么间隔 “group_ 的时间间隔后再重新发送报警信息。比如配置的是邮件报警,那么同属一个 group 的报警信息会汇总在一个邮件里进行发送。

  7. 如果 Alert Group 里的警报一直没发生变化并且已经成功发送,等待 ‘repeat_ 时间间隔之后再重复发送相同的报警邮件 ;如果之前的警报没有成功发送,则相当于触发第 6 条条件,则需要等待 group_interval 时间间隔后重复发送。同时最后至于警报信息具体发给谁,满足什么样的条件下指定警报接收人,设置不同报警发送频率,这里有 alertmanager 的 route 路由规则进行配置。

7.3 创建configmap配置文件

# 删除之前的cm配置文件
kubectl delete -f /opt/k8s-cfg/prometheus/prometheus-configmap.yaml

kubectl delete -f /opt/k8s-cfg/prometheus/prometheus-deploy.yaml

kubectl delete -f /opt/k8s-cfg/prometheus/prometheus-svc.yaml
# 创建新的cm文件,拉取后注意修改对应的节点IP
wget https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/configuration-file/prometheus-alertmanager-cfg.yaml

kubectl apply -f prometheus-alertmanager-cfg.yaml

7.4 创建deploy文件

# 生成一个etcd-certs ,这个在部署 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

image-20211110221938624

cat <<EOF> 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:
    securityContext:
      runAsUser: 0
    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
        nfs:
          server: 192.168.5.8
          path: /data/nfs
       - name: k8s-certs
        secret:
          secretName: etcd-certs
       - name: alertmanager-config
        configMap:
          name: alertmanager
       - name: alertmanager-storage
        nfs:
          server: 192.168.5.8
          path: /data/nfs/alertmanager
       - name: localtime
        hostPath:
          path: /usr/share/zoneinfo/Asia/Shanghai
EOF

kubectl apply -f prometheus-alertmanager-deploy.yaml

7.5 创建service文件

cat <<EOF> 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
EOF

kubectl apply -f alertmanager-svc.yaml
kubectl apply -f /opt/k8s-cfg/prometheus/prometheus-svc.yaml

查看部署情况

kubectl get pods,svc -n monitor-sa

image-20211110222821332

image-20211110222955493

image-20211110223241529

需要修改下proxy访问范围

kubectl edit configmap kube-proxy -n kube-system
# 把metricsBindAddress 这段修改成 metricsBindAddress: 0.0.0.0:10249

image-20211110223438329

# 然后重新启动kube-proxy 这个 pod
kubectl get pods -n kube-system | grep kube-proxy | awk '{print$1}' | xargs kubectl delete pods -n kube-system

image-20211110223657387

image-20211110223720701

image-20211110224923456

7.6 报警信息发送到钉钉

官方文档:

报警流程:

群设置→智能群助手→添加机器人→自定义→添加

1)在钉钉群中创建自定义机器人(生成Webhook)

参考文档:

https://developers.dingtalk.com/document/robots/custom-robot-access?spm=ding_open_doc.document.0.0.62846573jmFRhY#topic-2026027

2)安装钉钉的webhook插件

tar -zxvf prometheus-webhook-dingtalk-0.3.0.linux-amd64.tar.gz 

3)启动钉钉报警插件

cd prometheus-webhook-dingtalk-0.3.0.linux-amd64

nohup ./prometheus-webhook-dingtalk --web.listen-address="0.0.0.0:8060" --ding.profile="关键字= webhook地址 "

4)修改alertmanager-cm.yaml 文件

cat <<EOF> alertmanager-cm.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: alertmanager
namespace: monitor-sa
data:
alertmanager.yml: |-
global:
resolve_timeout: 1m
smtp_smarthost: 'smtp.qq.com:25'
smtp_from: '136***@qq.com'
smtp_auth_username: '158***8098'
smtp_auth_password: 'pcoe***aeg'
smtp_require_tls: false
route:
group_by: [alertname]
group_wait: 10s
group_interval: 10s
repeat_interval: 10m
receiver: 创建机器人时的关键字
receivers:
- name: 创建机器人时的关键字
webhook_configs:
- url: 'http://192.168.5.8:8060/dingtalk/cluster1/send'
send_resolved: true
EOF

kubectl apply -f alertmanager-cm.yaml

7.7 报警信息发送到企业微信

1)创建应用

找到应用管理,创建应用

应用名字wechat

2)修改alertmanager-cm.yaml 文件

cat <<EOF> alertmanager-cm.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: alertmanager
namespace: monitor-sa
data:
alertmanager.yml: |-
global:
resolve_timeout: 1m
smtp_smarthost: 'smtp.qq.com:25'
smtp_from: '136***63@qq.com'
smtp_auth_username: '1583***8'
smtp_auth_password: 'pco***aeg'
smtp_require_tls: false
route:
group_by: [alertname]
group_wait: 10s
group_interval: 10s
repeat_interval: 10m
receiver: prometheus
receivers:
- name: prometheus
wechat_configs:
- corp_id: ww***bb15
to_user: '@all
agent_id: 1***
api_secret: Ov5SWq_Jq***9qaMu1TTaDzVTCrXHcjlFs

EOF

kubectl apply -f alertmanager-cm.yaml

参数说明:

  • secret:企业微信 企业应用 自定应用 "[ Prometheus]----> "Secret")

  • wechat:是本人自创建应用名称

  • corp_id:企业信息 我的企业 ""------>" 在底部

  • agent_id:企业微信 企业应用 自定应用 "[ Prometheus]----> "AgentId ")

  • wechat:是自创建应用名称 在这创建的应用名字是 wechat ,那么在配置 route 时, receiver 也应该 是 Prometheus

  • to_user: '@all' :发送报警到所有人

3)配置自定义告警模板

cat template_wechat.tmpl
{{ define "wechat.default.message" }}
{{ range .Alerts }}
========start==========
告警程序:node_exporter
告警名称:{{ .Labels.alertname }}
故障主机:{{ .Labels.instance }}
告警主题:{{ .Annotations.summary }}
告警信息:{{ .Annotations.description }}
========end==========
{{ end }}
{{ end }}

8 Prometheus PromQL 语法

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

  • 瞬时向量(Instant vector): 一组时序,每个时序只有一个采样值

  • 区间向量(Range vector): 一组时序,每个时序包含一段时间内的多个采样值

  • 标量数据(Scalar): 一个浮点数

  • 字符串(String): 一个字符串,暂时未用

8.1 瞬时向量选择器

瞬时向量选择器用来选择一组时序在某个采样点的采样值。

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

apiserver_request_total

image-20211112105627800

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

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

image-20211112105614766

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

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

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

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

image-20211112105807383

8.2 区间向量选择器

区间向量选择器类似于瞬时向量选择器,不同的是它选择的是过去一段时间的采样值。可以通过在瞬时向量选择器后面添加包含在 [] 里的时长来得到区间向量选择器。比如下面的表达式选出了所有度量指标为 apiserver_request_total 且 resource 是 pod 的时序在过去 1 分钟的采样值。

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

image-20211112105914087

这个不支持Graph ,需要选择 Console ,才会看到采集的数据

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

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

8.3 偏移向量选择器

前面介绍的选择器默认都是以当前时间为基准时间,偏移修饰器用来调整基准时间,使其往前偏移一段时间。偏移修饰器紧跟在选择器后面,使用offset 来指定要偏移的量。比如下面的表达式选择度量名称为 apiserver_request_total 的所有时序在 5 分钟前的采样值。

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

image-20211112110040641

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

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

容器没有运行到一周的时间,故而没有图片演示

8.4 聚合操作符

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

  • sum:求和

  • min:最小值

  • max:最大值

  • avg:平均值

  • stddev:标准差

  • stdvar:方差

  • count:元素个数

  • count_values:等于某值的元素个数

  • bottomk:最小的 k 个元素

  • topk:最大的 k 个元素

  • quantile:分位数

示例:

计算k8s-master-01 节点 所有 容器总计内存

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

image-20211112110353190

计算k8s-master-01 节点 最近 1m 所有容器 cpu 使用率

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

image-20211112110535392

计算最近1m 所有容器 cpu 使用率

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

image-20211112110616142

8.5 函数

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

  • abs():绝对值

  • sqrt():平方根

  • exp():指数计算

  • ln():自然对数

  • ceil():向上取整

  • floor():向下取整

  • round():四舍五入取整

  • delta():计算区间向量里每一个时序第一个和最后一个的差值

  • sort():排序

9 Pushgateway介绍

9.1 介绍

Pushgateway 是 prometheus 的一个组件, prometheus server 默认是通过 exporter 主动获取数据(默认采取 pull 拉取数据), pushgateway 则是通过被动方式推送数据到 prometheus server用户可以写一些自定义的监控脚本把需要监控的数据发送给 pushgateway 然后 pushgateway 再把数据发送给 Prometheus server

1)Pushgateway优点:

Prometheus默认采用定时 pull 模式拉取 targets 数据,但是如果不在一个子网或者防火墙,prometheus 就拉取不到 targets 数据,所以可以采用各个 target 往 pushgateway 上 push 数据,然后 prometheus 去 pushgateway 上定时 pull 数据

在监控业务数据的时候,需要将不同数据汇总, 汇总之后的数据可以由 pushgateway 统一收集,然后由 Prometheus 统一拉取。

2)pushgateway缺点:

  • Prometheus拉取状态只针对 pushgateway, 不能对每个节点都有效;

  • Pushg ateway 出现问题,整个采集到的数据都会出现问题监控下线,

  • prometheus 还会拉取到旧的监控数据,需要手动清理 pushgateway 不要的数据。

9.2 安装

docker run -itd --name pushgateway -p 9091:9091 prom/pushgateway

image-20211112110955928

9.3 验证

1)修改prometheus-alertmanager-cfg.yaml 文件

- job_name: 'pushgateway'
scrape_interval: 5s
static_configs:
targets: ['192.168.5.8:9091']
honor_labels: true

image-20211112111410501

2)重新载入配置文件

kubectl apply -f prometheus-alertmanager-cfg.yaml
kubectl delete -f prometheus-alertmanager-deploy.yaml
kubectl apply -f prometheus-alertmanager-deploy.yaml

image-20211112111930633

3)手动推送简单数据到Pushgateway

echo "metric 3.6" | curl --data-binary @- http://192.168.5.8:9091/metrics/job/test_job

image-20211112112419161

image-20211112112614440

注: --data-binary 表示发送二进制数据,注意:它是使用 POST 方式发送的!

4)添加复杂数据

cat <<EOF | curl --data-binary @- http://192.168.5.8:9091/metrics/job/test_job/instance/test_instance
#TYPE node_memory_usage gauge
node_memory_usage 36
# TYPE memory_total gauge
node_memory_total 36000
EOF

image-20211112114725942

删除某个组下某个实例的所有数据

curl -X DELETE http://192.168.5.8:9091/metrics/job/test_job/instance/test_instance

删除某个组下的所有数据:

curl -X DELETE http://192.168.5.8:9091/metrics/job/test_job

9.4 实际场景演示

在被监控服务所在的机器配置数据上报想要把 192.168.5.9 这个机器的内存数据上报到pushgateway ,下面步骤需要在 192.168.5.9 操作

vim push
#!/bin/bash
node_memory_usages=$(free -m | grep Mem | awk '{print $3/$2*100}')
job_name="memory"
instance_name="192.168.5.9"

cat <<EOF | curl --data-binary @- http://192.168.5.8:9091/metrics/job/$job_name/instance/$instance_name
#TYPE node_memory_usages gauge
node_memory_usages $node_memory_usages
EOF

image-20211112120547974

可以通过定时任务来进行定时上传

注意:从上面配置可以看到,我们上传到pushgateway 中的数据有 job 也有 instance ,而prometheus 配置 pushgateway 这个 job _name 中也有 job 和 instance ,这个 job 和 instance 是指 pushgateway 实例本身, 添加 honor_labels: true 参数, 可以 避免 promethues 的 targets 列表中的 job _name 是 pushgateway 的 job 、 insta nce 和上报到 pushgateway 数据的 job 和instance 冲突 。

posted @ 2021-09-15 17:01  孤独的小人物  阅读(377)  评论(0编辑  收藏  举报