1 如何基于kube-prometheus设计一个监控系统-德赢Vwin官网 网
0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何基于kube-prometheus设计一个监控系统

马哥Linux运维 来源:马哥Linux运维 作者:马哥Linux运维 2022-09-13 09:47 次阅读

本文介绍了如何基于 kube-prometheus 设计一个监控系统, 以灵活简单的方式对 kubernetes 上的应用进行指标采集,并实现监控报警功能。

本文提供了作者的应用示例,另外还记录了作者在学习、使用 Prometheus 过程中的一些笔记,如 arm 版镜像获取、一些工具的使用等。

前言

衆所周知,大数据産品作为底层平台,其运维监控一直是生産实践的痛点难点,且在稳定运行的基础之上,往往还需要对性能进行评估优化,所以其监控系统的建设显得尤为重要。

Prometheus 作为云原生时代最火的监控软件,很多大数据组件或原生或以第三方插件 / exporter 的形式对 Prometheus 做了支持。

我使用的大数据平台是基于 kubernetes 运行的,有部署灵活管理方便的优点,更容易与 Prometheus 进行结合。

下面将对设计思路和技术实现进行阐述探讨。

设计思路

监控系统的核心任务是将暴露出来的指标数据进行抓取,在此之上进行分析、告警所以有以下几个要明确的问题:

监控对象是什么

监控对象如何暴露指标数据

监控系统如何对指标进行抓取

如何实现告警规则动态配置、管理

监控对象

以 pod(容器)形式运行在 kubernetes 集群上的各个大数据组件。

指标暴露方式

各组件根据对 Prometheus 的支持程度,可分为 3 种类型的指标暴露方式:

直接暴露 Prometheus 指标数据 (直接,拉)

主动将指标数据推送到 prometheus-pushGateway,由 pushGateway 暴露数据(间接,推)

自定义 exporter 将其他形式的指标数据转换为符合 Prometheus 标准的格式进行暴露(exporter,直接,拉)

个别组件同时支持多种方式,如 flink 支持直接和间接方式,spark 支持直接方式而且也有第三方 exporter。大部分组件都有官方 / 第三方的 exporter,极少数需要自己开发。

一般情况下直接方式就可以了。

需要注意的是,像 flink(spark) on yarn 模式运行的时候,flink 节点是跑在 yarn 容器里面的。这种情况下 Prometheus 很难对其直接进行抓取,这种时候就只能用间接方式,主动将数据推送到 pushGateway。

另外那些短暂生命周期的组件也建议用主动 push 到 pushGateway。

指标抓取方式

不管是 exporter 还是 pushGateway,到最后必然是由 Prometheus 主动对这些目标进行抓取。

Prometheus 主要通过 Pull 的方式来抓取目标服务暴露出来的监控接口,因此需要配置对应的抓取任务来请求监控数据并写入到 Prometheus 提供的存储中,目前 Prometheus 服务提供了如下几个任务的配置:

原生 Job 配置:提供 Prometheus 原生抓取 Job 的配置。

Pod Monitor:在 K8S 生态下,基于 Prometheus Operator 来抓取 Pod 上对应的监控数据。

Service Monitor:在 K8S 生态下,基于 Prometheus Operator 来抓取 Service 对应 Endpoints 上的监控数据。

参考:https://cloud.tencent.com/document/product/1416/55995

既然都上了 kubernetes 环境了,一般当然是推荐直接用 podMonitor。配置更简洁易懂。podMonitorSelector 的过滤在 prometheus-prometheus.yaml 配置。

prometheus-prometheus.yaml 是核心配置文件,不宜频繁修改 (会导致 Prometheus 重启)。

主要配置项为:serviceMonitorSelector,podMonitorSelector,ruleSelector,alertmanagers

其中 service 监控选择器和 pod 监控选择器默认选择所有,这里建议把 ruleSelector 也修改为选择所有。

不过一个 podMonitor 一般只对应一种类型的 pod,在已有 pod 类型较多的情况下,还可以考虑一种更取巧的方法就是 Prometheus 的 kubernetes 服务发现功能。即 kubernetes_sd_config。这种属于原生 Job 配置,建议使用 additional-scrape-config[1] 进行配置。

