百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 博客教程 > 正文

基于 Prometheus 的监控神器,简单灵活

connygpt 2024-12-16 11:38 10 浏览

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

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

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

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

一、设计思路

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

  1. 监控对象是什么
  2. 监控对象如何暴露指标数据
  3. 监控系统如何对指标进行抓取
  4. 如何实现告警规则动态配置、管理

监控对象

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

指标暴露方式

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

  1. 直接暴露 Prometheus 指标数据 (直接,拉)
  2. 主动将指标数据推送到 prometheus-pushGateway,由 pushGateway 暴露数据(间接,推)
  3. 自定义 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

既然都上了 K8s 环境了,一般当然是推荐直接用 podMonitor。配置更简洁易懂。

podMonitorSelector 的过滤在 prometheus-prometheus.yaml 配置。

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

主要配置项为:serviceMonitorSelector、podMonitorSelector、ruleSelector、alertmanagers。

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

不过一个 podMonitor 一般只对应一种类型的 pod,在已有 pod 类型较多的情况下,

还可以考虑一种更取巧的方法就是 Prometheus 的 K8s 服务发现功能。即 kubernetes_sd_config

这种属于原生 Job 配置,建议使用 additional-scrape-config 进行配置。

kubernetes_sd_config 赋予了 Prometheus 通过 kubernetes rest api 感知 K8s 资源的功能,

利用该能力,可以使用原生 Job 配置自动发现 pod,将其作为监控目标。

再利用 Prometheus 的 Relabel 功能可以改写发现的标签,进行前置处理、转换。实现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"

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

告警设计

告警流程

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

  1. 服务发生异常
  2. 触发 prometheus 服务器发出告警信息(alert)
  3. alertmanager 收到告警信息
  4. alertmanager 根据预配置的规则对告警信息进行处理,实现业务逻辑,如分组、抑制、触发短信邮箱等
  5. 当然具体的流程没那么简单,有很多细节需要注意,特别是触发告警时机,是个重点。

告警的动态配置

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

  1. alertmanager:即对告警信息的处理策略
  2. alertRule:即具体的告警规则

接入自定义告警平台

从个人实践的角度来看,AlertManager处理web hook之外的告警接收插件,如短信、邮箱等只适合测着玩。

生产使用还是要通过web hook将告警信息发送到自己的告警平台。可以根据业务需要对告警信息做高度定制化处理、记录等。

另外可以在告警信息中携带具体告警规则等信息指导告警平台进行处理。

这里要做个区分,AlertManager 是告警信息的前置处理,负责非业务性前置操作,如告警信息分组、平抑等。

而自定义告警平台则负责告警信息的业务处理,如记录、去敏、发送到多终端等。

AlertManager 可能收到 1w 条告警信息,经过处理最终只发了1条到自定义告警平台。

而自定义告警平台可以将这1条告警信息记录起来,修改内容,同时使用邮箱、短信通知到多个负责人。

告警层级标签设计

监控对象的粒度决定告警的层级,体现在配置上则是告警规则的分组。

分组信息决定 alertManager 的处理方式。

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

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

二、技术实现

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

  1. kubernetes 环境下 prometheus 的部署(kube-prometheus)
  2. kube-prometheus 的增强配置:即 kubernetes_sd_config+relabel 方案的实现
  3. bigdata-exporter 的实现
  4. 告警设计实例

1.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 编译清单。

下面都以默认配置为例

2. kubernetes_sd_config+relabel 方案的实现

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

3. bigdata-exporter的实现

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

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

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

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

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

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

  1. 授予 bigdata-exporter 调用kubernetes app的能力,
  2. 利用 label 和 annotations 进行筛选和信息传递,确定捕捉目标和途径。
  3. 使用 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"

4.告警设计示例

这里以组和实例两个维度为例,用 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 -n monitoring create secret generic alertmanager-main --from-file=alertmanager.yaml --dry-run -o yaml  |  kubectl -n=monitoring apply -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.ftl磁盘使用率告警配置示例如下:

注意:$为监控的磁盘路径,$为使用率阈值,需自行替换

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.ftl kafka 队列消费堆积告警配置示例如下:
我们只关心个别队列的消费情况,所以这里的粒度为 instance。

注意$为队列名,$为消费组名称,$为堆积数量阈值

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

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

10:23:14 收到第一次警报:node1 于 10:22:44 进入异常

10:28:14 收到第二次警报:node1 于 10:22:44 进入异常 node2 于 10:24:44 进入异常

10:38:29 收到第三次警报:node1 于 10:22:44 进入异常 node2 于 10:24:44 进入异常

10:48:44 收到第四次警报:node1 于 10:22:44 进入异常 node2 于 10:24:44 进入异常

10:58:44 收到第五次警报:恢复告警 node1 于 10:22:44 进入异常,并于 10:55:44 恢复 node2 于 10:24:44 进入异常,并于 10:49:14 恢复

总共收到 5 次短信:

第 1 次是 node1 异常,

