0

教你如何进行Prometheus 分片自动缩放 - 华为云开发者联盟

 1 month ago
source link: https://www.cnblogs.com/huaweiyun/p/18152120
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文分享自华为云社区《使用 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 查询功能。

1713776614765100303.png

整个时间内负载不均匀

我们已经通过使用分片而不是垂直扩展 Prometheus 取得了一些重大进展,但是当暴露的指标数量全天增加和减少时会发生什么?对于每天从数百个节点扩展到数千个节点(反之亦然)的 Kubernetes 集群来说,这是一种非常常见的情况。在决定普罗米修斯碎片的数量时,我们如何找到成本/效益比的最佳点?

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

1713776575167903411.png

使用 Keda 自动缩放 Prometheus 碎片

使用 Kubernetes Scale API 的任何类型的 Horizo​​ntal 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 个样本左右。

1713776644746781627.png

配置 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 时,我们会注意到摄取的样本快速增加:

1713776659254515672.png

如果我们检查 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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK