教你如何进行Prometheus 分片自动缩放 - 华为云开发者联盟
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 查询功能。
整个时间内负载不均匀
我们已经通过使用分片而不是垂直扩展 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
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK