教你如何进行Prometheus 分片自动缩放
本文分享自华为云社区《使用 Prometheus-Operator 进行 Prometheus + Keda 分片自动缩放》,作者: Kubeservice@董江。
垂直缩放与水平缩放
Prometheus已经成为云原生时代事实上的监控工具。从监控小型花园的实例到企业中大规模的监控,Prometheus 都可以处理工作负载!但并非没有挑战…
在拥有数百个团队的大型组织中,每秒获取数百万个指标是很常见的。人们可以维护一个 Prometheus 实例,并通过投入资金来解决扩展问题:只需获得一个更大的节点即可。好吧,如果你愿意付钱,那就去吧!但是节点价格的增长速度通常高于其大小,并且管理大型和小型 Prometheus 实例之间还有另一个很大的区别:WAL 重播!
Prometheus 保留一个包含最新抓取数据的内存数据库。为了避免在可能的重新启动期间丢失数据,Prometheus 在磁盘上保留了预写日志 (WAL)。当 Prometheus 重启时,它会将 WAL 重新加载到内存中,这样最新抓取的数据就又可用了,这个操作就是我们所说的 WAL Replay。
在 WAL 重放期间,Prometheus 完全无法进行查询,也无法抓取任何目标,因此我们希望尽快完成此操作!这就是巨大的 Prometheus 实例成为问题的时候。当将数百 GiB 的数据重放到内存中时,此操作很容易需要 20 到 30 分钟,在更极端的情况下甚至需要几个小时。如果您决定保留单个 Prometheus 实例,WAL Replay 操作可能会导致监控系统出现长时间停机。
避免大型 Prometheus 实例的一种常见策略是在多个 Prometheus 之间分片抓取目标。由于每个 Prometheus 都会抓取较少量的指标,因此它们会小得多,并且 WAL Replay 不会像以前那样成为问题。为了仍然能够拥有集中式查询体验,可以将指标转发到另一个工具,例如 Thanos、Cortex 或云提供商,这些工具也能够扩展 Prometheus 查询功能。

整个时间内负载不均匀
我们已经通过使用分片而不是垂直扩展 Prometheus 取得了一些重大进展,但是当暴露的指标数量全天增加和减少时会发生什么?对于每天从数百个节点扩展到数千个节点(反之亦然)的 Kubernetes 集群来说,这是一种非常常见的情况。在决定普罗米修斯碎片的数量时,我们如何找到成本/效益比的最佳点?
您可以每天手动微调集群中的分片数量,但有更智能的方法来完成此任务。在这篇博文中,我将重点介绍 Horizontal Pod Autoscaler 策略,该策略是最近通过 Prometheus-Operator v0.71.0 版本实现的。

使用 Keda 自动缩放 Prometheus 碎片
设置
使用 Kubernetes Scale API 的任何类型的 Horizontal Pod Autoscaler,但出于演示目的,将使用Keda,它支持多种扩展策略。
让我们从创建一个小型集群开始,我建议使用KinD或Minikube:
$ kind create cluster
Creating cluster "kind" ...
✓ Ensuring node image (kindest/node:v1.27.1)
✓ Preparing nodes
✓ Writing configuration
✓ Starting control-plane ️
✓ Installing CNI
✓ Installing StorageClass
Set kubectl context to "kind-kind"
You can now use your cluster with: kubectl cluster-info --context kind-kind Have a nice day!
现在让我们安装 Keda:
$ helm repo add kedacore https://kedacore.github.io/charts
$ helm repo update
$ helm install keda kedacore/keda --namespace keda --create-namespace
$ watch kubectl get pods -n keda
一旦所有 Pod 都达到该Running状态,我们就可以继续!下一步是安装 Prometheus Operator:
$ git clone https://github.com/prometheus-operator/prometheus-operator
$ cd prometheus-operator
$ kubectl apply --server-side -f bundle.yaml
部署 Prometheus 和示例应用程序
好了,初始设置完成了。让我们部署一些公开一些指标的应用程序!为了演示目的,让我们部署一个 Alertmanager:
---
apiVersion: monitoring.coreos.com/v1
kind: Alertmanager
metadata:
name: main
namespace: monitoring
spec:
image: quay.io/prometheus/alertmanager:v0.26.0
podMetadata:
labels:
app.kubernetes.io/instance: main
app.kubernetes.io/name: alertmanager
replicas: 1
serviceAccountName: alertmanager-main
---
apiVersion: v1
kind: Service
metadata:
name: alertmanager-main
namespace: monitoring
labels:
app.kubernetes.io/instance: main
app.kubernetes.io/name: alertmanager
spec:
ports:
- name: web
port: 9093
targetPort: web
- name: reloader-web
port: 8080
targetPort: reloader-web
selector:
app.kubernetes.io/instance: main
app.kubernetes.io/name: alertmanager
---
apiVersion: v1
automountServiceAccountToken: false
kind: ServiceAccount
metadata:
name: alertmanager-main
namespace: monitoring
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: alertmanager-main
namespace: monitoring
spec:
endpoints:
- interval: 30s
port: web
- interval: 30s
port: reloader-web
selector:
matchLabels:
app.kubernetes.io/instance: main
app.kubernetes.io/name: alertmanager
还有一个 Prometheus 负责抓取这个 Alertmanager(以及之后部署的更多内容)。我们希望根据每秒抓取的样本进行扩展,因此我们将配置 Prometheus 来抓取自身
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: k8s
spec:
image: quay.io/prometheus/prometheus:v2.48.1
podMetadata:
labels:
app.kubernetes.io/instance: k8s
app.kubernetes.io/name: prometheus
shards: 1
serviceAccountName: prometheus-k8s
serviceMonitorSelector: {}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus-k8s
rules:
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- apiGroups:
- ""
resources:
- services
- endpoints
- pods
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus-k8s
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus-k8s
subjects:
- kind: ServiceAccount
name: prometheus-k8s
namespace: default
---
apiVersion: v1
kind: Service
metadata:
name: prometheus-k8s
labels:
app.kubernetes.io/instance: k8s
app.kubernetes.io/name: prometheus
spec:
ports:
- name: web
port: 9090
targetPort: web
- name: reloader-web
port: 8080
targetPort: reloader-web
selector:
app.kubernetes.io/instance: k8s
app.kubernetes.io/name: prometheus
---
apiVersion: v1
automountServiceAccountToken: true
kind: ServiceAccount
metadata:
name: prometheus-k8s
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: prometheus-k8s
spec:
endpoints:
- interval: 30s
port: web
- interval: 30s
port: reloader-web
selector:
matchLabels:
app.kubernetes.io/instance: k8s
app.kubernetes.io/name: prometheus
部署完所有内容后,我们可以通过暴露其 UI 来验证 Prometheus 的表现:
$ kubectl port-forward prometheus-k8s-0 9090
如果我们查询指标sum(rate(prometheus_tsdb_head_samples_appended_total[2m])),
我们会注意到我们稳定在每秒摄取 40~50 个样本左右。

配置 Keda 来扩展/缩小 Prometheus
Keda 的自动缩放对象是通过ScaledObject CRD配置的。 ScaledObjects 有大量不同的缩放器,但在这里我们将使用Prometheus 缩放器来缩放 Prometheus 本身。
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: prometheus
spec:
scaleTargetRef:
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
name: k8s
minReplicaCount: 1
maxReplicaCount: 100
fallback:
failureThreshold: 5
replicas: 10
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus-k8s.svc.default.cluster.local:9090
# Ingested samples per second across all shards
query: sum(rate(prometheus_tsdb_head_samples_appended_total[2m]))
# We'll scale up/down on every 200 samples ingested per second
threshold: '200'
要验证 ScaledObject 是否按预期工作,请运行:
$ kubectl get scaledobject prometheus
你应该看到这一点STATUS并且ACTIVE两者都应该是True。
触发扩缩容
现在让我们开始有趣的部分,首先增加 Alertmanager Pod 的数量:
$ kubectl patch alertmanager main -p '{"spec": {"replicas": 20}}' --type merge
在检查 Prometheus UI 时,我们会注意到摄取的样本快速增加:

如果我们检查 Prometheus Pod 的数量,我们会注意到正在部署新的分片:
$ kubectl get pods -l app.kubernetes.io/name=prometheus
NAME READY STATUS RESTARTS AGE
prometheus-k8s-0 2/2 Running 0 21m
prometheus-k8s-shard-1-0 2/2 Running 0 2m54s
prometheus-k8s-shard-2-0 2/2 Running 0 2m24s
prometheus-k8s-shard-3-0 1/2 Running 0 54s
我们还验证一下,如果负载减少,Prometheus Pod 是否会缩小规模
$ kubectl patch alertmanager main -p '{"spec": {"replicas": 1}}' --type merge
几分钟后,分片将返回较少数量的摄取样本,Keda 应再次调整分片数量:
$ kubectl get pods -l app.kubernetes.io/name=prometheus
NAME READY STATUS RESTARTS AGE
prometheus-k8s-0 2/2 Running 0 30m
其他
- https://www.arthursens.dev/posts/prometheus-shard-autoscaling
- https://keda.sh/docs/2.13/scalers/prometheus/#integrating-cloud-offerings
教你如何进行Prometheus 分片自动缩放的更多相关文章
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容
上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...
- JS自动缩放页面图片
/** * 缩略图 * * @param bool isScaling 是否缩放 * @param int width 宽度 * @param int height 高度 * @param strin ...
- Windows窗口自动缩放机制
通过自动缩放功能,能使在一个计算机上设计的界面在另一个具有不同分辨率或系统字体的计算机上能正常显示.这样窗体及其控件就能通过智能化调整大小以保障在本地电脑和用户电脑上保持一致. 自动缩放的必要性 如果 ...
- Android drawable的自动缩放
今天在写程序时发现,一张图片被自动放大了,后来发现,这张图片放在了drawable-zh文件夹下,这个文件夹没有指定屏幕密度!于是将drawable-zh改为drawable-zh-nodpi,问题解 ...
- Android代码中动态设置图片的大小(自动缩放),位置
项目中需要用到在代码中动态调整图片的位置和设置图片大小,能自动缩放图片,用ImageView控件,具体做法如下: 1.布局文件 <RelativeLayout xmlns:android=&qu ...
- 百度地图API 级别自动缩放
今天做一个基于百度地图API的小项目 查了很长时间apid都没有找到地图呈现出来的时候地图按坐标的多少自动缩放显示的等级比例,特此记录笔记!var points = [point1, point2,p ...
- Android Oreo 8.0 新特性实战 Autosizing TextView --自动缩放TextView
Android Oreo 8.0 新特性实战 Autosizing TextView --自动缩放TextView 8.0出来很久了,这个新特性已经用了很久了,但是一直没有亲自去试试.这几天新的需求来 ...
- arcgis for js 根据多边形自动缩放
交代背景:多边形已经渲染在图层上,然后根据多边形自动缩放值合适的大小: 思路:获取图层信息,获取图层中的几何信息,获取图形范围信息,在地图上设置范围:(下面的方法有封装)记一下思路就好 var pol ...
- html 网页背景图片根据屏幕大小CSS自动缩放
https://blog.csdn.net/coslay/article/details/47109281 腾讯微博和QQ空间的登录背景图片是根据访客的屏幕大小自动缩放的,但是好像是用JQuery代码 ...
- pageresponse.min.js自动缩放页面改写
/* * 名称 :移动端响应式框架 * 作者 :白树 http://peunzhang.cnblogs.com * 版本 :v2.1 * 日期 :2015.10.13 * 兼容 :ios 5+.and ...
随机推荐
- centos 定时任务
想法 看见一个别的项目,每天扒bing的背景,然后 生成个列表,然后数据就一天天的增加,创意非常好 有时间研究下 关键字 centos 定时任务 基于centos7系统定时任务创建 https://b ...
- function 的入参 如果是指针的话,如果你用的好的话,会颠覆三观啊 这里就是指对象,数组不用考虑 // 夏娃的苹果
function 的入参 如果是指针的话,如果你用的好的话,会颠覆三观啊 这里就是指对象,数组不用考虑 这就是一颗 夏娃的苹果
- C++数值类型与string、CString之间的转换
目录 数值范围 数值类型与string互相转换 数值类型转换为string 使用函数模板+ostringstream 使用标准库函数std::to_string() string转换为数值类型 使用函 ...
- [置顶]
java动态控制线程的启动和停止
最近项目有这样的需求:原来系统有个计算的功能,但该功能执行时间会很长(大概需要几个小时才能完成),如果执行过程中出现了错误的话,也只能默默的等待错误执行完成才行,无法做到动态的对该功能进行停止. 我了 ...
- Performance Improvements in .NET 8 & 7 & 6 -- Thread【翻译】
线程 .NET 的最近版本在线程.并行.并发和异步等方面做出了巨大的改进,例如 ThreadPool 的完全重写(在 .NET 6 和 .NET 7 中),异步方法基础设施的完全重写(在 .NET C ...
- 一天涨 23k Star 的开源项目「GitHub 热点速览」
在 GitHub 上做过开源项目的小伙伴,可能都经历过截图自己项目 100 Star.1000 Star 的时刻,但有些时候事情发生的太快来不及截图,因为可能一觉醒来就破万了.这件事看似有些天方夜谭 ...
- 记录--使用Lunchbox 在 vue3 中创建一个 3D 地球
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 什么是 Lunchbox.js Lunchbox.js 是 Three.js 的 Vue 3 自定义渲染器. 你可以把它想象成 Vue 的 ...
- 记录--微信调用jssdk全流程详解
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 微信调用jssdk全流程详解 系统框架使用的是前后端分离,前端使用vant,后端是springboot 一.网页授权的时序图 二.公众号配 ...
- 那位拿了多个Offer的大佬分享了最新Go面经
和大家分享一下我们 Go就业训练营 和 升职加薪星球 中战友们投稿的真实面经. 这是第一篇,计划还会再更新4篇最新Go面经,都是拿到Offer的那种! 欢迎大家关注我的账号,关注之后不迷路. 先秀战绩 ...
- 【Nginx】如何使用自签CA配置HTTPS加密反向代理访问?看了这篇我会了!!
写在前面 随着互联网的发展,很多公司和个人越来越重视网络的安全性,越来越多的公司采用HTTPS协议来代替了HTTP协议.为何说HTTPS协议比HTTP协议安全呢?小伙伴们自行百度吧!我就不说了.今天, ...