找回密码
 立即注册
首页 业界区 业界 返璞归真--从零开始建设k8s监控之thanos-sidecar(七) ...

返璞归真--从零开始建设k8s监控之thanos-sidecar(七)

馑妣窟 昨天 10:18
前言

本文详细讨论一下thanos-sidecar
环境准备

组件版本操作系统Ubuntu 22.04.4 LTSdocker24.0.7thanos0.36.1thanos概述

thanos主要有4个组件

  • receive:独立部署,提供了数据写入的api,prometheus通过这个api把数据推送到receive的对象存储
  • sidecar:与prometheus部署在一起,成为prometheus的sidecar,负责把prometheus本地的数据上传至对象存储当中
  • query:独立部署,是一个兼容了prometheus的查询组件,汇总了来自不同来源的查询结果,并且可以从Sidecar和Store中读取数据
  • store:独立部署,提供了对象数据存储功能,并且提供相关的api,query通过该api查询历史数据
sidecar模式

Sidecar 与prometheus绑定在一起,负责处理与其绑定的prometheus各种监控数据的处理
1.png

1. k8s安装sidecar

1.1 改造prometheus configmap

加入重要的external label
  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4.   name: prometheus-cm
  5.   labels:
  6.     name: prometheus-cm
  7.   namespace: prometheus
  8. data:
  9.   prometheus.yml: |-
  10.     global:
  11.       scrape_interval: 5s
  12.       evaluation_interval: 5s
  13.       # 新增外部标签
  14.       external_labels:
  15.         cluster: "prometheus-k8s"
  16.       # 新增结束
  17.     scrape_configs:
  18.       - job_name: 'prometheus'
  19.         static_configs:
  20.         - targets: ['localhost:9090']
  21.       - job_name: "prometheus-kube-state-metrics"
  22.         static_configs:
  23.           - targets: ["kube-state-metrics.kube-system:8080"]
复制代码
1.2 改造prometheus deployment

加入thanos sidecar
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4.   name: prometheus-deploy
  5.   namespace: prometheus
  6.   labels:
  7.     app: prometheus
  8. spec:
  9.   replicas: 1
  10.   selector:
  11.     matchLabels:
  12.       app: prometheus
  13.   template:
  14.     metadata:
  15.       labels:
  16.         app: prometheus
  17.     spec:
  18.       containers:
  19.         - name: prometheus
  20.           image: registry.cn-beijing.aliyuncs.com/wilsonchai/prometheus:v2.54.1
  21.           args:
  22.             - "--storage.tsdb.retention.time=12h"
  23.             - "--config.file=/etc/prometheus/prometheus.yml"
  24.             - "--storage.tsdb.path=/prometheus/"
  25.             - "--storage.tsdb.min-block-duration=30m"
  26.             - "--storage.tsdb.max-block-duration=30m"
  27.             - --web.enable-lifecycle
  28.           ports:
  29.             - containerPort: 9090
  30.           resources:
  31.             requests:
  32.               cpu: 500m
  33.               memory: 500M
  34.             limits:
  35.               cpu: 1
  36.               memory: 1Gi
  37.           volumeMounts:
  38.             - name: prometheus-config
  39.               mountPath: /etc/prometheus/
  40.             - name: prometheus-data
  41.               mountPath: /prometheus
  42.         # 新增thanos-sidecar
  43.         - name: thanos
  44.           image: registry.cn-beijing.aliyuncs.com/wilsonchai/thanos:0.36.1
  45.           args:
  46.             - "sidecar"
  47.             - "--prometheus.url=http://localhost:9090"
  48.             - "--tsdb.path=/prometheus"
  49.           volumeMounts:
  50.             - name: prometheus-data
  51.               mountPath: /prometheus
  52.         # 新增结束
  53.       volumes:
  54.         - name: prometheus-config
  55.           configMap:
  56.             defaultMode: 420
  57.             name: prometheus-cm
  58.         - emptyDir: {}
  59.           name: prometheus-data
复制代码
1.3 新增thanos的service
  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4.   name: thanos-sidecar-service
  5.   namespace: prometheus
  6. spec:
  7.   ports:
  8.     - name: thanos-sidecar-port
  9.       port: 10901
  10.       protocol: TCP
  11.       targetPort: 10901
  12.   selector:
  13.     app: prometheus
  14.   type: NodePort
