本文分享自华为云社区《使用 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 集群来说,这是一种非常常见的情况。在决定普罗米修斯碎片的数量时,我们如何找到成本/效益比的最佳点?

您可以每天手动微调集群中的分片数量,但有更智能的方法来完成此任务。在这篇博文中,我将重点介绍 Horizo​​ntal Pod Autoscaler 策略,该策略是最近通过 Prometheus-Operator v0.71.0 版本实现的。

使用 Keda 自动缩放 Prometheus 碎片

设置

使用 Kubernetes Scale API 的任何类型的 Horizo​​ntal Pod Autoscaler,但出于演示目的,将使用Keda,它支持多种扩展策略。

让我们从创建一个小型集群开始,我建议使用KinD或Minikube:

  1. $ kind create cluster
  2. Creating cluster "kind" ...
  3. Ensuring node image (kindest/node:v1.27.1)
  4. Preparing nodes
  5. Writing configuration
  6. Starting control-plane
  7. Installing CNI
  8. Installing StorageClass
  9. Set kubectl context to "kind-kind"
  10. You can now use your cluster with:
  11.  
  12. kubectl cluster-info --context kind-kind
  13.  
  14. Have a nice day!

现在让我们安装 Keda:

  1. $ helm repo add kedacore https://kedacore.github.io/charts
  2. $ helm repo update
  3. $ helm install keda kedacore/keda --namespace keda --create-namespace
  4. $ watch kubectl get pods -n keda

一旦所有 Pod 都达到该Running状态,我们就可以继续!下一步是安装 Prometheus Operator:

  1. $ git clone https://github.com/prometheus-operator/prometheus-operator
  2. $ cd prometheus-operator
  3. $ kubectl apply --server-side -f bundle.yaml

部署 Prometheus 和示例应用程序

好了,初始设置完成了。让我们部署一些公开一些指标的应用程序!为了演示目的,让我们部署一个 Alertmanager:

  1. ---
  2. apiVersion: monitoring.coreos.com/v1
  3. kind: Alertmanager
  4. metadata:
  5. name: main
  6. namespace: monitoring
  7. spec:
  8. image: quay.io/prometheus/alertmanager:v0.26.0
  9. podMetadata:
  10. labels:
  11. app.kubernetes.io/instance: main
  12. app.kubernetes.io/name: alertmanager
  13. replicas: 1
  14. serviceAccountName: alertmanager-main
  15. ---
  16. apiVersion: v1
  17. kind: Service
  18. metadata:
  19. name: alertmanager-main
  20. namespace: monitoring
  21. labels:
  22. app.kubernetes.io/instance: main
  23. app.kubernetes.io/name: alertmanager
  24. spec:
  25. ports:
  26. - name: web
  27. port: 9093
  28. targetPort: web
  29. - name: reloader-web
  30. port: 8080
  31. targetPort: reloader-web
  32. selector:
  33. app.kubernetes.io/instance: main
  34. app.kubernetes.io/name: alertmanager
  35. ---
  36. apiVersion: v1
  37. automountServiceAccountToken: false
  38. kind: ServiceAccount
  39. metadata:
  40. name: alertmanager-main
  41. namespace: monitoring
  42. ---
  43. apiVersion: monitoring.coreos.com/v1
  44. kind: ServiceMonitor
  45. metadata:
  46. name: alertmanager-main
  47. namespace: monitoring
  48. spec:
  49. endpoints:
  50. - interval: 30s
  51. port: web
  52. - interval: 30s
  53. port: reloader-web
  54. selector:
  55. matchLabels:
  56. app.kubernetes.io/instance: main
  57. app.kubernetes.io/name: alertmanager

