写点什么

教你如何进行 Prometheus 分片自动缩放

  • 2024-04-23
    广东
  • 本文字数:4268 字

    阅读完需:约 14 分钟

教你如何进行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 集群来说,这是一种非常常见的情况。在决定普罗米修斯碎片的数量时,我们如何找到成本/效益比的最佳点?


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


使用 Keda 自动缩放 Prometheus 碎片

设置


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


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


$ kind create clusterCreating 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/v1kind: Alertmanagermetadata:  name: main  namespace: monitoringspec:  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: v1kind: Servicemetadata:  name: alertmanager-main  namespace: monitoring  labels:    app.kubernetes.io/instance: main    app.kubernetes.io/name: alertmanagerspec:  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: v1automountServiceAccountToken: falsekind: ServiceAccountmetadata:  name: alertmanager-main  namespace: monitoring---apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata:  name: alertmanager-main  namespace: monitoringspec:  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/v1kind: Prometheusmetadata:  name: k8sspec:  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/v1kind: ClusterRolemetadata:  name: prometheus-k8srules:- 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/v1kind: ClusterRoleBindingmetadata:  name: prometheus-k8sroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: prometheus-k8ssubjects:- kind: ServiceAccount  name: prometheus-k8s  namespace: default---apiVersion: v1kind: Servicemetadata:  name: prometheus-k8s  labels:    app.kubernetes.io/instance: k8s    app.kubernetes.io/name: prometheusspec:  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: v1automountServiceAccountToken: truekind: ServiceAccountmetadata:  name: prometheus-k8s---apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata:  name: prometheus-k8sspec:  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/v1alpha1kind: ScaledObjectmetadata:  name: prometheusspec:  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=prometheusNAME                       READY   STATUS    RESTARTS   AGEprometheus-k8s-0           2/2     Running   0          21mprometheus-k8s-shard-1-0   2/2     Running   0          2m54sprometheus-k8s-shard-2-0   2/2     Running   0          2m24sprometheus-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=prometheusNAME               READY   STATUS    RESTARTS   AGEprometheus-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


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

发布于: 7 小时前阅读数: 11
用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

生于云,长于云,让开发者成为决定性力量

评论

发布
暂无评论
教你如何进行Prometheus 分片自动缩放_开发_华为云开发者联盟_InfoQ写作社区