Prometheus 使用localpv 持久化存储

现在我们来创建 prometheus 的 Pod 资源:

# prometheus-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: kube-mon
  labels:
    app: prometheus
spec:
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      serviceAccountName: prometheus
      containers:
      - image: prom/prometheus:v2.24.1
        name: prometheus
        args:
        - "--config.file=/etc/prometheus/prometheus.yml"
        - "--storage.tsdb.path=/prometheus"  # 指定tsdb数据路径
        - "--storage.tsdb.retention.time=24h"
        - "--web.enable-admin-api"  # 控制对admin HTTP API的访问,其中包括删除时间序列等功能
        - "--web.enable-lifecycle"  # 支持热更新,直接执行localhost:9090/-/reload立即生效
        ports:
        - containerPort: 9090
          name: http
        volumeMounts:
        - mountPath: "/etc/prometheus"
          name: config-volume
        - mountPath: "/prometheus"
          name: data
        resources:
          requests:
            cpu: 100m
            memory: 512Mi
          limits:
            cpu: 100m
            memory: 512Mi
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: prometheus-data
      - configMap:
          name: prometheus-config
        name: config-volume

另外为了 prometheus 的性能和数据持久化我们这里是直接将通过一个 LocalPV 来进行数据持久化的,通过 --storage.tsdb.path=/prometheus 指定数据目录,创建如下所示的一个 PVC 资源对象,注意是一个 LocalPV,和 node3 节点具有亲和性:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: prometheus-local
  labels:
    app: prometheus
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 20Gi
  storageClassName: local-storage
  local:
    path: /data/k8s/prometheus
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - node3
  persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: prometheus-data
  namespace: kube-mon
spec:
  selector:
    matchLabels:
      app: prometheus
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: local-storage

现在我们就可以添加 promethues 的资源对象了:

$ kubectl apply -f prometheus-deploy.yaml 
deployment.apps/prometheus created
$ kubectl get pods -n kube-mon
NAME                         READY   STATUS             RESTARTS   AGE
prometheus-df4f47d95-vksmc   0/1     CrashLoopBackOff   3          98s
$ kubectl logs -f prometheus-df4f47d95-vksmc -n kube-mon
level=info ts=2019-12-12T03:08:49.424Z caller=main.go:332 msg="Starting Prometheus" version="(version=2.14.0, branch=HEAD, revision=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19)"
level=info ts=2019-12-12T03:08:49.424Z caller=main.go:333 build_context="(go=go1.13.4, user=root@df2327081015, date=20191111-14:27:12)"
level=info ts=2019-12-12T03:08:49.425Z caller=main.go:334 host_details="(Linux 3.10.0-1062.4.1.el7.x86_64 #1 SMP Fri Oct 18 17:15:30 UTC 2019 x86_64 prometheus-df4f47d95-vksmc (none))"
level=info ts=2019-12-12T03:08:49.425Z caller=main.go:335 fd_limits="(soft=1048576, hard=1048576)"
level=info ts=2019-12-12T03:08:49.425Z caller=main.go:336 vm_limits="(soft=unlimited, hard=unlimited)"
level=error ts=2019-12-12T03:08:49.425Z caller=query_logger.go:85 component=activeQueryTracker msg="Error opening query log file" file=/prometheus/queries.active err="open /prometheus/queries.active: permission denied"
panic: Unable to create mmap-ed active query log

goroutine 1 [running]:
github.com/prometheus/prometheus/promql.NewActiveQueryTracker(0x7ffd8cf6ec5d, 0xb, 0x14, 0x2b4f400, 0xc0006f33b0, 0x2b4f400)
        /app/promql/query_logger.go:115 +0x48c
main.main()
        /app/cmd/prometheus/main.go:364 +0x5229

创建 Pod 后,我们可以看到并没有成功运行,出现了 open /prometheus/queries.active: permission denied 这样的错误信息,这是因为我们的 prometheus 的镜像中是使用的 nobody 这个用户,然后现在我们通过 LocalPV 挂载到宿主机上面的目录的 ownership 却是 root: 

$ ls -la /data/k8s
total 36
drwxr-xr-x   6 root root  4096 Dec 12 11:07 .
dr-xr-xr-x. 19 root root  4096 Nov  9 23:19 ..
drwxr-xr-x   2 root root  4096 Dec 12 11:07 prometheus
[root@master persistentvolume]# kubectl exec -it prometheus-server-5775f99578-5gm5f -n monitor  sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/prometheus $ id
uid=65534(nobody) gid=65534(nogroup)

/prometheus $ ls -la /prometheus/
total 16
drwxr-xr-x    3 nobody   nogroup       4096 Jan 17 15:31 .
drwxr-xr-x    1 root     root          4096 Jan 17 15:31 ..
-rw-------    1 nobody   nogroup          2 Jan 17 15:31 lock
drwxr-xr-x    2 nobody   nogroup       4096 Jan 17 15:31 wal

所以当然会出现操作权限问题了,这个时候我们就可以通过 securityContext 来为 Pod 设置下 volumes 的权限,通过设置 runAsUser=0 指定运行的用户为 root,也可以通过设置一个 initContainer 来修改数据目录权限:

......
initContainers:
- name: fix-permissions
  image: busybox
  command: [chown, -R, "nobody:nobody", /prometheus]
  volumeMounts:
  - name: data
    mountPath: /prometheus

这个时候我们重新更新下 prometheus:

$ kubectl apply -f prometheus-deploy.yaml
deployment.apps/prometheus configured
$ kubectl get pods -n kube-mon                              
NAME                          READY   STATUS    RESTARTS   AGE
prometheus-79b8774f68-7m8zr   1/1     Running   0          56s
$ kubectl logs -f prometheus-79b8774f68-7m8zr -n kube-mon
level=info ts=2019-12-12T03:17:44.228Z caller=main.go:332 msg="Starting Prometheus" version="(version=2.14.0, branch=HEAD, revision=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19)"
......
level=info ts=2019-12-12T03:17:44.822Z caller=main.go:673 msg="TSDB started"
level=info ts=2019-12-12T03:17:44.822Z caller=main.go:743 msg="Loading configuration file" filename=/etc/prometheus/prometheus.yml
level=info ts=2019-12-12T03:17:44.827Z caller=main.go:771 msg="Completed loading of configuration file" filename=/etc/prometheus/prometheus.yml
level=info ts=2019-12-12T03:17:44.827Z caller=main.go:626 msg="Server is ready to receive web requests."
<think>好的,我现在需要帮助用户了解在Kubernetes(k8s)中使用NFS进行持久化存储的创建过程,以及涉及的关键组件如ETCD、apiserver、kubectl、StorageClass、nfs-provisioner的作用,同时还需要提供YAML配置示例和详细解释,还要参考官方文档和生产环境的建议。 首先,我需要回忆Kubernetes持久化存储的基本概念。持久化存储主要涉及PV(PersistentVolume)和PVC(PersistentVolumeClaim),而StorageClass用于动态供应PV。当使用NFS时,通常需要nfs-provisioner来自动创建PV,这属于动态供应。 接下来,各个组件的作用: - ETCD:存储集群的所有状态数据,包括PV、PVC、StorageClass等对象的定义。 - apiserver:处理REST请求,验证并更新资源到ETCD。 - kubectl:用户通过命令行工具创建和管理的资源,如StorageClass、PVC等。 - StorageClass:定义存储的类型和供应者,这里用的是nfs-provisioner。 - nfs-provisioner:负责根据PVC动态创建对应的PV,并与NFS服务器交互。 然后,具体步骤可能包括: 1. 部署NFS服务器,并导出共享目录。 2. 部署nfs-provisioner,可能需要使用Deployment或StatefulSet。 3. 创建StorageClass,指定provisioner为nfs-provisioner。 4. 用户创建PVC,StorageClass会自动触发nfs-provisioner创建PV。 5. 应用Pod中使用PVC挂载存储。 需要注意生产环境中的问题,比如NFS服务器的性能、高可用性,nfs-provisioner的部署方式,以及StorageClass的参数配置(如回收策略)。 然后需要准备YAML示例,比如StorageClass的配置,nfs-provisioner的部署文件,PVC的定义,以及Pod中使用PVC的例子。 官方文档方面,需要参考Kubernetes关于StorageClass、PV/PVC以及nfs-provisioner的相关部分,可能还要提到社区维护的nfs-subdir-external-provisioner项目。 可能的问题点:用户是否已经了解静态和动态供应的区别,是否需要先配置NFS服务器,以及权限设置是否正确。生产环境中可能需要考虑Provisioner的高可用和NFS的冗余。 现在需要组织这些信息,按照用户的要求,分步骤详细说明,并确保YAML语法正确,同时解释每个组件的作用和整个流程。还需要注意用户提到的关键组件,确保每个组件的作用都被明确提到。 最后,生成相关问题,可能涉及如何验证持久化是否成功,如何监控存储使用情况,如何处理NFS服务器的故障,或者如何调整StorageClass的参数优化性能。</think>### Kubernetes 使用NFS实现持久化存储的创建过程 #### 关键组件作用 1. **ETCD** Kubernetes集群的分布式键值存储数据库,保存所有资源对象(如StorageClass、PV、PVC)的元数据[^1]。 2. **apiserver** 接收并验证用户请求(如`kubectl`命令),将合法请求写入ETCD,并协调组件间的通信[^2]。 3. **kubectl** 用户通过命令行工具创建资源(如StorageClass、PVC),触发持久化存储的配置流程。 4. **StorageClass** 定义动态存储供应的模板,指定`provisioner`(如NFS Provisioner)和参数(如回收策略)。 5. **nfs-provisioner** 自动监听PVC请求,根据StorageClass配置动态创建PV,并与NFS服务器交互生成对应的目录。 --- #### 具体步骤与YAML示例 ##### 1. 部署NFS服务器(假设已存在) ```bash # NFS服务器端(需提前配置) $ mkdir /nfs_share && chmod 777 /nfs_share $ echo "/nfs_share *(rw,sync,no_root_squash)" >> /etc/exports $ systemctl restart nfs-server ``` ##### 2. 部署NFS Provisioner ```yaml # nfs-provisioner-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nfs-provisioner spec: replicas: 1 selector: matchLabels: app: nfs-provisioner template: metadata: labels: app: nfs-provisioner spec: containers: - name: nfs-provisioner image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2 env: - name: NFS_SERVER value: 192.168.1.100 # 替换为NFS服务器IP - name: NFS_PATH value: /nfs_share volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes volumes: - name: nfs-client-root nfs: server: 192.168.1.100 path: /nfs_share ``` ##### 3. 创建StorageClass ```yaml # storageclass-nfs.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-storage provisioner: cluster.local/nfs-provisioner # 需与Provisioner配置匹配 parameters: archiveOnDelete: "false" # 删除PVC时是否保留数据 reclaimPolicy: Retain # 或Delete(生产环境建议Retain) allowVolumeExpansion: true ``` ##### 4. 创建PVC触发动态供应 ```yaml # pvc-nfs.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc spec: storageClassName: nfs-storage accessModes: - ReadWriteMany resources: requests: storage: 10Gi ``` ##### 5. 在Pod中使用PVC ```yaml # pod-example.yaml apiVersion: v1 kind: Pod metadata: name: nginx-pod spec: containers: - name: nginx image: nginx volumeMounts: - name: nfs-vol mountPath: /usr/share/nginx/html volumes: - name: nfs-vol persistentVolumeClaim: claimName: nfs-pvc ``` --- #### 生产环境注意事项 1. **NFS服务器高可用** 使用分布式文件系统(如GlusterFS)或NFS集群方案(如DRBD+Keepalived)[^3]。 2. **Provisioner冗余** 部署多个nfs-provisioner副本(需支持Leader Election),避免单点故障。 3. **存储配额与监控** 通过Kubernetes的`ResourceQuota`限制PVC大小,集成Prometheus监控NFS性能。 4. **备份策略** 定期备份ETCD中存储的元数据,并同步NFS服务器上的实际数据。 --- #### 官方文档参考 - StorageClass配置: [Kubernetes官方文档](https://kubernetes.io/docs/concepts/storage/storage-classes/) - NFS Provisioner项目: [GitHub - nfs-subdir-external-provisioner](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值