kubernetes_sd_config[2] 赋予了 Prometheus 通过 kubernetes rest api 感知 kubernetes 资源的功能,利用该能力,可以使用原生 Job 配置自动发现 pod,将其作为监控目标。再利用 Prometheus 的 Relabel 功能[3]可以改写发现的标签,进行前置处理、转换。实现 pod 筛选,修改抓取配置的效果。而自动发现的 pod 的标签的来源又可以是 pod 资源的 label/annotation 等。

最终实现的效果如下:

这是一个 pushGateway 的 pod 的配置 , 则 Prometheus 会通过其 19091 端口访问 / metrics 路径获取其指标数据

annotations:
prometheus.io/scrape:"true"
prometheus.io/scheme:"http"
prometheus.io/path:"/metrics"
prometheus.io/port:"19091"

这部分的内容主要参考:

https://godleon.github.io/blog/Prometheus/Prometheus-Relabel

https://yunlzheng.gitbook.io/prometheus-book/part-iii-prometheus-shi-zhan/readmd/service-discovery-with-kubernetes

podMonitor 是官方支持,简洁易懂。kubernetes_sd_config+relabel 的方案较复杂,难度较高,但不用写那么多的 podMonitor。自行抉择就行,也可以一起用。

告警设计

告警流程

prometheus 的监控告警基本流程是:

服务发生异常

触发 prometheus 服务器发出告警信息(alert)

alertmanager 收到告警信息

alertmanager 根据预配置的规则对告警信息进行处理,实现业务逻辑,如分组、抑制、触发短信邮箱等

当然具体的流程没那么简单,有很多细节需要注意,特别是触发告警时机,是个重点。

这些属于 Prometheus 的机制实现,这里就不展开赘述,推荐阅读以下文章:

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

AlertManager 何时报警[5]

后边会给出一个本人实际应用测试的例子,可供参考,会直观一些。

告警的动态配置

kube-prometheus 的告警规则分两部分:

alertmanager: 即对告警信息的处理策略

配置参考:https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/alert/alert-manager-config

核心是 alertmanager-secret.yaml 配置文件,该文件以 secret 的形式被 Alertmanager 读取。Alertmanager 会自动读取 secret 中的配置进行更新。

alertRule: 即具体的告警规则

配置参考:https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/alert/prometheus-alert-rule

在 kubernetes 中是以 PrometheusRule 类型操作,所以管理起来跟 pod 一样,直接使用 kubelet 增删改即可。

接入自定义告警平台

从个人实践的角度来看,AlertManager 处理 web hook 之外的告警接收插件,如短信、邮箱等只适合测着玩。生産使用还是要通过 web hook 将告警信息发送到自己的告警平台。可以根据业务需要对告警信息做高度定制化处理、记录等。另外可以在告警信息中携带具体告警规则等信息指导告警平台进行处理。

这里要做个区分,AlertManager 是告警信息的前置处理,负责非业务性前置操作,如告警信息分组、平抑等。而自定义告警平台则负责告警信息的业务处理,如记录、去敏、发送到多终端等。

AlertManager 可能收到 1w 条告警信息,经过处理最终只发了 1 条到自定义告警平台。而自定义告警平台可以将这 1 条告警信息记录起来,修改内容,同时使用邮箱、短信通知到多个负责人。

告警层级标签设计

监控对象的粒度决定告警的层级,体现在配置上则是告警规则的分组。分组信息决定 alertManager 的处理方式。

alertManager 对告警信息的路由策略是树状的,所以可通过多个分组标签实现多层级路由处理。

具体设计应结合业务需求,不在这里展开,感兴趣的可以看我下面的实现举例。

技术实现

技术实现主要分以下几部分:

kubernetes 环境下 prometheus 的部署 (kube-prometheus)

kube-prometheus 的增强配置 : 即 kubernetes_sd_config+relabel 方案的实现

bigdata-exporter 的实现