还有一个 Prometheus 负责抓取这个 Alertmanager(以及之后部署的更多内容)。我们希望根据每秒抓取的样本进行扩展,因此我们将配置 Prometheus 来抓取自身

  1. apiVersion: monitoring.coreos.com/v1
  2. kind: Prometheus
  3. metadata:
  4. name: k8s
  5. spec:
  6. image: quay.io/prometheus/prometheus:v2.48.1
  7. podMetadata:
  8. labels:
  9. app.kubernetes.io/instance: k8s
  10. app.kubernetes.io/name: prometheus
  11. shards: 1
  12. serviceAccountName: prometheus-k8s
  13. serviceMonitorSelector: {}
  14. ---
  15. apiVersion: rbac.authorization.k8s.io/v1
  16. kind: ClusterRole
  17. metadata:
  18. name: prometheus-k8s
  19. rules:
  20. - apiGroups:
  21. - ""
  22. resources:
  23. - configmaps
  24. verbs:
  25. - get
  26. - apiGroups:
  27. - ""
  28. resources:
  29. - services
  30. - endpoints
  31. - pods
  32. verbs:
  33. - get
  34. - list
  35. - watch
  36. - apiGroups:
  37. - extensions
  38. resources:
  39. - ingresses
  40. verbs:
  41. - get
  42. - list
  43. - watch
  44. - apiGroups:
  45. - networking.k8s.io
  46. resources:
  47. - ingresses
  48. verbs:
  49. - get
  50. - list
  51. - watch
  52. ---
  53. apiVersion: rbac.authorization.k8s.io/v1
  54. kind: ClusterRoleBinding
  55. metadata:
  56. name: prometheus-k8s
  57. roleRef:
  58. apiGroup: rbac.authorization.k8s.io
  59. kind: ClusterRole
  60. name: prometheus-k8s
  61. subjects:
  62. - kind: ServiceAccount
  63. name: prometheus-k8s
  64. namespace: default
  65. ---
  66. apiVersion: v1
  67. kind: Service
  68. metadata:
  69. name: prometheus-k8s
  70. labels:
  71. app.kubernetes.io/instance: k8s
  72. app.kubernetes.io/name: prometheus
  73. spec:
  74. ports:
  75. - name: web
  76. port: 9090
  77. targetPort: web
  78. - name: reloader-web
  79. port: 8080
  80. targetPort: reloader-web
  81. selector:
  82. app.kubernetes.io/instance: k8s
  83. app.kubernetes.io/name: prometheus
  84. ---
  85. apiVersion: v1
  86. automountServiceAccountToken: true
  87. kind: ServiceAccount
  88. metadata:
  89. name: prometheus-k8s
  90. ---
  91. apiVersion: monitoring.coreos.com/v1
  92. kind: ServiceMonitor
  93. metadata:
  94. name: prometheus-k8s
  95. spec:
  96. endpoints:
  97. - interval: 30s
  98. port: web
  99. - interval: 30s
  100. port: reloader-web
  101. selector:
  102. matchLabels:
  103. app.kubernetes.io/instance: k8s
  104. app.kubernetes.io/name: prometheus

部署完所有内容后,我们可以通过暴露其 UI 来验证 Prometheus 的表现:

  1. $ 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 本身。

  1. apiVersion: keda.sh/v1alpha1
  2. kind: ScaledObject
  3. metadata:
  4. name: prometheus
  5. spec:
  6. scaleTargetRef:
  7. apiVersion: monitoring.coreos.com/v1
  8. kind: Prometheus
  9. name: k8s
  10. minReplicaCount: 1
  11. maxReplicaCount: 100
  12. fallback:
  13. failureThreshold: 5
  14. replicas: 10
  15. triggers:
  16. - type: prometheus
  17. metadata:
  18. serverAddress: http://prometheus-k8s.svc.default.cluster.local:9090
  19. # Ingested samples per second across all shards
  20. query: sum(rate(prometheus_tsdb_head_samples_appended_total[2m]))
  21. # We'll scale up/down on every 200 samples ingested per second
  22. threshold: '200'

要验证 ScaledObject 是否按预期工作,请运行:

  1. $ kubectl get scaledobject prometheus

你应该看到这一点STATUS并且ACTIVE两者都应该是True

触发扩缩容

现在让我们开始有趣的部分,首先增加 Alertmanager Pod 的数量:

  1. $ kubectl patch alertmanager main -p '{"spec": {"replicas": 20}}' --type merge

在检查 Prometheus UI 时,我们会注意到摄取的样本快速增加:

如果我们检查 Prometheus Pod 的数量,我们会注意到正在部署新的分片:

  1. $ kubectl get pods -l app.kubernetes.io/name=prometheus
  2. NAME READY STATUS RESTARTS AGE
  3. prometheus-k8s-0 2/2 Running 0 21m
  4. prometheus-k8s-shard-1-0 2/2 Running 0 2m54s
  5. prometheus-k8s-shard-2-0 2/2 Running 0 2m24s
  6. prometheus-k8s-shard-3-0 1/2 Running 0 54s

我们还验证一下,如果负载减少,Prometheus Pod 是否会缩小规模

  1. $ kubectl patch alertmanager main -p '{"spec": {"replicas": 1}}' --type merge

几分钟后,分片将返回较少数量的摄取样本,Keda 应再次调整分片数量:

  1. $ kubectl get pods -l app.kubernetes.io/name=prometheus
  2. NAME READY STATUS RESTARTS AGE
  3. prometheus-k8s-0 2/2 Running 0 30m

其他

点击关注,第一时间了解华为云新鲜技术~

