Prometheus 的新战场:精准监控阿里云 AKS Serverless 集群

文摘   2025-01-14 21:50   挪威  

 


Kaiserstuhl, Swtizerland

引言

我们紧接着上篇的 PromQL,接着往上盖大楼。这篇我们的主角是 Prometheus-Operator 的 Prometheus,它的重要性就不言而喻了。

Prometheus-Operator 是 Kubernetes 生态中广泛应用的监控组件,能够简化 Prometheus 的部署和管理。然而,随着云原生技术的发展,监控阿里云 AKS Serverless 集群成为了一个新的挑战。这些服务本质上是无服务器的,无法通过传统的节点指标采集方式进行监控。因此,我们需要对 Prometheus 自身进行调整,以更好地适配阿里云 AKS Serverless 场景。

本文将探讨如何通过重塑 Prometheus ,使其高效监控阿里云 AKS Serverless 环境。

开始

基本设计

prometheus-operator 的控制链路其实非常简单,我们只需要知道以下基本原理就行:

  • • PodMonitor 和 ServiceMonitor 最终是用于生成 Prometheus 配置文件中的 srape_config
  • • Prometheus 可以使用一个 HTTP Post 请求 /-/reload 来在运行时重新加载配置文件使新的 scrape_config 生效;

以上文为例,prometheus-operator 的控制链路是:

Prometheus

prometheus-operator 监听 Promtheus 资源,当有 Add Event 发生时,prometheus-operator 将以 StatefulSet 的形式部署 Prometheus 实例。每一个 Prometheus Pod 里有两个容器:

  • • prometheus 容器:主容器,使用 /etc/prometheus/config_out/prometheus.env.yaml 作为主要的配置文件:
...
    - --config.file=/etc/prometheus/config_out/prometheus.env.yaml 
... 
  • • prometheus-config-reloader 容器:辅助容器,用于监听上游配置文件的变化并调用主容器的 reload 接口重新加载配置;

当我们观察这个 Pod 的 volumes 时候,有两个 volume 可以重点关注:

...
volumes:
  - name: config
    secret:
      defaultMode: 420
      secretName: prom-agent-prometheus-agent
  - name: config-out
    emptyDir:
      medium: Memory
...
  • • config-outEmptyDir 类型的卷,主要是用于 prometheus 容器与 prometheus-config-reloader 容器的数据共享,同时挂载于两个容器的 /etc/prometheus/config_out/ 中;
  • • config:底层是一个 Secret,这个 config 将被挂载为 prometheus-config-reloader 容器中的 /etc/prometheus/config/prometheus.yaml.gz 。 prometheus-config-reloader 会监听这个文件的变化,一旦有变化,将基于新的文件内容生成新的配置文件 /etc/prometheus/config_out/prometheus.env.yaml。 prometheus-config-reloader 将调用主容器的 reload API 来重新加载配置文件;

PodMonitor / ServiceMonitor

  • • prometheus-operator 监听 PodMonitor 和 ServiceMonitor 的变化。一旦对应资源发生了变化,prometheus-operator 将基于新的资源生成新的配置文件并将其更新到对应的 Secrets 中。由于对应 Secrets 以文件形式挂载于 prometheus-config-reloader 容器中并被监听文件变化,所以当底层 Secrets 发生了变化,kubelet 将分钟级传播变化到对应容器内部,从而触发 prometheus-config-reloader 容器内的监听逻辑。
  • • Secrets 内部是一个 Base64 之后的 gz 格式的 prometheus.yaml,比如我们可以用下面这种方式解码出 prometheus.yaml:
kubectl get secrets prometheus-k8s -o jsonpath="{.data.prometheus\.yaml\.gz}" | base64 -d > prometheus.yaml.gz 

gzip -d prometheus.yaml.gz

我们这些了解完成之后,对于我们后面的改进可谓是……语文不好,有点丢人,想不出来成语了。

Prometheus CRD YAML 优化

我们先从 Prometheus 的持久化数据说起:

  storage:
    volumeClaimTemplate:
      spec:
        storageClassName: alicloud-nas-subpath
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 15Gi

本地存储优化

启用 WAL 压缩

  wal_compression: true

减少数据保留时间

  retention: 7d

还有我们资源的优化,如果你的集群应用很多,资源太少,就会导致 pod 异常,这边你自己调整:

  resources:
    limits:
      cpu: "3"
      memory: 3Gi
    requests:
      cpu: 1000m
      memory: 1024Mi

完整文件

apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  labels:
    app.kubernetes.io/component: prometheus
    app.kubernetes.io/instance: k8s
    app.kubernetes.io/name: prometheus
    app.kubernetes.io/part-of: kube-prometheus
    app.kubernetes.io/version: 3.0.1
  name: k8s
  namespace: monitoring
spec:
  alerting:
    alertmanagers:
    - apiVersion: v2
      name: alertmanager-main
      namespace: monitoring
      port: web
  enableFeatures: []
  storage:
    volumeClaimTemplate:
      spec:
        storageClassName: alicloud-nas-subpath
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 15Gi
  externalLabels: {}
  image: quay.io/prometheus/prometheus:v3.0.1
  nodeSelector:
    kubernetes.io/os: linux
  podMetadata:
    labels:
      app.kubernetes.io/component: prometheus
      app.kubernetes.io/instance: k8s
      app.kubernetes.io/name: prometheus
      app.kubernetes.io/part-of: kube-prometheus
      app.kubernetes.io/version: 3.0.1
  podMonitorNamespaceSelector: {}
  #  matchExpressions:
  #    - key: kubernetes.io/metadata.name
  #      operator: In
  #      values:
  #        - monitoring
  #        - lobby
  podMonitorSelector: {}
  probeNamespaceSelector: {}
  probeSelector: {}
  replicas: 2
  resources:
    limits:
      cpu: "5"
      memory: 5Gi
    requests:
      cpu: 2000m
      memory: 2048Mi
  ruleNamespaceSelector: {}
  ruleSelector: {}
  scrapeConfigNamespaceSelector: {}
  scrapeConfigSelector: {}
  securityContext:
    fsGroup: 2000
    runAsNonRoot: true
    runAsUser: 1000
  serviceAccountName: prometheus-k8s
  serviceMonitorSelector: {}
  serviceMonitorNamespaceSelector: {}
  #  matchExpressions:
  #    - key: kubernetes.io/metadata.name
  #      operator: In
  #      values:
  #        - monitoring
  #        - lobby
  version: 3.0.1
  retention: 15d
  wal_compression: true

扩展

因为 Prometheus 这边优化的还挺多的,所以我们这一篇就先讲到这里,后面我们会更多的剖析相关内容。

  • • Prometheus Agent
  • • PrometheusRule

结语

我们 Prometheus 基础的优化和改进就结束了,相比较前几篇,这篇的东西不是很多。其实还有很多的东西都需要讲,我会把它们给分开。


云原生SRE
懂点K8S的SRE,关注云原生、DevOps、AI\x26amp;ChatGPT等技术热点
 最新文章