Prometheus存储

原文

一、介绍

prometheus 提供了本地存储(TSDB)时序型数据库的存储方式,在2.0版本之后,压缩数据的能力得到了大大的提升(每个采样数据仅仅占用3.5byte左右空间),单节点情况下可以满足大部分用户的需求,但本地存储阻碍了prometheus集群化的实现,因此在集群中应当采用 其他时序性数据来替代,比如influxdb

prometheus 分为三个部分,分别是:抓取数据存储数据查询数据

在早期有一个单独的项目叫做 TSDB,但是,在2.1.x的某个版本,已经不单独维护这个项目了,直接将这个项目合并到了prometheus的主干上了。

二、案例

我们的prometheus目前申请了三个文件系统NFS,托管集群存在一个文件系统,QKE集群存在另一个文件系统,单都是存储到云端(StorageClass)。

存储的方式:每个prometheus实例对应一个目录,如果有多个prometheus实例,则对应多个目录。

另外,注意,每个文件系统对应一个StorageClass自由对象。

以prometheus托管集群为例,如下是创建StorageClass

img

关键的两个文件:

创建StorageClass资源对象:

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: prometheus-data-03
provisioner: prometheus-data-03/nfs
reclaimPolicy: Retain

创建StorageClass后,还需要K8S存储插件进行真正的存储工作:

nfs-client-provisioner 可动态为kubernetes提供pv卷,是Kubernetes的简易NFS的外部provisioner,本身不提供NFS,需要现有的NFS服务器提供存储。持久卷目录的命名规则为: n a m e s p a c e − {namespace}- namespace{pvcName}-${pvName}。

树莓派k8s集群安装nfs-client-provisioner_崔一凡的技术博客_51CTO博客

kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-provisioner-03
spec:
  selector:
    matchLabels:
      app: nfs-provisioner-03
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-provisioner-03
    spec:
      serviceAccount: nfs-provisioner
      containers:
        - name: nfs-provisioner
          image: docker-registry.xxx.virtual/hubble/nfs-client-provisioner:v3.1.0-k8s1.11
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: prometheus-data-03/nfs
            - name: NFS_SERVER
              value: hubble-587ceb02-5e85e802.cnhz1.qfs.xxx.storage
            - name: NFS_PATH
              value: /hubble-wuhan-lkg
      volumes:
        - name: nfs-client-root
          nfs:
            server: hubble-587ceb02-5e85e802.cnhz1.qfs.xxx.storage
            path: /hubble-wuhan-lkg

上面的server地址其实就是云存储那边提供的地址:

img

部署prometheus:

kind: Service
apiVersion: v1
metadata:
  name: prometheus-headless
  namespace: example-nfs
  labels:
    app.kubernetes.io/name: prometheus
spec:
  type: ClusterIP
  clusterIP: None
  selector:
    app.kubernetes.io/name: prometheus
  ports:
  - name: web
    protocol: TCP
    port: 9090
    targetPort: web
  - name: grpc
    port: 10901
    targetPort: grpc
---
 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
  namespace: example-nfs
 
---
 
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: prometheus-example-nfs
subjects:
  - kind: ServiceAccount
    name: prometheus
    namespace: example-nfs
roleRef:
  kind: ClusterRole
  name: prometheus
  apiGroup: rbac.authorization.k8s.io
---
 
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: prometheus
  namespace: example-nfs
  labels:
    app.kubernetes.io/name: prometheus
spec:
  serviceName: prometheus-headless
  podManagementPolicy: Parallel
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: prometheus
  template:
    metadata:
      labels:
        app.kubernetes.io/name: prometheus
    spec:
      serviceAccountName: prometheus
      securityContext:
        fsGroup: 1000
        runAsUser: 0
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app.kubernetes.io/name
                operator: In
                values:
                - prometheus
            topologyKey: kubernetes.io/hostname
      containers:
      - name: prometheus
        image: docker-registry.xxx.virtual/hubble/prometheus:v2.34.0
        args:
        - --config.file=/etc/prometheus/config_out/prometheus.yaml
        - --storage.tsdb.path=/prometheus
        - --storage.tsdb.retention.time=30d
        - --web.external-url=/example-nfs/prometheus
        - --web.enable-lifecycle
        - --storage.tsdb.no-lockfile
        - --storage.tsdb.min-block-duration=2h
        - --storage.tsdb.max-block-duration=1d
        ports:
        - containerPort: 9090
          name: web
          protocol: TCP
        livenessProbe:
          failureThreshold: 6
          httpGet:
            path: /example-nfs/prometheus/-/healthy
            port: web
            scheme: HTTP
          periodSeconds: 5
          successThreshold: 1
          timeoutSeconds: 3
        readinessProbe:
          failureThreshold: 120
          httpGet:
            path: /example-nfs/prometheus/-/ready
            port: web
            scheme: HTTP
          periodSeconds: 5
          successThreshold: 1
          timeoutSeconds: 3
        resources:
          requests:
            memory: 1Gi
          limits:
            memory: 30Gi
        volumeMounts:
        - mountPath: /etc/prometheus/config_out
          name: prometheus-config-out
          readOnly: true
        - mountPath: /prometheus
          name: prometheus-storage
        - mountPath: /etc/prometheus/rules
          name: prometheus-rules
      - name: thanos
        image: docker-registry.xxx.virtual/hubble/thanos:v0.25.1
        args:
        - sidecar
        - --tsdb.path=/prometheus
        - --prometheus.url=http://127.0.0.1:9090/example-nfs/prometheus
        - --reloader.config-file=/etc/prometheus/config/prometheus.yaml.tmpl
        - --reloader.config-envsubst-file=/etc/prometheus/config_out/prometheus.yaml
        - --reloader.rule-dir=/etc/prometheus/rules/
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        ports:
        - name: http-sidecar
          containerPort: 10902
        - name: grpc
          containerPort: 10901
        livenessProbe:
            httpGet:
              port: 10902
              path: /-/healthy
        readinessProbe:
          httpGet:
            port: 10902
            path: /-/ready
        volumeMounts:
        - name: prometheus-config-tmpl
          mountPath: /etc/prometheus/config
        - name: prometheus-config-out
          mountPath: /etc/prometheus/config_out
        - name: prometheus-rules
          mountPath: /etc/prometheus/rules
        - name: prometheus-storage
          mountPath: /prometheus
      volumes:
      - name: prometheus-config-tmpl
        configMap:
          defaultMode: 420
          name: prometheus-config-tmpl
      - name: prometheus-config-out
        emptyDir: {}
      - name: prometheus-rules
        configMap:
          name: prometheus-rules
  volumeClaimTemplates:
  - metadata:
      name: prometheus-storage
      labels:
        app.kubernetes.io/name: prometheus
    spec:
      storageClassName: prometheus-data-03
      accessModes:
      - ReadWriteOnce
      volumeMode: Filesystem
      resources:
        requests:
          storage: 100Gi
        limits:
          storage: 300Gi

–storage.tsdb.min-block-duration:控制数据落盘的时间,即最小落盘时间是2小时

–storage.tsdb.min-block-duration:控制数据落盘的时间,即最大落盘时间是1天

–storage.tsdb.retention.time配置本地保留30天数据,减少空间占用;

如上,volumeClaimTemplates即是定义一个PVC,如何创建PV呢?使用StorageClass定义的模板去创建PV。

那么prometheus查询数据的时候是怎么查的呢?

其实对于prometheus来说,就是从prometheus这个实例提供的接口查询数据而已,和普通的容器一样,不管是云存储还是node存储或是其他存储,对于容器来说是透明的,都是从挂载到的目录去查询,所以远端对于prometheus来说就是查本地的目录文件。

三、存储原理

prometheus将采集到的样本以时间序列的方式保存在内存(TSDB 时序数据库)中,并定时保存到硬盘中。

与zabbix不同,zabbix会保存所有的数据,而prometheus本地存储会保存15天,超过15天以上的数据将会被删除,若要永久存储数据,有两种方式:

  • 方式一:修改prometheus的配置参数“storage.tsdb.retention.time=10000d”;
  • 方式二:将数据引入存储到Influcdb中。

prometheus按照block块的方式来存储数据,每2小时为一个时间单位,首先会存储到内存中,当到达2小时后,会自动写入磁盘中。

为防止程序异常而导致数据丢失,采用了WAL机制,即2小时内记录的数据存储在内存中的同时,还会记录一份日志,存储在block下的wal目录中。当程序再次启动时,会将wal目录中的数据写入对应的block中,从而达到恢复数据的效果。

当删除数据时,删除条目会记录在tombstones 中,而不是立刻删除。

prometheus采用的存储方式称为“时间分片”,每个block都是一个独立的数据库。优势是可以提高查询效率,查哪个时间段的数据,只需要打开对应的block即可,无需打开多余数据。

四、数据备份

1、完全备份

备份prometheus的data目录可以达到完全备份的目的,但效率较低。

2、快照备份

prometheus提供了一个功能,是通过API的方式,快速备份数据。实现方式:

  • 首先,修改prometheus的启动参数,新增以下两个参数:
--storage.tsdb.path=/usr/local/share/prometheus/data \
--web.enable-admin-api
  • 然后,重启prometheus
  • 最后,调用接口备份:
# 不跳过内存中的数据,即同时备份内存中的数据
curl -XPOST http://127.0.0.1:9090/api/v2/admin/tsdb/snapshot?skip_head=false
# 跳过内存中的数据
curl -XPOST http://127.0.0.1:9090/api/v2/admin/tsdb/snapshot?skip_head=true

skip_head作用:是否跳过存留在内存中还未写入磁盘中的数据,仍在block块中的数据, 默认是false

五、数据还原

利用api方式制作成snapshot后,还原时将snapshot中的文件覆盖到data目录下,重启prometheus即可!

添加定时备份任务(每周日3点备份)

crontable -e                              #注意时区,修改完时区后,需要重启 crontab    systemctl  restart cron
0 3 * * 7 sudo /usr/bin/curl -XPOST -I http://127.0.0.1:9090/api/v1/admin/tsdb/snapshot >> /home/bill/prometheusbackup.log
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值