教你如何进行Prometheus 分片自动缩放的更多相关文章

  1. 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容

    上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...

  2. JS自动缩放页面图片

    /** * 缩略图 * * @param bool isScaling 是否缩放 * @param int width 宽度 * @param int height 高度 * @param strin ...

  3. Windows窗口自动缩放机制

    通过自动缩放功能,能使在一个计算机上设计的界面在另一个具有不同分辨率或系统字体的计算机上能正常显示.这样窗体及其控件就能通过智能化调整大小以保障在本地电脑和用户电脑上保持一致. 自动缩放的必要性 如果 ...

  4. Android drawable的自动缩放

    今天在写程序时发现,一张图片被自动放大了,后来发现,这张图片放在了drawable-zh文件夹下,这个文件夹没有指定屏幕密度!于是将drawable-zh改为drawable-zh-nodpi,问题解 ...

  5. Android代码中动态设置图片的大小(自动缩放),位置

    项目中需要用到在代码中动态调整图片的位置和设置图片大小,能自动缩放图片,用ImageView控件,具体做法如下: 1.布局文件 <RelativeLayout xmlns:android=&qu ...

  6. 百度地图API 级别自动缩放

    今天做一个基于百度地图API的小项目 查了很长时间apid都没有找到地图呈现出来的时候地图按坐标的多少自动缩放显示的等级比例,特此记录笔记!var points = [point1, point2,p ...

  7. Android Oreo 8.0 新特性实战 Autosizing TextView --自动缩放TextView

    Android Oreo 8.0 新特性实战 Autosizing TextView --自动缩放TextView 8.0出来很久了,这个新特性已经用了很久了,但是一直没有亲自去试试.这几天新的需求来 ...

  8. arcgis for js 根据多边形自动缩放

    交代背景:多边形已经渲染在图层上,然后根据多边形自动缩放值合适的大小: 思路:获取图层信息,获取图层中的几何信息,获取图形范围信息,在地图上设置范围:(下面的方法有封装)记一下思路就好 var pol ...

  9. html 网页背景图片根据屏幕大小CSS自动缩放

    https://blog.csdn.net/coslay/article/details/47109281 腾讯微博和QQ空间的登录背景图片是根据访客的屏幕大小自动缩放的,但是好像是用JQuery代码 ...

  10. pageresponse.min.js自动缩放页面改写

    /* * 名称 :移动端响应式框架 * 作者 :白树 http://peunzhang.cnblogs.com * 版本 :v2.1 * 日期 :2015.10.13 * 兼容 :ios 5+.and ...

随机推荐

  1. obs 屏幕录像 1. 屏幕放大缩小 2. 圆形摄像头

    obs 屏幕录像 1. 屏幕放大缩小 2. 圆形摄像头 屏幕放大缩小 windows 放大镜 屏幕放大快捷键 win + '+' 是放大屏幕 win + '-' 是缩小屏幕 因为obs不支持缩放功能, ...

  2. k8s安全之Network Policy

    K8s Network Policy 是一种资源,它用于在 Pod 之间以及从其他网络实体到 Pod 的通信中进行网络级别的访问控制.它允许您定义一组规则,这些规则可以指定允许或拒绝网络流量. 具体来 ...

  3. 前后端分离之jQuery入门

    jQuery入门 基本概念:jQuery是一个快速,小型且功能丰富的JavaScript库.借助易于使用的API(可在多种浏览器中使用),使HTML文档的遍历和操作,事件处理,动画和Ajax等事情变得 ...

  4. FAT32 文件系统详解

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  5. apache的安装和修改端口号

    实验介绍: apache(阿帕奇)是最流行的web服务器端软件 一:下载apache服务器 1进入官网https://httpd.apache.org/download.cgi 选择最新版本 2选择w ...

  6. Mysql访问问题,远程连接提示:Host 'xxx' is not allowed to connect to this MySQL server。是mysql未开启mysql远程访问权限导致

    1.MySql服务器共享问题 对于在车间工作者,如果远程Mysql,我们这里假定网线连接 GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.1.3' IDE ...

  7. vue初学核心基础02

    8.v-bind补充 8.1v-bind绑定类名 v-bind指令给"任意标签"的"任意属性"绑定数据 对于大部分的属性而言我们只需要直接赋值即可, 例如:va ...

  8. Oracle 备份 还原 导入 导出 数据库

    导出数据 SQL> conn / as sysdba Connected. SQL> create directory lxw_dir as '/home/oracle'; Directo ...

  9. verilog基本语法之always和assign

    always和assign的作用 一.语法定义 assign,连续赋值.always,敏感赋值.连续赋值,就是无条件全等.敏感赋值,就是有条件相等.assign的对象是wire,always的对象是r ...

  10. UE4中的GamePlay模块

    链接 该文档主要通过学习自己构建文件,形成GamePlay模块.下图是利用引擎创建的一个空模板C++代码结构 简要流程 UBT 虚幻编译工具(UBT:Unreal Build Tool)是一个自定义工 ...