基于 Prometheus 的监控神器,看完不信你不会,简单灵活!
一、设计思路
监控系统的核心任务是将暴露出来的指标数据进行抓取,在此之上进行分析、告警,所以有以下几个要明确的问题:
监控对象是什么
监控对象如何暴露指标数据
监控系统如何对指标进行抓取
如何实现告警规则动态配置、管理
监控对象
以 pod(容器)形式运行在 kubernetes 集群上的各个大数据组件。
指标暴露方式
各组件根据对 Prometheus 的支持程度,可分为 3 种类型的指标暴露方式:
直接暴露 Prometheus 指标数据 (直接,拉)
主动将指标数据推送到 prometheus-pushGateway,由 pushGateway 暴露数据(间接,推)
自定义 exporter 将其他形式的指标数据转换为符合 Prometheus 标准的格式进行暴露(exporter,直接,拉)
指标抓取方式
不管是 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 重启)。
kubernetes_sd_config
。这种属于原生 Job 配置,建议使用 additional-scrape-config 进行配置。
annotations:
prometheus.io/scrape: "true"
prometheus.io/scheme: "http"
prometheus.io/path: "/metrics"
prometheus.io/port: "19091"
告警设计
告警流程
prometheus 的监控告警基本流程是:
服务发生异常
触发 prometheus 服务器发出告警信息(alert)
alertmanager 收到告警信息
alertmanager 根据预配置的规则对告警信息进行处理,实现业务逻辑,如分组、抑制、触发短信邮箱等
当然具体的流程没那么简单,有很多细节需要注意,特别是触发告警时机,是个重点。
告警的动态配置
kube-prometheus 的告警规则分两部分:
alertmanager:即对告警信息的处理策略
alertRule:即具体的告警规则
接入自定义告警平台
告警层级标签设计
二、技术实现
技术实现主要分以下几部分:
kubernetes 环境下 prometheus 的部署(kube-prometheus)
kube-prometheus 的增强配置:即 kubernetes_sd_config+relabel 方案的实现
bigdata-exporter 的实现
告警设计实例
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 指标的方式。
指标数据的转换规则可以查看 github 上的一些项目,要注意版本,也可以像我一样自己写,更可靠。
bigdata-exporter 如何感知到采集目标?
授予 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"
4.告警设计示例
这里以组和实例两个维度为例,用 groupId 和 instanceId 表示。
1) alertManager配置示例
使用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
磁盘使用率告警配置示例如下:$
为监控的磁盘路径,$为使用率阈值,需自行替换在这个任务中,我们的目标是组粒度的(所有节点),所以不需要设置 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}}%"
我们只关心个别队列的消费情况,所以这里的粒度为 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}}"
三、其他
告警流程示例
(测试过程中可通过生成、删除指定体积的文件来控制空间占用)
其中配置项如下:
告警规则: 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 次是已经恢复正常了。
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。这有点反直觉,且个人认为不是很合理,不知道是不是测试有问题,也没有找到比较好的资料说明。希望知道的可以指教一下。
使用 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
<< 滑动查看下一张图片 >>
看个新闻原来这么麻烦!一文趣谈 HTTP 协议
“高效运维”公众号诚邀广大技术人员投稿投稿邮箱:jiachen@greatops.net 或添加联系人微信:greatops1118。