PV和PVC的概念
PV(Persistent Volume)是持久化卷的意思,是对底层的共享存储的一种抽象。一般情况下PV由kubernetes管理员进行创建和配置,它与底层具体的共享存储技术有关,并通过插件完成与共享存储的对接。
PVC(Persistent Volume Claim)是持久卷声明的意思,是用户对于存储需求的一种声明。换句话说,PVC其实就是用户向kubernetes系统发出的一种资源需求申请。
使用了PV和PVC之后,工作可以得到进一步的细分:
- PV: kubernetes管理员维护(管理员提供PV)
- PVC:kubernetes用户维护(用户创建PVC,自己寻找PV进行绑定)
PV
##PV的资源清单
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2 #pv的名称,与后面的PVC进行绑定
spec:
nfs: # 存储类型,与底层真正存储对应
path:
capacity: # 存储能力,目前只支持存储空间的设置
storage: 2Gi
accessModes: # 访问模式
storageClassName: # 存储类别
persistentVolumeReclaimPolicy: # 回收策略
注意点:
PV是集群中的资源,是全局资源,不归属任何的namespace,所以PV的资源清单中不需要指定namespace
##PV的关键配置参数说明
-
存储类型
底层实际存储的类型,kubernetes支持多种存储类型(nfs、cifs、glusterfs、hostPath等),每种存储类型的配置都有所差异
-
存储能力(capacity)
目前只支持存储空间的设置( storage=1Gi )
-
访问模式(accessModes)
用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
- ReadWriteOnce(RWO):以读写权限挂载(mount)到单个节点
- ReadOnlyMany(ROX): 以只读权限挂载(mount)到多个节点
- ReadWriteMany(RWX):以读写权限挂载(mount)到多个节点
-
回收策略(persistentVolumeReclaimPolicy)
- Retain (保留) 保留数据,需要管理员手工清理数据(一般使用)
- Recycle(回收) 清除 PV 中的数据,效果相当于执行:rm -rf /thevolume/*
- Delete (删除) 删除 Storage Provider 上的对应存储资源,例如 AWS EBS、GCE PD、Azure Disk、- OpenStack Cinder Volume 等,可以看成连同管理员PV的存储资源和数据也一起干掉。
-
存储类别(storageClassName)
PV可以通过storageClassName参数指定一个存储类别
- 具有特定类别的PV只能与请求了该类别的PVC进行绑定
- 未设定类别的PV(为" ")则只能与不请求任何类别的PVC进行绑定
PV和PVC的存储类别必须一致。
-
状态(status)
一个 PV 的生命周期中,可能会处于4中不同的阶段:
- Available(可用): 表示可用状态,还未被任何 PVC 绑定
- Bound(已绑定): 表示 PV 已经被 PVC 绑定
- Released(已释放): 表示 PVC 被删除,但是资源还未被集群重新声明
- Failed(失败): 表示该 PV 的自动回收失败
PV资源的创建
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /root/data/pv1 #nfs目录
server: 192.168.5.6 #nfs目录所在的机器地址
# 创建 pv
[root@k8s-master01 ~]# kubectl create -f pv.yaml
persistentvolume/pv1 created
# 查看pv
[root@k8s-master01 ~]# kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS AGE VOLUMEMODE
pv1 1Gi RWX Retain Available 10s Filesystem
STATUS:创建的PV状态是Available,表示PV就绪,可以被PVC申请。等绑定了PVC就会变成Bound
PVC
PVC的资源清单
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc #PVC的名称
namespace: dev #PVC所属的命名空间
spec:
accessModes: # 访问模式
selector: # 采用标签对PV选择
storageClassName: # 采用存储类别对PV进行选择
matchLabels
resources: # 请求空间
requests:
storage: 5Gi
PVC的创建只需要指定PV的容量,访问模式,Class(所以这三个值都和PV一致)
目前PVC与PV匹配可以通过StorageClassName、selector(matchLabels或者matchExpressions)两种方式
PV和PVC的关系是一对一的,只能将一个PVC绑定到一个PV上
PVC的关键配置参数说明
- 访问模式(accessModes)
用于描述用户应用对存储资源的访问权限(与PV一致)
-
选择条件(selector)
通过Label Selector的设置,可使PVC对于系统中己存在的PV进行筛选(PV的label标签)
-
存储类别(storageClassName)
PVC在定义时可以设定需要的后端存储的类别,只有设置了该class的pv才能被系统选出(以PV一致)
-
资源请求(Resources )
描述对存储资源的请求
PVC资源的创建
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
namespace: dev
spec:
storageClassName: nfs
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
[root@k8s-master01 ~]# kubectl get pvc -n dev -o wide
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
pvc1 Bound pv1 1Gi RWX 15s Filesystem
# 查看pv
[root@k8s-master01 ~]# kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM AGE VOLUMEMODE
pv1 1Gi RWx Retain Bound dev/pvc1 3h37m Filesystem
此时查看PVC和PV都是Bound绑定状态,在PV的CLAIM可以看到绑定的PV(此处是通过storageClassName进行的绑定)
PV和PVC的使用
Pod的创建
apiVersion: v1
kind: Pod
metadata:
name: pod1
namespace: dev
spec:
containers:
- name: busybox
image: busybox:1.30
command: ["/bin/sh","-c","while true;do echo pod1 >> /root/out.txt; sleep 10; done;"]
volumeMounts:
- name: volume
mountPath: /root/
volumes:
- name: volume
persistentVolumeClaim:
claimName: pvc1
与普通的Volume的格式类似,在volumes通过persistentVolumeClaim指定pvc
volumeMounts中指定容器内挂载的路径
# 查看pod
[root@k8s-master01 ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod1 1/1 Running 0 14s 10.244.1.69 node1
# 查看pvc
[root@k8s-master01 ~]# kubectl get pvc -n dev -o wide
NAME STATUS VOLUME CAPACITY ACCESS MODES AGE VOLUMEMODE
pvc1 Bound pv1 1Gi RWX 94m Filesystem
# 查看pv
[root@k8s-master01 ~]# kubectl get pv -n dev -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM AGE VOLUMEMODE
pv1 1Gi RWX Retain Bound dev/pvc1 5h11m Filesystem
# 查看nfs中的文件存储
[root@nfs ~]# more /root/data/pv1/out.txt
node1
node1
PV的回收
当PV不再需要时,可以通过删除PVC进行回收
kubectl delete pvc pvc1
当PVC被删除之后
-
如果PV的回收策略为Recycle,那么PV中路径的数据会被清除掉,PV的状态又会变回Available,说明此PV可以继续被PVC绑定。
-
如果PV的回收策略是Retain,那么数据则会被保留,PV的状态会一致处于Released,不能被其他的PVC申请。
为了重新使用存储资源,可以删除并重新创建PV(kubectl delete pv pv1),删除PV的操作只是删除了PV对象,之前的数据并不会被删除,继续保留,重新创建PV,使用路径下的其余存储空间。新建的PV状态为Available,可以被PVC申请。
-
会删除 PV 在 Storage Provider 上对应存储空间。NFS 的 PV 不支持
Delete
,支持Delete
的 Provider 有 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等
#PV和PVC的生命周期
-
资源供应:管理员手动创建底层存储和PV
-
资源绑定:用户创建PVC,kubernetes负责根据PVC的声明去寻找PV,并绑定
在用户定义好PVC之后,系统将根据PVC对存储资源的请求在已存在的PV中选择一个满足条件的
- 一旦找到,就将该PV与用户定义的PVC进行绑定,用户的应用就可以使用这个PVC了
- 如果找不到,PVC则会无限期处于Pending状态,直到等到系统管理员创建了一个符合其要求的PV
PV一旦绑定到某个PVC上,就会被这个PVC独占,不能再与其他PVC进行绑定了
PV和PVC的关系是一对一的,只能将一个PVC绑定到一个PV上
-
资源使用:用户可在pod中像volume一样使用pvc,Pod使用Volume的定义,将PVC挂载到容器内的某个路径进行使用。
-
资源释放:用户删除pvc来释放pv
当存储资源使用完毕后,用户可以删除PVC,与该PVC绑定的PV将会被标记为“已释放”,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还被留在存储设备上,只有在清除之后该PV才能再次使用。
-
资源回收:kubernetes根据pv设置的回收策略进行资源的回收
对于PV,管理员可以设定回收策略,用于设置与之绑定的PVC释放资源之后如何处理遗留数据的问题。只有PV的存储空间完成回收,才能供新的PVC绑定和使用
PV和PVC常见问题
删除Kubernetes的PV和PVC时状态一直为Terminating
这是正常的,是Kubernetes为了防止误删除PV和PVC导致数据丢失的保护机制。
如果确认要删除PV和PVC,并删除关联的数据,可以执行以下命令:
# 先解除保护机制,再删除PVC
# 如果已经处在Terminating状态,patch后直接删除
kubectl patch pvc <pvc-name> -p '{"metadata":{"finalizers":null}}'
kubectl delete pvc <pvc-name>
# 先解除保护机制,再删除PV
# 如果已经处在Terminating状态,patch后直接删除
kubectl patch pv <pv-name> -p '{"metadata":{"finalizers":null}}'
kubectl delete pv <pv-name>
PV/PVC的动态供给
##PV动态供给概念
我们提前创建了 PV,然后通过 PVC 申请 PV 并在 Pod 中使用,这种方式叫做静态供给(Static Provision)。
如果没有满足 PVC 条件的 PV,会动态创建 PV,这种方式叫做动态供给(Dynamical Provision)。
相比静态供给,动态供给有明显的优势:不需要提前创建 PV,减少了管理员的工作量,效率高。
动态供给是通过 StorageClass 实现的。
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: standard
provisioner : kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy:Retain
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: slow
provisioner : kubernetes.io/aws-ebs
parameters:
type: io1
zones: us-east-1d,us-east-1c
iopsPerGB: "10"
这两个 StorageClass 都会动态创建 AWS EBS,不同在于 standard
创建的是 gp2
类型的 EBS,而 slow
创建的是 io1
类型的 EBS。
StorageClass 支持 Delete
和 Retain
两种 reclaimPolicy
,默认是 Delete
。
与之前一样,PVC 在申请 PV 时,只需要指定 StorageClass 和容量以及访问模式。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
namespace: dev
spec:
storageClassName: standard
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName即为上面创建的两个StorageClass其中一个
除了 AWS EBS,Kubernetes 支持其他多种动态供给 PV 的 Provisioner,完整列表请参考 https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner