百里宵月 发表于 2025-7-21 08:42:08

抽丝剥茧--从零开始建设k8s监控之水平拆分(五)

前言

书接上文,经过之前的不懈努力,我们已经有了较为完善的监控系统与告警系统,而prometheus的工作模式就像一个单点,拉取数据回来之后存储在自己的磁盘上
当监控数据越来越多,那prometheus单点的压力就会变大,那本文就来讨论一下如何降低单点prometheus的压力
环境准备

组件版本操作系统Ubuntu 22.04.4 LTSdocker24.0.7kube-state-metricsv2.13.0thanos0.36.1水平拆分

水平拆分的目的就是为了拆成多个prometheus,让单个prometheus负载降低,不要这么容易挂掉,并且拆成多个之后,就算挂掉一个,其余的也可以正常工作。比如一个prometheus专门负责节点监控数据采集、一个prometheus专门负责k8s监控数据采集等
1. 根据采集的目标进行拆分


每个业务都有一个prometheus对其进行采集,并且不同prometheus之间解耦
这时候业务部门提出需求,k8s的监控还是太多了,一个prometheus依然不堪重负,那怎么办呢?
2. kube-state-metrics拆分

由于k8s是通过kube-state-metrics这个exporter进行采集,所以我们需要对其进行拆分
2.1 根据namespace进行拆分

这个拆分是显而易见的,不同的namespace采集进入不同的prometheus即可,配置也很简单,只需要修改kube-state-metrics的启动参数即可
apiVersion: apps/v1
kind: Deployment
metadata:
name: kube-state-metrics
namespace: kube-system
spec:
replicas: 1
selector:
    matchLabels:
      app: kube-state-metrics
template:
    metadata:
      labels:
      app: kube-state-metrics
    spec:
      serviceAccountName: kube-state-metrics
      containers:
      - args:
      - --metric-labels-allowlist=pods=[*]
      - --metric-annotations-allowlist=pods=[*]
      - --namespaces=default # 新增
      name: kube-state-metrics
      image: registry.cn-beijing.aliyuncs.com/wilsonchai/kube-state-metrics:v2.13.0
      ports:
      - containerPort: 8080--namespaces=default 告诉kube-state-metrics只采集namespace为default的数据

创建多个prometheus以及kube-state-metrics,然后指定采集不同的namespace
这种方法配置简单,但是分配多个kube-state-metrics的采集策略就比较复杂,一旦业务复杂,namespace多起来之后,也会造成频繁修改配置,还有没有更简单的方法呢?
2.2 kube-state-metrics根据shard拆分

在kube-state-metrics的高版本(具体是哪个版本待查,笔者的版本是v2.13.0),支持了自动分片的采集策略,就是让多个kube-state-metrics自己去分片,省去人为配置的烦恼
关于水平分片的例子,可以参考 kube-state-metrics
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
    app.kubernetes.io/name: kube-state-metrics
    app.kubernetes.io/version: v2.13.0
name: kube-state-metrics
namespace: kube-system
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- apps
resourceNames:
- kube-state-metrics
resources:
- statefulsets
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
    app.kubernetes.io/name: kube-state-metrics
    app.kubernetes.io/version: v2.13.0
name: kube-state-metrics
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kube-state-metrics
subjects:
- kind: ServiceAccount
name: kube-state-metrics
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
    app.kubernetes.io/name: kube-state-metrics
    app.kubernetes.io/version: v2.13.0
name: kube-state-metrics
namespace: kube-system
spec:
replicas: 2
selector:
    matchLabels:
      app.kubernetes.io/name: kube-state-metrics
serviceName: kube-state-metrics
template:
    metadata:
      labels:
      app.kubernetes.io/name: kube-state-metrics
      app.kubernetes.io/version: v2.13.0
    spec:
      containers:
      - args:
      - --pod=$(POD_NAME)
      - --pod-namespace=$(POD_NAMESPACE)
      env:
      - name: POD_NAME
          valueFrom:
            fieldRef:
            fieldPath: metadata.name
      - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
            fieldPath: metadata.namespace
      image: registry.cn-beijing.aliyuncs.com/wilsonchai/kube-state-metrics:v2.13.0
      livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 5
          timeoutSeconds: 5
      name: kube-state-metrics
      ports:
      - containerPort: 8080
          name: http-metrics
      - containerPort: 8081
          name: telemetry
      readinessProbe:
          httpGet:
            path: /
            port: 8081
          initialDelaySeconds: 5
          timeoutSeconds: 5
      securityContext:
          runAsUser: 65534
      nodeSelector:
      kubernetes.io/os: linux
      serviceAccountName: kube-state-metrics启动起来之后检查一下metrics的指标数量
▶ curl -s 10.244.0.107:8080/metrics | wc -l
949
▶ curl -s 10.244.0.108:8080/metrics | wc -l
909看起来已经打散到2个节点去了,如果我再增加一个节点,那指标数量又分散了
▶ curl -s 10.244.0.107:8080/metrics | wc -l
702
▶ curl -s 10.244.0.108:8080/metrics | wc -l
733
▶ curl -s 10.244.0.109:8080/metrics | wc -l
663这时候只需要把不同的prometheus配置采集不同kube-state-metrics即可,架构也变成了这个样子

当然kube-state-metrics也是有手动分片模式的,就是通过参数--shard来实现了,只不过有自动分片的话,没有极致特殊的需求,我们还是用自动分片来处理更加合适
多prometheus数据汇聚

当我们拆分了监控数据,用不同的prometheus来采集的时候,又带来了新的问题

[*]由于prometheus使用本地磁盘存储数据,所以通过prometheus的web界面查看监控数据时,也只能查看到本prometheus的监控数据,不能跨prometheus查询监控数据
[*]使用grafana添加数据源的时候,就出现了多prometheus数据源的情况,造成管理复杂


[*]有一个公共的storage组件,prometheus通过remote_write的方式,把数据汇聚在这个组件,就可以解决数据分散的问题,并且数据存储的方式就很灵活了,可以存储在本地,然后通过传统的raid做数据备份,也可以直接通过云 平台的对象存储保存历史数据
[*]最后再来一个统一的web界面进行查询,同时这个web界面兼容了prometheus的promQL,并且兼容了prometheus的api,可以直接作为数据源添加至grafana中
[*]有这种功能的组件就很多了,比如thanos、cortext、influxDB等等,都可以完成这个工作
小结


[*]下一小节,通过thanos来详细讨论一下怎么做数据汇聚
联系我


[*]联系我,做深入的交流

至此,本文结束
在下才疏学浅,有撒汤漏水的,请各位不吝赐教...

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 抽丝剥茧--从零开始建设k8s监控之水平拆分(五)