Kubernetes集群PV和PVC详解
Kubernetes集群高级存储资源PV及PVC
文章目录
- Kubernetes集群高级存储资源PV及PVC
-
- 1.高级存储PV和PVC概念部分
- 2.PV和PVC资源的生命周期
- 3.PV资源介绍与案例配置
- 4.PVC资源介绍与案例配置
-
-
- 4.2.2.指定PVC使用某个PV
- 4.3.查看pvc的详细输出
-
- 5.创建Pod资源使用PVC高级存储
-
- 5.1.编写pv及pvc资源yaml文件
- 5.2.创建pod并观察资源状态
- 5.3.向nfs存储中写入数据观察pod的效果
- 6.将PV的回收策略设置为Recycle观察生命周期
1.高级存储PV和PVC概念部分
像NFS类型提供的存储需要用户会搭建NFS系统,并且会在yaml中配置nfs,由于k8s支持的存储系统很多,要求用户全部掌握不太现实。
针对以上现象,k8s提供了PV和PVC两种资源对象。
PV(persistent Volume)是持久化卷的意思,是对底层共享存储的一种抽象,一般情况下PV通过插件完成与共享存储的对接。
PVC(Persistent Volume Claim)是持久卷声明的意思,表示从哪个PV中获取存储空间。
PV具体对存储进行配置和分配,pod等资源可以使用PV抽象出来的存储资源PVC,不需要指定集群的存储细节。
PV和PVC类似于Pod和Node的关系,创建pod需要消耗一定的node资源,node上提供了各种控制器类型,而PV则提供了各种存储资源,PVC只需要指定使用哪个PV,就可以从PV中分配一定的资源给PVC,最后Pod挂载PVC就可以实现数据的持久化。
注意:PVC需要分配namespace,不分配默认在default命名空间中,一个pod只能使用当前namespace中的pvc
2.PV和PVC资源的生命周期
PV和PVC是一一对应的,即一个PV只能为一个PVC服务
生命周期的几个阶段:
-
资源供应:运维手动创建底层存储和PV资源
-
资源绑定:用户创建PVC后kubernetes负责根据PVC的声明自动去匹配合适的PV并进行绑定,也可以通过标签选择器让PVC去匹配指定的PV资源
在用户定义好PVC之后,系统将根据PVC对存储资源的请求,选择一个满足条件的PV进行绑定
PVC在绑定PV时会有两种情况:
- 匹配到合适的PV,就与该PV进行绑定,Pod应用也就可以使用该PVC作为存储
- 如果匹配不到合适的PV,PVC则会处于Pengding状态,知道出现一个符合要求的PV
PV一旦绑定上某个PVC,就会被这个PVC独占,不能在与其他PVC进行绑定
-
资源使用:可以在Pod中像volume一样使用pvc作为持久化存储,在pod中定义volumes,类型为PVC,在容器中定义volumMounts调用PV并指定PVC挂载的路径
-
资源释放:运维删除PVC来释放PV
当存储资源使用完毕后,运维可以删除PVC,与该PVC绑定的PV将会被标记为“已释放(Released)”状态,但是还不能立刻与其他PVC进行绑定,通过之前PVC写入的数据还被保留在存储设备上,只有在回收之后,该PV才能被再次使用
-
资源回收:kubernetes根据PV设置的回收策略进行资源的回收
对于PV,可以设定回收策略,用于设置与之绑定的PVC释放资源后如何处理遗留数据的问题,只有PV的存储空间完成回收,才能为新的PVC提供绑定和使用
PV和PVC的生命周期: 1.首先准备好存储设备,例如nfs、gfs等 2.通过yaml创建pv,创建好pv后,此时pv处于待使用状态 3.通过yaml创建pvc,pvc创建后,kubernetes根据pvc的声明自动匹配一个符合要求的pv,并与pv进行绑定,如果没有符合要求的pv,pvc将会处于pengding状态,直到出现符合要求的pv为止 4.pvc准备好之后就可以让pod进行使用了,pod可以通过valume的方式将pvc挂载到容器的某个路径上,实现持久化存储 5.当pvc资源使用完毕,被删除后,pv此时处于released状态,这时新的pvc是不能在当前pv上进行绑定,只有当回收策略执行完毕,pv上遗留的之前pvc数据清除后,新的pvc才能与pv进行绑定 6.当pv通过回收策略将pvc的数据清除后,pv再次处于待使用状态 pv和pvc的德胜门周期类似一个环形结构,一轮一轮的反复工作
3.PV资源介绍与案例配置
3.1.PV资源清单文件
apiVersion: v1 kind: PersistentVolume metadata: name: pv1 spec: nfs: //存储类型,不同的存储类型配置都不相同,nfs则填写nfs capacity: //存储能力,目前只支持存储空间的设置 storage: 2Gi //具体的存储大小 accessModes: //访问模式 storageClassName: //存储类别 persistentVolumeReclaimPolicy: //回收策略 PV关键参数配置说明: 存储类型 底层实际存储的类型,k8s支持多种存储类型,每种存储类型都存在配置差异 存储能力(capacity) 目前只支持存储空间的设置,未来可能会加入iops、吞吐量等指标的配置 访问模式(accessMode) 用于描述pv对应存储资源的访问权限,有三种访问权限配置 ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载,也就是说只能被一个pvc进行挂载,第二个pvc无法使用当前pv ReadOnlyMany(ROX):只读权限,可以被多个节点挂载,也就是说可以被多个pvc同时使用,但是只有读权限 ReadWriteMany(RWX):读写权限,可以被多个节点挂载,也就是说可以被多个pvc同时使用,并且可读可写 底层不同的存储类型可能支持的访问模式不同 存储类别(storageClassName) PV可以通过storageClassName指定一个存储类别 具有特定类别的PV只能与请求了该类别的PVC进行绑定,也就是说某个PV设置了存储类别,只有有pvc请求申请资源时指定了与PV相同的存储类别才能进行匹配 未设定类别的PV只能与未请求任何类别的PVC进行绑定,也就是说PV没有设置存储类别时,只有有pvc请求申请资源时不指定任何存储类别才能进行匹配 回收策略(persistentVolumeReclaimPolicy) 当PV不再被使用了后,对其的处理方式,目前支持三种策略: Retain(保留)保留数据,需要运维手工清理数据 Recycle(回收)清除PV对应PVC的数据,相当于执行rm -rf volume Delete(删除)与PV项链的后端存储完成volume数据的删除,也就相当于nfs自己删除里面的数据,常用于云服务商和存储服务 不同底层存储支持的回收策略不同 状态(status) 一个pv的生命周期中,会存在4中不同的阶段 Available(可用):表示可用状态,还未被任何PVC进行绑定 Bound(已绑定):表示PV已经被PVC进行绑定 Released(已释放):表示PVC被删除,但是资源还未被集群重新声明,处于Released状态下的pv无法让pvc进行绑定,只有将上次pv残留的数据删除后才能再次使用 Failed(失败):表示该PV的自动回收策略失败
3.2.创建一个PV资源
以nfs为底层存储创建3个pv,大小分别为1/2/3G
1)准备nfs共享路径
1.准备nfs存储路径 [root@k8s-master ~]# mkdir /data/pv_{1..3} -p 2.配置nfs将新建的路径提供共享存储 [root@k8s-master ~]# vim /etc/exports /data/pv_1 192.168.81.0/24(rw,no_root_squash) /data/pv_2 192.168.81.0/24(rw,no_root_squash) /data/pv_3 192.168.81.0/24(rw,no_root_squash) 3.重启nfs [root@k8s-master ~]# systemctl restart nfs 4.查看共享存储路径列表 [root@k8s-master ~]# showmount -e Export list for k8s-master: /data/pv_3 192.168.81.0/24 /data/pv_2 192.168.81.0/24 /data/pv_1 192.168.81.0/24
2)编写yaml文件
[root@k8s-master ~/k8s_1.19_yaml]# vim pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-1 spec: capacity: storage: 1Gi #存储空间大小 accessModes: #访问模式 - ReadWriteMany #多主机读写 persistentVolumeReclaimPolicy: Retain #回收策略为保留 nfs: #使用nfs存储类型 path: /data/pv_1 #nfs共享路径 server: 192.168.81.210 #nfs服务器地址 --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-2 spec: capacity: storage: 2Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain nfs: path: /data/pv_2 server: 192.168.81.210 --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-3 spec: capacity: storage: 3Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain nfs: path: /data/pv_3 server: 192.168.81.210
3)创建PV并查看PV的状态
1.创建pv [root@k8s-master ~/k8s_1.19_yaml]# kubectl create -f pv.yaml persistentvolume/pv-1 created persistentvolume/pv-2 created persistentvolume/pv-3 created 2.查看pv [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv -o wide NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE pv-1 1Gi RWX Retain Available 72s Filesystem pv-2 2Gi RWX Retain Available 72s Filesystem pv-3 3Gi RWX Retain Available 72s Filesystem 3.查看pv的详细信息 [root@k8s-master ~/k8s_1.19_yaml]# kubectl describe pv pv-1 Name: pv-1 Labels: <none> Annotations: <none> Finalizers: [kubernetes.io/pv-protection] StorageClass: Status: Available Claim: Reclaim Policy: Retain Access Modes: RWX VolumeMode: Filesystem Capacity: 1Gi Node Affinity: <none> Message: Source: Type: NFS (an NFS mount that lasts the lifetime of a pod) Server: 192.168.81.210 Path: /data/pv_1 ReadOnly: false Events: <none>
4.PVC资源介绍与案例配置
4.1.PVC资源清单文件
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc namespace: dev spec: accessModes: //访问模式 selector: //采用标签选择具体的pv storageClassName: //存储类别 resources: //请求空间 requests: storage: 5Gi //具体的请求大小
PVC关键参数配置说明:
- 访问模式(accessModes)
- 用于描述pvc对存储资源的访问权限,必须和pv的accessModes保持一致
- 选择条件(selector)
- 通过Label Selector的设置,指定pvc使用哪个pv
- 资源请求:(resources)
- 配置pvc所使用pv的容量
PVC可以根据配置参数自动匹配一个随机PV,也可以通过selector指定使用某个PV
当pvc删除后,pv才能被删除
4.2.创建一个PVC资源
4.2.1.PVC随机匹配PV
1.查看在2.2中创建的pv资源 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv -o wide NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-1 1Gi RWX Retain Available 72s pv-2 2Gi RWX Retain Available 72s pv-3 3Gi RWX Retain Available 72s 2.编写pvc yaml #创建3个pvc,其中2个容量设置成1G,1个设置成5G,使pvc根据容量大小随机匹配pv [root@k8s-master ~/k8s_1.19_yaml]# vim pvc-suiji.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-1 namespace: dev spec: accessModes: #设置访问模式 - ReadWriteMany #多节点可读可写 resources: #设置请求的PV容量 requests: storage: 1Gi \#设置容量为1G,`可以匹配到pv-1` --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-2 namespace: dev spec: accessModes: #设置访问模式 - ReadWriteMany #多节点可读可写 resources: #设置请求的PV容量 requests: storage: 1Gi \#设置容量为1G,`可以匹配到pv-2` --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-3 namespace: dev spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi \#设置容量为5G,`应该是无法匹配到任何pv` 3.创建pvc [root@k8s-master ~/k8s_1.19_yaml]# kubectl create -f pvc-suiji.yaml persistentvolumeclaim/pvc-1 created persistentvolumeclaim/pvc-2 created persistentvolumeclaim/pvc-3 created 4.查看pvc的状态 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pvc -n dev NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-1 Bound pv-1 1Gi RWX 2m16s pvc-2 Bound pv-2 2Gi RWX 2m16s pvc-3 Pending 2m16s #由于pv-3设置的请求容量为5G,没有任何pv的容量在5G以上,因此pvc-3一直处于penging状态,无法匹配pvc 5.查看pv的状态 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv -n dev NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-1 1Gi RWX Retain Bound dev/pvc-1 13m pv-2 2Gi RWX Retain Bound dev/pvc-2 13m pv-3 3Gi RWX Retain Available 13m #可以看到pvc-1匹配到了pv-1的pv,pvc-2匹配到哦pv-2的pv
4.2.2.指定PVC使用某个PV
需求:pvc-1绑定pv-2 pvc-2绑定pv-1 交叉绑定
主要是通过标签选择器的方式让pvc指定使用某个pv
1)编写yaml文件
[root@k8s-master ~/k8s_1.19_yaml]# vim pvc-zhiding.yaml apiVersion: v1 kind: PersistentVolume #控制器类型为pv metadata: name: pv-1 labels: #定义一组标签,用于pvc调用 pv: pv-1 #标签pv值为pv-1 spec: capacity: #定义pv的容量 storage: 2Gi accessModes: #定义访问模式为多主机可读可写 - ReadWriteMany persistentVolumeReclaimPolicy: Retain #定义回收策略 nfs: #定义使用的存储类型 path: /data/pv_1 #共享存储路径 server: 192.168.81.210 #nfs地址 --- apiVersion: v1 kind: PersistentVolume #控制器类型为pv metadata: name: pv-2 labels: pv: pv-2 spec: capacity: storage: 2Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain nfs: path: /data/pv_2 server: 192.168.81.210 --- apiVersion: v1 kind: PersistentVolumeClaim #控制器类型为pvc metadata: name: pvc-1 namespace: dev #指定所在的namespace spec: accessModes: #定义访问模式,多主机可读可写,和pv的访问模式保持一致 - ReadWriteMany resources: #定义申请pv资源的大小 requests: storage: 1Gi selector: #定义标签选择器,用于关联具体使用哪个pv资源 matchLabels: pv: pv-2 --- apiVersion: v1 kind: PersistentVolumeClaim #控制器类型为pvc metadata: name: pvc-2 namespace: dev spec: accessModes: - ReadWriteMany resources: requests: storage: 1Gi selector: matchLabels: pv: pv-1
2)创建资源并查看资源状态
1.创建资源 [root@k8s-master ~/k8s_1.19_yaml]# kubectl create -f pvc-zhiding.yaml persistentvolume/pv-1 created persistentvolume/pv-2 created persistentvolumeclaim/pvc-1 created persistentvolumeclaim/pvc-2 created 2.查看pv的状态 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-1 2Gi RWX Retain Bound dev/pvc-2 6s pv-2 2Gi RWX Retain Bound dev/pvc-1 6s #pv-1的pv存储卷绑定了pvc-2 ,pv-2的pv存储卷绑定了dev/pvc-1 3.查看pvc的状态 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pvc -n dev NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-1 Bound pv-2 2Gi RWX 10s pvc-2 Bound pv-1 2Gi RWX 10s #pvc-1绑定在了pv-2的存储卷,pvc-2绑定在了pv-1的存储卷
4.3.查看pvc的详细输出
[root@k8s-master ~/k8s_1.19_yaml]# kubectl describe pvc pvc-1 -n dev Name: pvc-1 Namespace: dev StorageClass: Status: Bound Volume: pv-2 #挂载的pv Labels: <none> Annotations: pv.kubernetes.io/bind-completed: yes pv.kubernetes.io/bound-by-controller: yes Finalizers: [kubernetes.io/pvc-protection] Capacity: 2Gi #可用的大小 Access Modes: RWX #访问权限 VolumeMode: Filesystem Mounted By: <none> Events: <none>
5.创建Pod资源使用PVC高级存储
需求:创建两个pod,pod-pvc1使用pvc-1,pod-pvc2使用pvc-2,根据3.2.2中pvc的交叉绑定,理想形态应是pod-pvc1使用pvc-1但是存储在pv-2上,pod-pvc2使用pvc-2但是存储在pv-1上
注意:PVC需要分配namespace,不分配默认在default命名空间中,一个pod只能使用当前namespace中的pvc
如果pvc和pod不再一个namespace下,pod将会一直处于pengding状态,并且提示pvc找不到
5.1.编写pv及pvc资源yaml文件
[root@k8s-master ~/k8s_1.19_yaml]# vim pod-pv-pvc.yaml apiVersion: v1 kind: Pod metadata: name: pod-pvc1 namespace: dev spec: containers: - name: nginx-1 image: nginx:1.17.1 ports: - containerPort: 80 volumeMounts: #定义持久卷挂载路径 - name: volume-1 #指定pvc名称 mountPath: /usr/share/nginx/html #指定pvc挂载到容器的路径 volumes: #定义持久卷信息 - name: volume-1 #定义持久卷名称 persistentVolumeClaim: #使用pvc类型 claimName: pvc-1 #指定使用的pvc名称 readOnly: false #关闭只读 --- apiVersion: v1 kind: Pod metadata: name: pod-pvc2 namespace: dev spec: containers: - name: nginx-2 image: nginx:1.17.1 ports: - containerPort: 80 volumeMounts: - name: volume-2 mountPath: /usr/share/nginx/html volumes: - name: volume-2 persistentVolumeClaim: claimName: pvc-2 readOnly: false
5.2.创建pod并观察资源状态
[root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv,pvc -n dev NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pv-1 2Gi RWX Retain Bound dev/pvc-2 20h persistentvolume/pv-2 2Gi RWX Retain Bound dev/pvc-1 20h NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/pvc-1 Bound pv-2 2Gi RWX 20h persistentvolumeclaim/pvc-2 Bound pv-1 2Gi RWX 20h 1.创建资源 [root@k8s-master ~/k8s_1.19_yaml]# kubectl create -f pod-pv-pvc.yaml pod/pod-pvc1 created pod/pod-pvc2 created 2.查看pod资源状态 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pod-pvc1 1/1 Running 0 17m pod-pvc2 1/1 Running 0 17m 3.查看pv,pvc状态 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv,pvc -n dev NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pv-1 2Gi RWX Retain Bound dev/pvc-2 20h persistentvolume/pv-2 2Gi RWX Retain Bound dev/pvc-1 20h NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/pvc-1 Bound pv-2 2Gi RWX 20h persistentvolumeclaim/pvc-2 Bound pv-1 2Gi RWX 20h
查看pod资源的详细信息,明显看出挂载的设备是什么。
![](https://img0.tuicool.com/I3Ebemu.png!mobile)
5.3.向nfs存储中写入数据观察pod的效果
pod-pvc1对应的是pv-2,pod-pvc2对应的是pv-1,如果看pod-pvc1的数据是否写入成功则需要看对应的pv-1的存储设备,看pod-pvc2的数据是否写入成功则需要看对应pv-2的存储设备。
1.向pod-pvc1写入数据 [root@k8s-master ~/k8s_1.19_yaml]# echo "pod-pvc1 pv-2 pvc-1" > /data/pv_2/index.html 2.向pod-pvc2写入数据 [root@k8s-master ~/k8s_1.19_yaml]# echo "pod-pvc2 pv-1 pvc-1" > /data/pv_1/index.html 3.查看pod的ip地址 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pod -n dev -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-pod 1/1 Running 1 6h44m 10.244.1.51 k8s-node1 <none> <none> pod-pvc1 1/1 Running 1 6h34m 10.244.1.53 k8s-node1 <none> <none> pod-pvc2 1/1 Running 1 6h34m 10.244.1.50 k8s-node1 <none> <none> 4.访问pod [root@k8s-master ~/k8s_1.19_yaml]# curl 10.244.1.53 pod-pvc1 pv-2 pvc-1 [root@k8s-master ~/k8s_1.19_yaml]# curl 10.244.1.50 pod-pvc2 pv-1 pvc-1 #均是我们想要的信息
6.将PV的回收策略设置为Recycle观察生命周期
将PV的回收策略设置为Recycle观察PV的状态
1.编写yaml文件 [root@k8s-master ~/k8s_1.19_yaml]# vim pv-recycle.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-3 spec: capacity: storage: 3Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Recycle #将PV回收策略设置为Recycle nfs: path: /data/pv_3 server: 192.168.81.210 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-3 namespace: dev spec: accessModes: - ReadWriteMany resources: requests: storage: 2Gi 2.创建资源 [root@k8s-master ~/k8s_1.19_yaml]# kubectl create -f pv-recycle.yaml persistentvolume/pv-3 created persistentvolumeclaim/pvc-3 created 3.查看pv和pvc的状态 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv,pvc -n dev #可以看到pvc-3绑定了pv-3 4.删除pvc-3 [root@k8s-master ~/k8s_1.19_yaml]# kubectl delete persistentvolumeclaim/pvc-3 -n dev persistentvolumeclaim "pvc-3" deleted 5.持续观察pv的状态 [root@k8s-master ~]# kubectl get pv -w
总结:当pvc-3删除后,对应吃pv-3首先处于released状态,当回收策略完成后,pv-3再次处于available状态。
转:https://www.tuicool.com/wx/M7fuquJ