复制代码
照葫芦画瓢,改造另一个prometheus,专门采集node监控数据的
2. 部署thanos-query
  1. docker run -d --net=host \
  2.   --name thanos-query \
  3.   registry.cn-beijing.aliyuncs.com/wilsonchai/thanos:0.36.1 \
  4.   query \
  5.     --http-address "0.0.0.0:39090" \
  6.     --grpc-address "0.0.0.0:39091" \
  7.     --store "192.168.49.2:30139" \
  8.     --store "192.168.49.2:31165"
复制代码
需要注意一下192.168.49.2:30139与192.168.49.2:31165,这里ip是thanos-sidecar所在pod的node ip,端口则是映射出来的nodeport
打开thanos-query页面检查
2.png

3. 部署对象存储minio

3.png

3.1 部署方式同receive

3.2 新增sidecar configmap

首先准备bucket.yml,由于thanos-sidecar在k8s里面,所以做成configmap
  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4.   name: bucket-cm
  5.   labels:
  6.     name: bucket-cm
  7.   namespace: prometheus
  8. data:
  9.   bucket.yml: |-
  10.     type: S3
  11.     config:
  12.       bucket: "wilson-test"
  13.       endpoint: "10.22.11.156:9090"
  14.       access_key: "zzUrkBzyqcCDXySsMLlS"
  15.       secret_key: "nWCcztESnxnUZIKSKsELGEFdg6l6fjzhtqkARJB8"
  16.       insecure: true
复制代码
3.3 改造thanos-sidecar
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4.   name: prometheus-deploy
  5.   namespace: prometheus
  6.   labels:
  7.     app: prometheus
  8. spec:
  9.   replicas: 1
  10.   selector:
  11.     matchLabels:
  12.       app: prometheus
  13.   template:
  14.     metadata:
  15.       labels:
  16.         app: prometheus
  17.     spec:
  18.       containers:
  19.         - name: prometheus
  20.           image: registry.cn-beijing.aliyuncs.com/wilsonchai/prometheus:v2.54.1
  21.           args:
  22.             - "--storage.tsdb.retention.time=12h"
  23.             - "--config.file=/etc/prometheus/prometheus.yml"
  24.             - "--storage.tsdb.path=/prometheus/"
  25.             - "--storage.tsdb.min-block-duration=30m"
  26.             - "--storage.tsdb.max-block-duration=30m"
  27.             - --web.enable-lifecycle
  28.           ports:
  29.             - containerPort: 9090
  30.           resources:
  31.             requests:
  32.               cpu: 500m
  33.               memory: 500M
  34.             limits:
  35.               cpu: 1
  36.               memory: 1Gi
  37.           volumeMounts:
  38.             - name: prometheus-config
  39.               mountPath: /etc/prometheus/
  40.             - name: prometheus-data
  41.               mountPath: /prometheus
  42.         - name: thanos
  43.           image: registry.cn-beijing.aliyuncs.com/wilsonchai/thanos:0.36.1
  44.           args:
  45.             - "sidecar"
  46.             - "--prometheus.url=http://localhost:9090"
  47.             - "--tsdb.path=/prometheus"
  48.             - "--objstore.config-file=/etc/thanos/bucket.yml"
  49.           volumeMounts:
  50.             - name: prometheus-data
  51.               mountPath: /prometheus
  52.             - name: bucket-config
  53.               mountPath: /etc/thanos/
  54.       volumes:
  55.         - name: prometheus-config
  56.           configMap:
  57.             defaultMode: 420
  58.             name: prometheus-cm
  59.         - name: bucket-config
  60.           configMap:
  61.             defaultMode: 420
  62.             name: bucket-cm
  63.         - emptyDir: {}
  64.           name: prometheus-data
复制代码
由于上传对象存储的时间是30m,所以我们先继续下面的步骤,一会回头过来再回来检查minio中是否有文件上传
4. 部署thanos-store

4.png

部署方式同receive
调整thanos-query的配置,新增thanos-store的地址
  1. docker run -d --net=host \
  2.   --name thanos-query \
  3.   registry.cn-beijing.aliyuncs.com/wilsonchai/thanos:0.36.1 \
  4.   query \
  5.     --http-address "0.0.0.0:39090" \
  6.     --grpc-address "0.0.0.0:39091" \
  7.     --store "192.168.49.2:30139" \
  8.     --store "192.168.49.2:31165" \    --store "10.22.11.156:10901"