告警设计实例

kubernetes 环境下 prometheus 的部署

1) kube-prometheus vs prometheus-operator

github 上 coreos 下有两个项目:kube-prometheus 和 prometheus-operator,两者都可以实现 prometheus 的创建及管理。

需要注意的是,kube-prometheus 上的配置操作也是基于 prometheus-operator 的,并提供了大量的默认配置,故这里使用的是 kube-prometheus 项目的配置。

另外使用前需注意 k8s 版本要求,找到对应的 kube-prometheus 版本,弄清楚对应的 prometheus-operator 版本。如:k8s1.14 版本最高可使用 kube-prometheus 0.3,对应的 prometheus-operator 版本是 0.32,阅读文档时注意对应版本。

2) kube-prometheus 使用前说明

kube-prometheus 使用 jsonnet 编写配置模板文件,生成 k8s 配置清单。已提供默认清单文件,在 manifests 文件夹下。如果需要修改默认清单配置,需要在 go 环境下使用 jp 编译清单。

下面都以默认配置为例

3) 安装教程

参考官方说明即可

1、git clone 项目 并切换到指定分支

2、kubectl create

清单文件中各配置已附带 namespace 信息,故执行时不需要指定 namespace,否则可能出错。

官方命令如下:

#CreatethenamespaceandCRDs,andthenwaitforthemtobeavailblebeforecreatingtheremainingresources

$kubectlcreate-fmanifests/setup
$untilkubectlgetservicemonitors--all-namespaces;dodate;sleep1;echo"";done
$kubectlcreate-fmanifests/

kubernetes_sd_config+relabel 方案的实现

见:https://github.com/linshenkx/kube-prometheus-enhance

bigdata-exporter 的实现

hdfs、yarn、hbase、yarn 等组件都提供了 web 获取 jmx 指标的方式。

这里的思路是使用一个 bigdata-exporter,去采集多个组件多个节点的指标数据,并进行转换,然后以 Prometheus 规定的格式对外公开。

指标数据的转换规则可以查看 github 上的一些项目,要注意版本,也可以像我一样自己写,更可靠。

bigdata-exporter 如何感知到采集目标?

除了部署 ip 不同,不同组件不同角色的指标对外端口、路径、内容(解析规则)也都不一样。

这里可以参考上面 kubernetes_sd_config+relabel 的方案,做得优雅一些:

授予 bigdata-exporter 调用 kubernetes app 的能力,

利用 label 和 annotations 进行筛选和信息传递,确定捕捉目标和途径。

使用 role 代表解析内容的类型,根据 role 确定解析规则

labels:
bigData.metrics.object:pod
annotations:
bigData.metrics/scrape:"true"
bigData.metrics/scheme:"https"
bigData.metrics/path:"/jmx"
bigData.metrics/port:"29871"
bigData.metrics/role:"hdfs-nn,common"

告警设计示例

这里以实例两个维度为例,用 groupId 和 instanceId 表示。

1) alertManager 配置示例

以下是 alertmanager 的规则配置,有两个接收者,其中 test.web.hook 指向自定义告警平台。default 是空白接收者,不做处理。路由策略是根据 groupId,instanceId 分组,对节点磁盘使用率、kafka 队列堆积两个组处理,instanceId 还没有展开。

旧版本是用 secret 的 data 字段,需要将配置内容转成 base64 编码格式。新版本直接用 stringData 字段。推荐用 stringData 字段配置。其实只要看一下 kube-prometheus 的 alertmanager-secret.yaml 文件就知道怎么回事了。

使用 data 字段的配置方法:写好 config 文件,以 alertmanager.yaml 命名(不能使用其他名称)。执行以下命令 , 即可更新 secret。

$kubectl-nmonitoringcreatesecretgenericalertmanager-main--from-file=alertmanager.yaml--dry-run-oyaml|kubectl-n=monitoringapply-f-
global:
resolve_timeout:5m
receivers:
-name:'default'
-name:'test.web.hook'
webhook_configs:
-url:'http://alert-url'
route:
receiver:'default'
group_wait:30s
group_interval:5m
repeat_interval:2h
group_by:[groupId,instanceId]
routes:
-receiver:'test.web.hook'
continue:true
match:
groupId:node-disk-usage
-receiver:'test.web.hook'
continue:true
match:
groupId:kafka-topic-highstore