第 2 到 4 次是 node1 和 node2 都异常,因为属于同个分组 group,所以合并发送。

第 5 次是已经恢复正常了。

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

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

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




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

firing:node1




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

node2 记录异常时间为 10:24:44,实际异常状态至少在 10:24:44 的一分钟前,此时 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=monitoring exec -it prometheus-k8s-0  sh

# 查看帮助

$ promtool -h

# 检查指标格式

$ curl -s http://ip:9999/metrics | promtool check metrics

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

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

# prometheus

$ nohup  kubectl port-forward --address 0.0.0.0 service/prometheus-k8s 19090:9090 -n=monitoring &

# grafana

$ nohup kubectl port-forward --address 0.0.0.0 service/grafana 13000:3000 -n=monitoring &

# alertmanager

$ nohup  kubectl port-forward --address 0.0.0.0 service/alertmanager-main 9093:9093 -n=monitoring &

jobs -l 可以查看

来源:https://www.linshenkx.cn/archives/kube-prometheus-bigdata

侵删

相关推荐

3分钟让你的项目支持AI问答模块,完全开源!

hello,大家好,我是徐小夕。之前和大家分享了很多可视化,零代码和前端工程化的最佳实践,今天继续分享一下最近开源的Next-Admin的最新更新。最近对这个项目做了一些优化,并集成了大家比较关注...

干货|程序员的副业挂,12个平台分享

1、D2adminD2Admin是一个完全开源免费的企业中后台产品前端集成方案,使用最新的前端技术栈,小于60kb的本地首屏js加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助...

Github标星超200K,这10个可视化面板你知道几个

在Github上有很多开源免费的后台控制面板可以选择,但是哪些才是最好、最受欢迎的可视化控制面板呢?今天就和大家推荐Github上10个好看又流行的可视化面板:1.AdminLTEAdminLTE是...

开箱即用的炫酷中后台前端开源框架第二篇

#头条创作挑战赛#1、SoybeanAdmin(1)介绍:SoybeanAdmin是一个基于Vue3、Vite3、TypeScript、NaiveUI、Pinia和UnoCSS的清新优...

搭建React+AntDeign的开发环境和框架

搭建React+AntDeign的开发环境和框架随着前端技术的不断发展,React和AntDesign已经成为越来越多Web应用程序的首选开发框架。React是一个用于构建用户界面的JavaScrip...

基于.NET 5实现的开源通用权限管理平台

??大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!??今天小编推荐一款基于.NE...

StreamPark - 大数据流计算引擎

使用Docker完成StreamPark的部署??1.基于h2和docker-compose进行StreamPark部署wgethttps://raw.githubusercontent.com/a...

教你使用UmiJS框架开发React

1、什么是Umi.js?umi,中文可发音为乌米,是一个可插拔的企业级react应用框架。你可以将它简单地理解为一个专注性能的类next.js前端框架,并通过约定、自动生成和解析代码等方式来辅助...

简单在线流程图工具在用例设计中的运用

敏捷模式下,测试团队的用例逐渐简化以适应快速的发版节奏,大家很早就开始运用思维导图工具比如xmind来编写测试方法、测试点。如今不少已经不少利用开源的思维导图组件(如百度脑图...)来构建测试测试...

【开源分享】神奇的大数据实时平台框架,让Flink&Spark开发更简单

这是一个神奇的框架,让Flink|Spark开发更简单,一站式大数据实时平台!他就是StreamX!什么是StreamX大数据技术如今发展的如火如荼,已经呈现百花齐放欣欣向荣的景象,实时处理流域...

聊聊规则引擎的调研及实现全过程

摘要本期主要以规则引擎业务实现为例,陈述在陌生业务前如何进行业务深入、调研、技术选型、设计及实现全过程分析,如果你对规则引擎不感冒、也可以从中了解一些抽象实现过程。诉求从硬件采集到的数据提供的形式多种...

【开源推荐】Diboot 2.0.5 发布,自动化开发助理

一、前言Diboot2.0.5版本已于近日发布,在此次发布中,我们新增了file-starter组件,完善了iam-starter组件,对core核心进行了相关优化,让devtools也支持对IAM...

微软推出Copilot Actions,使用人工智能自动执行重复性任务

IT之家11月19日消息,微软在今天举办的Ignite大会上宣布了一系列新功能,旨在进一步提升Microsoft365Copilot的智能化水平。其中最引人注目的是Copilot...

Electron 使用Selenium和WebDriver

本节我们来学习如何在Electron下使用Selenium和WebDriver。SeleniumSelenium是ThoughtWorks提供的一个强大的基于浏览器的开源自动化测试工具...

Quick 'n Easy Web Builder 11.1.0设计和构建功能齐全的网页的工具

一个实用而有效的应用程序,能够让您轻松构建、创建和设计个人的HTML网站。Quick'nEasyWebBuilder是一款全面且轻巧的软件,为用户提供了一种简单的方式来创建、编辑...