复制代码
添加完毕后,检查thanos-query的web页面
5.png

5. pod权限调整

万事俱备,回头去看看minio是否有文件上传,打开之后空空如也,怎么回事,去看一下thanos-sidecar的日志
  1. ▶ kubectl -n prometheus logs prometheus-deploy-6f8c5549b9-rqqk6 -c thanos
  2. ...
  3. ts=2024-10-30T06:03:23.704299583Z caller=sidecar.go:410 level=warn err="upload 01JBDQNT0RZH4GFCFC564RWZT7: hard link block: hard link file chunks/000001: link /prometheus/01JBDQNT0RZH4GFCFC564RWZT7/chunks/000001 /prometheus/thanos/upload/01JBDQNT0RZH4GFCFC564RWZT7/chunks/000001: operation not permitted" uploaded=0
复制代码
怎么回事?没有权限,冷静分析一下thanos-sidecar的上传逻辑

  • 首先数据文件是由prometheus产生的,thanos-sidecar上传文件应该直接使用prometheus产生的数据文件,这样是最简便的策略,不需要把文件复制到自己的目录,带来额外的磁盘消耗,
  • 由于1个pod当中有2个container,带来的问题就是启动进程的用户与组是不一样的,再加上prometheus与thanos-sidecar使用同一个目录/prometheus,2个pod分别在该目录下创建的子目录或文件权限不一致,到此初步判断是 因为2个pod不同的启动用户导致权限有问题
  • 登录到prometheus的pod之后进入/prometheus证实
  1. /prometheus $ ls -lrt                                                                                                                                                                                    
  2. total 44                                                                                                                                                                                                  
  3. -rw-r--r--    1 nobody   nobody       20001 Oct 30 02:46 queries.active                                                                                                                                   
  4. -rw-r--r--    1 nobody   nobody           0 Oct 30 02:46 lock                                                                                                                                             
  5. -rw-r--r--    1 1001     root            37 Oct 30 03:31 thanos.shipper.json                                                                                                                              
  6. drwxr-xr-x    3 nobody   nobody        4096 Oct 30 03:31 01JBDQNT0RZH4GFCFC564RWZT7
复制代码

  • 再加上日志,源文件是在/prometheus下,而thanos-sidecar会在/prometheus/thanos/下对源文件创建硬链接,先检查一下源文件
  1. /prometheus/01JBDQNT0RZH4GFCFC564RWZT7/chunks $ ls -lrt
  2. total 96
  3. -rw-r--r--    1 nobody   nobody       88911 Oct 30 03:31 000001
复制代码

  • 源文件没有组的写权限,垂死病中惊坐起!创建硬链接是需要写权限的,快速验证一下
  1. ▶ id
  2. uid=1000(wilson) gid=1000(wilson) groups=1000(wilson)
  3. ▶ touch /tmp/test
  4. ▶ sudo chown root.root /tmp/test
  5. ▶ sudo chmod 644 /tmp/test
  6. ▶ ln /tmp/test /tmp/ttttt
  7. ln: failed to create hard link '/tmp/ttttt' => '/tmp/test': Operation not permitted
复制代码
到此为止,问题已经比较明朗了,1个pod的2个container,使用了不同的启动用户,创建出来的文件是不同用户的权限,同时他们共享了同一个目录,而prometheus创建的数据文件是644的权限,没有三方写权限。而thanos-sidecar需要把prometheus创建的数据文件创建硬链接到自己的目录,由于没有写权限,创建硬链接失败
解决方案有很多种,这里给出最简单的一种,因为是部署在k8s中的1个pod,只需要指定同一个启动用户去启动不同container即可
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4.   labels:
  5.     app: prometheus
  6.   name: prometheus-deploy
  7.   namespace: prometheus
  8. spec:
  9. ...
  10.   template:
  11. ...
  12.     spec:
  13.       securityContext:
  14.         runAsUser: 555
  15.       containers:
  16. ...
复制代码
加入securityContext,并且随便指定一个用户id,这里我随便指定了一个555,重启之后再登录prometheus查看
6.png

问题解决
联系我


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

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

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