一、什么是PV和PVC?

PV:Persistent Volume 持久数据卷(持久卷)
PVC:Persistent Volume Claim 持久数据卷申领(持久卷申领),也就是表示对PV的使用要求,Pod并不直接绑定PV,而是绑定PVC。

我们可以在Pod直接配置数据卷Volume,支持Volume的类型有20多种,而Pod中的应用程序通常是由开发人员,因此如果直接在Pod直接配置Volume的话,增大了开发人员的学习和使用成本。

而实际生产的kubernetes集群中,通常使用人员和管理人员是分开的,也就是应用容器由开发人员进行开发,而集群的管理由运维人员进行管理。

因此kubernetes在Pod和存储中间加了一层抽象,也就是所谓的PV (Persistent Volume),运维人员创建各种不同存储类型的PV,开发人员只需要创建对应的PVC,并在Pod引用即可,而不需要去关注到底层存储,降低了学习和使用成本。

此外,把Pod和底层存储通过PV进行解耦,可以增加底层存储的可重用性。

二、应用场景

image-1672238365682

比较理想的状态是kubernetes集群有不同的角色,比如专门负责底层存储的存储管理员,专门负责kubernetes管理的集群管理员以及kubernetes集群的使用者,也就是应用者。

那么通过PV进行定义存储,可以使得各方各司其职,术业有专攻。开发人员在定义Pod时,不再需要什么都懂的全栈人员,而是把专注力放在业务层面。

三、简单使用

PV和PVC的使用可以查阅官方文档:https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/

1. 创建PV

这里定义一个hostPath类型的PV,如下面配置所属,并通过kubelet apply -f 命令进行创建。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-hostpath
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  hostPath:
    path: "/k8s-volumes"

说明:
(1)spec.capacity.storage:配置PV使用存储空间
(2)spec.accessModes:配置访问模式,包括下面多种模式:
a)ReadWriteOnce(RWO):读写权限,但是只支持挂载在1个Pod
b)ReadOnlyMany(ROX):只读权限,支持挂载在多个Pod
c)ReadWriteMany(RW):读写权限,支持挂载在多个Pod上
(3)spec.persistentVolumeReclaimPolicy:配置PV的回收策略,当PVC被删除后,对应的PV的处理策略,包括下面多种策略:
a)Retain:PV的数据不会清理,会保留volume,如果需要清理,需要手动进行。
b)Recycle:会将数据进行清理,即 rm -rf /thevolume/*(只有 NFS 和 HostPath 支持),清理完成后,PV为available状态。
c)Delete:删除存储资源,会删除PV及后端的存储资源,比如删除 AWS EBS 卷(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)

[root@test-99 pvs]# kubectl apply -f 01-create-pv.yml 
persistentvolume/pv-hostpath created
[root@test-99 pvs]# kubectl get pv
NAME          CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv-hostpath   1Gi        RWO            Recycle          Available           manual                  11s

通过kubectl apply -f 创建PV之后,可以通过kubelet get pv查看PV的创建情况。
从上面的创建情况来看,CLAIM列为空,表示该PV还没有对应的PVC进行申领,而STATUS为Available表示该PV处于可用状态,PV的状态有如下几种:
(1)Available(可用):表示可用状态,还未被任何 PVC 绑定。
(2)Bound(已绑定):表示 PV 已经被 PVC 绑定。
(3)Released(已释放):PVC 被删除,但是资源还未被集群重新声明。
(3)Failed(失败): 表示该 PV 的自动回收失败。

2. 创建PVC

定义一个PVC配置,具体如下,并通过kubectl apply -f 执行创建。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-local
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 0.1Gi

这里需要注意的是:
(1)PVC的spec.storageClassName需要匹配绑定的PV的spec.storageClassName,也就是PVC是通过storageClassName与PV进行绑定的。
(2)PVC的spac.resources.requests.storage不能大于PV的spec.capacity.storage。

[root@test-99 pvs]# kubectl apply -f 02-create-pvc.yml 
persistentvolumeclaim/pvc-local created
[root@test-99 pvs]# kubectl get pvc
NAME        STATUS   VOLUME        CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-local   Bound    pv-hostpath   1Gi        RWO            manual         6s
[root@test-99 pvs]# kubectl get pv
NAME          CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
pv-hostpath   1Gi        RWO            Recycle          Bound    default/pvc-local   manual                  11m
[root@test-99 pvs]#

创建PVC之后,通过kubectl get pvc查看创建情况,如上面所示,可以发现PVC的VOLUME列匹配上了PV,而对应PV的状态STAUS也变为Bound,且CLAIM为对应的PVC(也就是default/pvc-local,其中default为namespace)。

3. 创建Pod

定义一个Pod配置,具体如下:

apiVersion: v1
kind: Pod
metadata:
  name: pod-pvc-busybox
spec:
  volumes:
    - name: volume-pvc
      persistentVolumeClaim:
        claimName: pvc-local
  containers:
    - name: task-pv-container
      image: busybox:1.28
      imagePullPolicy: IfNotPresent
      command:
      - sleep
      - "3600"
      volumeMounts:
        - mountPath: "/config"
          name: volume-pvc

说明:
spec.volumes.persistentVolumeClaim.claimName表示通过PVC的方式声明Volume,其中claimName配置的是对应的PVC的名称。

[root@test-99 pvs]# kubectl apply -f 03-create-pod.yml 
pod/pod-pvc-busybox created
[root@test-99 pvs]# kubectl get pods -o wide
NAME               READY   STATUS    RESTARTS   AGE    IP               NODE      NOMINATED NODE   READINESS GATES
busybox            1/1     Running   53         2d5h   192.168.252.66   test-99   <none>           <none>
pod-pvc-busybox    1/1     Running   0          14s    192.168.43.72    develop   <none>           <none>
volume-configmap   1/1     Running   36         36h    192.168.43.70    develop   <none>           <none>
volume-emptydir    2/2     Running   96         2d     192.168.43.65    develop   <none>           <none>
volume-hostpath    1/1     Running   47         47h    192.168.43.68    develop   <none>           <none>
[root@test-99 pvs]# 
[root@test-99 pvs]# 
[root@test-99 pvs]# 
[root@test-99 pvs]# kubectl exec -it pod-pvc-busybox -- sh
/ # cat /config/test.txt 
123
/ # 

通过kubectl apply -f 创建Pod之后,通过kubectl exec -it pod-pvc-busybox – sh进行到Pod容器内部,并查看挂载目录/config下的内容与宿主机/k8s-volumes一致。

4. 清理

我们在Pod中使用PV,资源的创建顺序是,PV -> PVC -> Pod, 那么清理时需要按照:Pod -> PVC -> PV 这样的顺序进行,从上面的实例来看,删除顺序如下:

kubectl delete pod pod-pvc-busybox
kubectl delete pvc pvc-local
kubectl delete pv pv-hostpath
打赏
支付宝 微信
上一篇 下一篇