2) alertRule 配置示例

组代表一个类型的所有目标:即所有节点。实例则代表具体的某个节点。

disk-usage.yaml 磁盘使用率告警配置示例如下:

注意:${path} 为监控的磁盘路径,${thresholdValue} 为使用率阈值,需自行替换。labels 中的 userIds 和 receivers 为传递给自定义告警平台的参数,以指导告警平台如何操作。

在这个任务中,我们的目标是组粒度的(所有节点),所以不需要设置 instanceId。

apiVersion:monitoring.coreos.com/v1
kind:PrometheusRule
metadata:
creationTimestamp:null
labels:
role:alert-rules
name:node-disk-usage
namespace:monitoring
spec:
groups:
-name:node-disk-usage
rules:
-alert:node-disk-usage
expr:100*(1-node_filesystem_avail_bytes{mountpoint="${path}"}/node_filesystem_size_bytes{mountpoint="${path}"})>${thresholdValue}
for:1m
labels:
groupId:node-disk-usage
userIds:super
receivers:SMS
annotations:
title:"磁盘警告:节点{{$labels.instance}}的${path}目录使用率已达到{{$value}}%"
content:"磁盘警告:节点{{$labels.instance}}的${path}目录使用率已达到{{$value}}%"

kafka-topic-highstore.yaml kafka 队列消费堆积告警配置示例如下:

我们只关心个别队列的消费情况,所以这里的粒度为 instance。

注意:${uniqueName} 为队列名,${consumergroup} 为消费组名称,${thresholdValue} 为堆积数量阈值。

apiVersion:monitoring.coreos.com/v1
kind:PrometheusRule
metadata:
creationTimestamp:null
labels:
role:alert-rules
name:kafka-topic-highstore-${uniqueName}
namespace:monitoring
spec:
groups:
-name:kafka-topic-highstore
rules:
-alert:kafka-topic-highstore-${uniqueName}
expr:sum(kafka_consumergroup_lag{exporterType="kafka",consumergroup="${consumergroup}"})>${thresholdValue}
for:1m
labels:
groupId:kafka-topic-highstore
instanceId:${uniqueName}
userIds:super
receivers:SMS
annotations:
title:"KAFKA警告:消费组${consumergroup}的堆积数量达到:{{$value}}"
content:"KAFKA警告:消费组${consumergroup}的堆积数量达到:{{$value}}"

其他

告警流程示例

这里以两个节点 node1 和 node2 配置了磁盘空间监控为例,空间使用到达阈值则触发告警。(测试过程中可通过生成、删除指定体积的文件来控制空间占用)

其中配置项如下:

告警规则 : node-disk-usage

for 为 1m

告警中心 : alertManager

group_wait: 30s

group_interval: 5m

repeat_interval: 10m

收到的告警短信内容及时间线如下:

1014 收到第一次警报:node1 于 1044 进入异常

1014 收到第二次警报:node1 于 1044 进入异常node2 于 1044 进入异常

1029 收到第三次警报:node1 于 1044 进入异常node2 于 1044 进入异常

1044 收到第四次警报:node1 于 1044 进入异常node2 于 1044 进入异常

1044 收到第五次警报:恢复告警node1 于 1044 进入异常,并于 1044 恢复node2 于 1044 进入异常,并于 1014 恢复

总共收到 5 次短信,第 1 次是 node1 异常,第 2 到 4 次是 node1 和 node2 都异常,因为属于同个分组 group,所以合并发送。第 5 次是已经恢复正常了。

根据短信内容和时间,整理出告警逻辑时间线如下:

node1 等待 for 1 分钟 后警报进入 group

node1 记录异常时间为 1044,实际异常状态至少在 1044 的一分钟前

group 等待 group_wait 30s 后发送第一次告警

