Kubernetes(k8s)的Volume数据存储高级储存类型PV和PVC的使用

  • Post author:
  • Post category:其他




1. PV和PVC概述

由于kubernetes支持的存储系统有很多,为了能够屏蔽底层存储实现的细节,方便普通用户使用,kubernetes引入了PV和PVC两种资源对象

  • PV(Persistent Volume)是持久化卷的意思,是对底层的共享存储的一种抽象
  • PVC(Persistent Volume Claim)是持久化卷声明的意思,是用户对于存储需求的一种声明

PV和PVC



2. PV



2.1 PV的资源清单文件

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1
spec:
  nfs:
    path: /root/data/nfs/pv1
    server: 192.168.23.31
  capacity: 
    storage: 2Gi                                  # 存储空间的设置
  accessModes:                                    # 访问模式
    - ReadWriteMany
  storageClassName: fast                          # 自定义的存储类别
  persistentVolumeReclaimPolicy: Retain           # 回收策略

访问模式(accessModes):用来描述用户应用对存储资源的访问权限,底层不同的存储类型可能支持的访问模式不同

  • ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
  • ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
  • ReadWriteMany(RWX):读写权限,可以被多个节点挂载

回收策略(persistentVolumeReclaimPolicy):当PV不再被使用之后,对其的处理方式,底层不同的存储类型可能支持的回收策略不同

  • Retain(保留):保留数据,需要管理员手动清理数据
  • Recycle(回收):清除PV中的数据,效果相当于rm -rf /volume/*
  • Delete(删除):和PV相连的后端存储完成volume的删除操作,常见于云服务器厂商的存储服务

存储类别(storageClassName):PV可以通过自定义storageClassName参数指定一个存储类别

  • 具有特定类型的PV只能和请求了该类别的PVC进行绑定
  • 未设定类别的PV只能和不请求任何类别的PVC进行绑定



2.2 准备NFS环境

创建共享目录

[root@nfs ~]# mkdir -p /root/data/nfs/{pv1,pv2,pv3}

修改/etc/exports文件

[root@nfs ~]# cat /etc/exports
/root/data/nfs/pv1 192.168.23.0/24(rw,no_root_squash) 
/root/data/nfs/pv2 192.168.23.0/24(rw,no_root_squash) 
/root/data/nfs/pv3 192.168.23.0/24(rw,no_root_squash)
[root@nfs ~]#

重启nfs

[root@nfs ~]# systemctl restart nfs



2.3 创建PV

新建pv.yaml文件,内容如下。然后创建PV

[root@k8s-master ~]# cat pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1
spec:
  nfs:
    path: /root/data/nfs/pv1
    server: 192.168.23.31
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain

---

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv2
spec:
  nfs: 
    path: /root/data/nfs/pv2
    server: 192.168.23.31
  capacity: 
    storage: 2Gi
  accessModes: 
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain

---

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv3
spec:
  nfs: 
    path: /root/data/nfs/pv3
    server: 192.168.23.31
  capacity: 
    storage: 3Gi
  accessModes: 
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
[root@k8s-master ~]# 
[root@k8s-master ~]# kubectl apply -f pv.yaml 
persistentvolume/pv1 created
persistentvolume/pv2 created
persistentvolume/pv3 created
[root@k8s-master ~]#



2.4 查看PV

[root@k8s-master ~]# kubectl get pv -o wide
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE   VOLUMEMODE
pv1    1Gi        RWX            Retain           Available                                   41s   Filesystem
pv2    2Gi        RWX            Retain           Available                                   41s   Filesystem
pv3    3Gi        RWX            Retain           Available                                   41s   Filesystem
[root@k8s-master ~]# 



3. PVC



3.1 PVC的资源清单文件

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc1
  namespace: dev
spec:
  accessModes:                         # 访客模式
    - ReadWriteMany
  selector:                            # 采用标签对PV进行选择
    matchLabels:
      pv: pv1
  storageClassName: fast               # 存储类别
  resources:                           # 请求空间
    requests:
      storage: 1Gi

访客模式(accessModes):用于描述用户应用对存储资源的访问权限。需和PV的accessModes一致才能绑定到PV

存储类别(storageClassName):PVC在定义时可以设定需要的后端存储的类别。需和PV的storageClassName一致才能绑定到PV

资源请求(resources):描述对存储资源的请求。PVC请求的资源必须等于小于PV的资源,才能绑定到PV



3.3 创建PVC

新建pvc.yaml文件,内容如下。然后创建PVC

[root@k8s-master ~]# cat pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc1
  namespace: dev
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc2
  namespace: dev
spec:
  accessModes: 
    - ReadWriteMany
  resources: 
    requests:
      storage: 2Gi

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc3
  namespace: dev
spec:
  accessModes: 
    - ReadWriteMany
  resources: 
    requests:
      storage: 5Gi

[root@k8s-master ~]# 
[root@k8s-master ~]# kubectl apply -f pvc.yaml 
persistentvolumeclaim/pvc1 created
persistentvolumeclaim/pvc2 created
persistentvolumeclaim/pvc3 created
[root@k8s-master ~]# 



3.4 查看PVC

[root@k8s-master ~]# 
[root@k8s-master ~]# kubectl get pvc -n dev -o wide
NAME   STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
pvc1   Bound     pv1      1Gi        RWX                           56s   Filesystem
pvc2   Bound     pv2      2Gi        RWX                           56s   Filesystem
pvc3   Pending                                                     55s   Filesystem
[root@k8s-master ~]# 
[root@k8s-master ~]# kubectl get pv -o wide
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM      STORAGECLASS   REASON   AGE   VOLUMEMODE
pv1    1Gi        RWX            Retain           Bound       dev/pvc1                           14m   Filesystem
pv2    2Gi        RWX            Retain           Bound       dev/pvc2                           14m   Filesystem
pv3    3Gi        RWX            Retain           Available                                      14m   Filesystem
[root@k8s-master ~]# 



4. 创建Pod使用PVC

新建pod.yaml文件,内容如下。然后创建Pod

[root@k8s-master ~]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod1
  namespace: dev
spec:
  containers:
    - name: busybox
      image: busybox:latest
      command: ["/bin/sh", "-c", "while true; do echo pod1 >> /root/logs/pod.log; sleep 10; done;"]
      volumeMounts:
        - name: volume
          mountPath: /root/logs
  volumes:
    - name: volume
      persistentVolumeClaim:
        claimName: pvc1
        readOnly: false

---

apiVersion: v1
kind: Pod
metadata:
  name: pod2
  namespace: dev
spec:
  containers:
    - name: busybox
      image: busybox:latest
      command: ["/bin/sh", "-c", "while true; do echo pod2 >> /root/logs/pod.log; sleep 10; done;"]
      volumeMounts:
        - name: volume
          mountPath: /root/logs
  volumes:
    - name: volume
      persistentVolumeClaim:
        claimName: pvc2
        readOnly: false

[root@k8s-master ~]# 
[root@k8s-master ~]# kubectl apply -f pod.yaml 
pod/pod1 created
pod/pod2 created
[root@k8s-master ~]# 



5. 查看PV和PVC

[root@k8s-master ~]# kubectl get pvc -n dev -o wide
NAME   STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE     VOLUMEMODE
pvc1   Bound     pv1      1Gi        RWX                           9m31s   Filesystem
pvc2   Bound     pv2      2Gi        RWX                           9m31s   Filesystem
pvc3   Pending                                                     9m30s   Filesystem
[root@k8s-master ~]# 
[root@k8s-master ~]# kubectl get pv -o wide
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM      STORAGECLASS   REASON   AGE   VOLUMEMODE
pv1    1Gi        RWX            Retain           Bound       dev/pvc1                           23m   Filesystem
pv2    2Gi        RWX            Retain           Bound       dev/pvc2                           23m   Filesystem
pv3    3Gi        RWX            Retain           Available                                      23m   Filesystem
[root@k8s-master ~]# 



6. 查看远程NFS的共享目录

[root@docker ~]# ll data/nfs/pv1/pod.log 
-rw-r--r--. 1 root root 80 5月  23 18:17 data/nfs/pv1/pod.log
[root@docker ~]# 
[root@docker ~]# ll data/nfs/pv2/pod.log 
-rw-r--r--. 1 root root 70 5月  23 18:17 data/nfs/pv2/pod.log
[root@docker ~]# 
[root@docker ~]# ll data/nfs/pv3
总用量 0
[root@docker ~]# 



7. PV和PVC的生命周期

PV和PVC的生命周期

PV和PVC之间的相互作用遵循如下的生命周期:

  • 资源供应(此时PV的状态为Available):管理员手动创建底层存储和PV
  • 资源绑定(此时PV的状态为Bound):用户创建PVC,kubernetes负责根据PVC声明去寻找PV,一旦找到符合条件的PV,就将该PV和用户定义的PVC进行绑定,用户的应用就可以使用这个PVC了。PV一旦绑定到某个PVC上,就会被这个PVC独占,不能再和其他的PVC进行绑定。如果找不到,PVC就会无限期的处于Pending状态,直到系统管理员创建一个符合其要求的PV
  • 资源使用:用户可以在Pod中像volume一样使用PVC
  • 资源释放(此时PV的状态为已释放):用户删除PVC来释放PV。和该PVC绑定的PV将会标记为“已释放”,但是还不能立刻和其他的PVC进行绑定。之前PVC写入的数据可能还留在存储设备上,只有在清除之后该PV才能再次使用
  • 资源回收:kubernetes根据PV设置的回收策略进行资源的回收。如果该PV的自动回收失败,则此时PV的状态为Failed



版权声明:本文为yy8623977原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。