找回密码
 立即注册
首页 业界区 业界 抽丝剥茧--从零开始建设k8s监控之水平拆分(五) ...

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

百里宵月 11 小时前
前言

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

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

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

1.png

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

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

这个拆分是显而易见的,不同的namespace采集进入不同的prometheus即可,配置也很简单,只需要修改kube-state-metrics的启动参数即可
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4.   name: kube-state-metrics
  5.   namespace: kube-system
  6. spec:
  7.   replicas: 1
  8.   selector:
  9.     matchLabels:
  10.       app: kube-state-metrics
  11.   template:
  12.     metadata:
  13.       labels:
  14.         app: kube-state-metrics
  15.     spec:
  16.       serviceAccountName: kube-state-metrics
  17.       containers:
  18.       - args:
  19.         - --metric-labels-allowlist=pods=[*]
  20.         - --metric-annotations-allowlist=pods=[*]
  21.         - --namespaces=default # 新增
  22.         name: kube-state-metrics
  23.         image: registry.cn-beijing.aliyuncs.com/wilsonchai/kube-state-metrics:v2.13.0
  24.         ports:
  25.         - containerPort: 8080
复制代码
--namespaces=default 告诉kube-state-metrics只采集namespace为default的数据
2.png

创建多个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
  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: Role
  3. metadata:
  4.   labels:
  5.     app.kubernetes.io/name: kube-state-metrics
  6.     app.kubernetes.io/version: v2.13.0
  7.   name: kube-state-metrics
  8.   namespace: kube-system
  9. rules:
  10. - apiGroups:
  11.   - ""
  12.   resources:
  13.   - pods
  14.   verbs:
  15.   - get
  16. - apiGroups:
  17.   - apps
  18.   resourceNames:
  19.   - kube-state-metrics
  20.   resources:
  21.   - statefulsets
  22.   verbs:
  23.   - get
  24. ---
  25. apiVersion: rbac.authorization.k8s.io/v1
  26. kind: RoleBinding
  27. metadata:
  28.   labels:
  29.     app.kubernetes.io/name: kube-state-metrics
  30.     app.kubernetes.io/version: v2.13.0
  31.   name: kube-state-metrics
  32.   namespace: kube-system
  33. roleRef:
  34.   apiGroup: rbac.authorization.k8s.io
  35.   kind: Role
  36.   name: kube-state-metrics
  37. subjects:
  38. - kind: ServiceAccount
  39.   name: kube-state-metrics
  40. ---
  41. apiVersion: apps/v1
  42. kind: StatefulSet
  43. metadata:
  44.   labels:
  45.     app.kubernetes.io/name: kube-state-metrics
  46.     app.kubernetes.io/version: v2.13.0
  47.   name: kube-state-metrics
  48.   namespace: kube-system
  49. spec:
  50.   replicas: 2
  51.   selector:
  52.     matchLabels:
  53.       app.kubernetes.io/name: kube-state-metrics
  54.   serviceName: kube-state-metrics
  55.   template:
  56.     metadata:
  57.       labels:
  58.         app.kubernetes.io/name: kube-state-metrics
  59.         app.kubernetes.io/version: v2.13.0
  60.     spec:
  61.       containers:
  62.       - args:
  63.         - --pod=$(POD_NAME)
  64.         - --pod-namespace=$(POD_NAMESPACE)
  65.         env:
  66.         - name: POD_NAME
  67.           valueFrom:
  68.             fieldRef:
  69.               fieldPath: metadata.name
  70.         - name: POD_NAMESPACE
  71.           valueFrom:
  72.             fieldRef:
  73.               fieldPath: metadata.namespace
  74.         image: registry.cn-beijing.aliyuncs.com/wilsonchai/kube-state-metrics:v2.13.0
  75.         livenessProbe:
  76.           httpGet:
  77.             path: /healthz
  78.             port: 8080
  79.           initialDelaySeconds: 5
  80.           timeoutSeconds: 5
  81.         name: kube-state-metrics
  82.         ports:
  83.         - containerPort: 8080
  84.           name: http-metrics
  85.         - containerPort: 8081
  86.           name: telemetry
  87.         readinessProbe:
  88.           httpGet:
  89.             path: /
  90.             port: 8081
  91.           initialDelaySeconds: 5
  92.           timeoutSeconds: 5
  93.         securityContext:
  94.           runAsUser: 65534
  95.       nodeSelector:
  96.         kubernetes.io/os: linux
  97.       serviceAccountName: kube-state-metrics
复制代码
启动起来之后检查一下metrics的指标数量
  1. ▶ curl -s 10.244.0.107:8080/metrics | wc -l
  2. 949
  3. ▶ curl -s 10.244.0.108:8080/metrics | wc -l
  4. 909
复制代码
看起来已经打散到2个节点去了,如果我再增加一个节点,那指标数量又分散了
  1. ▶ curl -s 10.244.0.107:8080/metrics | wc -l
  2. 702
  3. ▶ curl -s 10.244.0.108:8080/metrics | wc -l
  4. 733
  5. ▶ curl -s 10.244.0.109:8080/metrics | wc -l
  6. 663
复制代码
这时候只需要把不同的prometheus配置采集不同kube-state-metrics即可,架构也变成了这个样子
3.png

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

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

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


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


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


  • 联系我,做深入的交流
5.bmp

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

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册