firing:node1

node2 等待 for 1 分钟 后警报进入 group

node2 记录异常时间为 1044,实际异常状态至少在 1044 的一分钟前,此时 group 中有两个异常目标 node1 和 node2。

group 等待 group_interval 5m 后发送第二次告警

firing:node1,node2

注意:因为 group 发生了变化,所以这里用的是 group_interval。

group 等待 repeat_interval 10m 后发送第三次告警

firing:node1,node2

注意:因为 group 没有变化,属于重复告警,用的是 repeat_interval。

group 等待 repeat_interval 10m 后发送第四次告警

firing:node1,node2

同上一次。

第四次告警后的 前 5 分钟:node2 恢复正常

第四次告警后的 后 5 分钟:node1 恢复正常

group 等待 repeat_interval 10m 后发送第五次告警

resolved:node1,node2

注意,这里 node1,node2 都恢复正常用的也是 repeat_interval。

综上:

for 是告警规则个体的监控配置,用来衡量服务多久检测不通过才算异常。

group_wait:初次发送告警的等待时间

用于 group 创建后的等待,这个值通常设置较小,在几分钟以内。

group_interval:同一个组其他新发生的告警发送时间间隔

是 group 内容发生变化后的告警间隔。

repeat_interval:重复发送同一个告警的时间间隔

group 内容没有变化且上一次发生成功时用的发生间隔。

需要注意,恢复正常不属于 group 变化,用的是 repeat_interval。这有点反直觉,且个人认为不是很合理,不知道是不是测试有问题,也没有找到比较好的资料说明。希望知道的可以指教一下。

exporter 的位置

exporter 可以以 sidecar 的形式和原容器放在同一个 pod 内(1 对 1),也可以以独立部署的形式存在(1 对 1/1 对多)。

这个视具体情况而定,技术上没什么不同,sidecar 可以绑定生命周期,视为对原有组件的补充。独立部署则耦合度更低,更灵活。像单节点的 mysql,用 sidecar 则只需要 1 个 pod,不会太复杂。

而如果像多节点的 kafka 集群,用独立部署则只需要一个 exporter 就可以实现对多个节点的采集监控。

这里出于减小耦合、节省资源的目的,我主要使用的是独立部署形式。

使用 promtool 检查指标格式是否正确

promtool 使用方法:

#进入pod
$kubectl-n=monitoringexec-itprometheus-k8s-0sh
#查看帮助
$promtool-h
#检查指标格式
$curl-shttp://ip:9999/metrics|promtoolcheckmetrics

比方说 指标 name、labelname 不能使用小数点

使用 port-forward 临时提供 Prometheus 外部访问

#prometheus
$nohupkubectlport-forward--address0.0.0.0service/prometheus-k8s19090:9090-n=monitoring&
#grafana
$nohupkubectlport-forward--address0.0.0.0service/grafana13000:3000-n=monitoring&
#alertmanager
$nohupkubectlport-forward--address0.0.0.0service/alertmanager-main9093:9093-n=monitoring&

用 jobs -l 可以查看

kube-prometheus 对 arm 的支持

目标是找到 kube-prometheus 用到的镜像的 arm 版本。

可以使用 https://quay.io/[6] 搜索。

以下是用到的镜像和各自对 arm 的支持情况。注意对照自己使用的版本,很多镜像高版本都支持 arm 了。

审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 监控系统
    +关注

    关注

    21

    文章

    3904

    浏览量

    174327
  • 软件
    +关注

    关注

    69

    文章

    4921

    浏览量

    87389
  • 大数据
    +关注

    关注

    64

    文章

    8882

    浏览量

    137392

原文标题:kube-prometheus 监控系统使用与总结

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Prometheus的架构原理从“监控”谈起

    Prometheus是继Kubernetes(k8s)之后,CNCF毕业的第二开源项目,其来源于Google的Borgmon。本文从监控这件事说起,深入浅出Prometheus的架构
    的头像 发表于 10-10 15:47 4479次阅读
    <b class='flag-5'>Prometheus</b>的架构原理从“<b class='flag-5'>监控</b>”谈起

    Prometheus的基本原理与开发指南

    PromQL高级实战 告警引擎深度解析 本地存储与远程存储 梯度运维管理平台监控模块架构 01监控系统概述 导读:本章从监控的作用、架构分类、指标
    的头像 发表于 11-09 10:45 1117次阅读
    <b class='flag-5'>Prometheus</b>的基本原理与开发指南

    阿里云容器Kubernetes监控(二) - 使用Grafana展现Pod监控数据

    Heapster的功能。因此Heapster成为了kubernetes中必不可少的组件,在阿里云的kubernetes集群中已经内置了Heapster+Influxdb的组合,如果需要将监控的数据进行
    发表于 05-10 15:28

    prometheus监控服务的整个流程介绍

    最近有新项目需要搞套完整的监控告警系统,我们使用了开源监控告警系统
    发表于 12-23 17:34

    django-prometheus数据监控

    django-prometheus.zip
    发表于 04-26 11:07 1次下载
    django-<b class='flag-5'>prometheus</b>数据<b class='flag-5'>监控</b>

    Prometheus服务监控系统

    prometheus.zip
    发表于 04-26 10:23 3次下载
    <b class='flag-5'>Prometheus</b>服务<b class='flag-5'>监控</b><b class='flag-5'>系统</b>

    使用Thanos+Prometheus+Grafana构建监控系统

    对于弹性伸缩和高可用的系统来说,般有大量的指标数据需要收集和存储,如何为这样的系统打造监控
    的头像 发表于 05-05 21:14 2632次阅读

    监控神器:Prometheus

    Prometheus发展速度很快,12年开发完成,16年加入CNCF,成为继K8s 之后第二CNCF托管的项目,目前Github 42k的,而且社区很活跃,维护频率很高,基本稳定在1月1
    的头像 发表于 07-31 11:55 1182次阅读

    关于Prometheus监控系统相关的知识体系

    今天浩道跟大家分享关于Prometheus监控系统相关的知识体系,让你通过本文可以大体掌握其相关知识体系!
    的头像 发表于 10-20 09:06 1188次阅读

    SpringBoot+Prometheus+Grafana实现自定义监控

    这里 management.endpoints.web.exposure.include=* 配置为开启 Actuator 服务,因为Spring Boot Actuator 会自动配置 URL
    的头像 发表于 12-26 16:02 1654次阅读

    prometheus下载安装教程

    Prometheus开放性的监控解决方案,用户可以非常方便的安装和使用 Prometheus 并且能够非常方便的对其进行扩展。 在
    的头像 发表于 01-13 16:07 8011次阅读
    <b class='flag-5'>prometheus</b>下载安装教程

    基于kube-prometheus的大数据平台监控系统设计

    本文介绍了如何基于 kube-prometheus 设计监控系统, 以灵活简单的方式对 kubernetes 上的应用进行指标采集,并实
    的头像 发表于 05-30 17:02 666次阅读

    40步骤安装部署Prometheus监控系统

    Prometheus套开源的监控&报警&时间序列数据库的组合,起始是由SoundCloud公司开发的。随着发展,越来越多公司和组织接受采用Prometheus,社区也十分活跃,他们
    的头像 发表于 08-14 11:53 5.1w次阅读
    40<b class='flag-5'>个</b>步骤安装部署<b class='flag-5'>Prometheus</b><b class='flag-5'>监控</b><b class='flag-5'>系统</b>

    基于Prometheus开源的完整监控解决方案

    一个Prometheus 监控的服务都是 Job,Prometheus 为这些 Job
    发表于 10-18 09:15 477次阅读
    基于<b class='flag-5'>Prometheus</b>开源的完整<b class='flag-5'>监控</b>解决方案

    Prometheus实战篇:Exporter知识概述

    所有可以向Prometheus提供监控样本数据的程序都可以被称为Exporter.而Exporter的
    的头像 发表于 12-25 09:57 1112次阅读
    <b class='flag-5'>Prometheus</b>实战篇:Exporter知识概述