文章目录
- k8s 存储卷之 PV & PVC
- 高级存储
- PV
- 创建 PV 实例
- PVC
- Pod 挂载数据卷
- 生命周期
k8s 存储卷之 PV & PVC
书接上文:
高级存储
由于kubernetes支持的存储系统有很多,要求客户全都掌握,显然不现实。为了能够屏蔽底层存储实现的细节,方便用户使用, kubernetes引入PV和PVC两种资源对象。
PV(Persistent Volume)是持久化卷的意思,是对底层的共享存储的一种抽象。一般情况下PV由kubernetes管理员进行创建和配置,它与底层具体的共享存储技术有关,并通过插件完成与共享存储的对接。
PVC(Persistent Volume Claim)是持久卷声明的意思,是用户对于存储需求的一种声明。换句话说,PVC其实就是用户向kubernetes系统发出的一种资源需求申请。
使用了PV和PVC之后,工作可以得到进一步的细分:
- 存储:存储工程师维护
- PV: kubernetes管理员维护
- PVC:kubernetes用户维护
PV
PV作为存储资源,主要包括存储能力、访问模式、存储类型、回收策略、后端存储类型等关键信息的设置。
apiVersion: v1kind: PersistentVolumemetadata:name: pv2spec:nfs: # 存储类型,和底层的存储对应path:server:capacity: # 存储能力,目前只支持存储空间的设置storage: 2GiaccessModes: # 访问模式-storageClassName: # 存储类别persistentVolumeReclaimPolicy: # 回收策略
访问模式(accessModes)
用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载ReadOnlyMany(ROX): 只读权限,可以被多个节点挂载ReadWriteMany(RWX):读写权限,可以被多个节点挂载
需要注意的是,底层不同的存储类型可能支持的访问模式不同:
回收策略(persistentVolumeReclaimPolicy)
当PV不再被使用了之后,对其的处理方式。目前支持三种策略:
Retain (保留) 保留数据,需要管理员手工清理数据Recycle(回收) 清除 PV 中的数据,效果相当于执行 rm -rf /thevolume/*Delete (删除) 与 PV 相连的后端存储完成 volume 的删除操作,当然这常见于云服务商的存储服务
需要注意的是,底层不同的存储类型可能支持的回收策略不同。
警告: 回收策略 Recycle 已被废弃。取而代之的建议方案是使用动态供应。
- 状态(status)
某个PV在生命周期中可能处于以下4个阶段(Phaes)之一。
◎ Available:可用状态,还未与某个PVC绑定。◎ Bound:已与某个PVC绑定。◎ Released:绑定的PVC已经删除,资源已释放,但没有被集群回收。◎ Failed:自动资源回收失败。
创建 PV 实例
示例
1、准备环境
# 创建目录[root@nfs ~]# mkdir /root/data/{pv1,pv2,pv3} -pv# 暴露服务[root@nfs ~]# more /etc/exports/root/data/pv1 192.168.5.0/24(rw,no_root_squash)/root/data/pv2 192.168.5.0/24(rw,no_root_squash)/root/data/pv3 192.168.5.0/24(rw,no_root_squash)# 重启服务[root@nfs ~]#systemctl restart nfs
2、创建pv.yaml
apiVersion: v1kind: PersistentVolumemetadata:name:pv1spec:capacity: storage: 1GiaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Retainnfs:path: /root/data/pv1server: 192.168.5.6---apiVersion: v1kind: PersistentVolumemetadata:name:pv2spec:capacity: storage: 2GiaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Retainnfs:path: /root/data/pv2server: 192.168.5.6---apiVersion: v1kind: PersistentVolumemetadata:name:pv3spec:capacity: storage: 3GiaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Retainnfs:path: /root/data/pv3server: 192.168.5.6
PVC
PVC是资源的申请,用来声明对存储空间、访问模式、存储类别需求信息。
apiVersion: v1kind: PersistentVolumeClaimmetadata:name: pvcnamespace: devspec:accessModes: # 访问模式selector: # 采用标签对PV选择storageClassName: # 存储类别resources: # 请求空间requests:storage: 5Gi
示例:
注:这里申请的大小需要注意,申请的存储卷大小需要等于或小于当前系统中空闲的存储卷大小,以本文为例,前面我们创建了 1G/2G/3G 三个 PV 实例,都还没用,都是空闲的。但是这里申请的存储空间大小为 8 G,所以是无法被匹配的。
Pod 挂载数据卷
这是很重要的临门一脚,我们前面又是创建 PV 实例,又是申请空间,就是为了挂载到 Pod 上使用。
apiVersion: v1kind: Podmetadata:name: pod1namespace: devspec:containers:- name: busyboximage: busybox:1.30command: ["/bin/sh","-c","while true;do echo pod1 >> /root/out.txt; sleep 10; done;"]volumeMounts:- name: volumemountPath: /root/volumes:- name: volumepersistentVolumeClaim:claimName: pvc1readOnly: false---apiVersion: v1kind: Podmetadata:name: pod2namespace: devspec:containers:- name: busyboximage: busybox:1.30command: ["/bin/sh","-c","while true;do echo pod2 >> /root/out.txt; sleep 10; done;"]volumeMounts:- name: volumemountPath: /root/volumes:- name: volumepersistentVolumeClaim:claimName: pvc2readOnly: false
注:这里需要特别注意这一行:claimName: pvc1
这个 pvc 需要真实存在的,不然是无法调度到的。
PVC和PV都受限于Namespace,PVC在选择PV时受到Namespace的限制,只有相同Namespace中的PV才可能与PVC绑定。Pod在引用PVC时同样受Namespace的限制,只有相同Namespace中的PVC才能挂载到Pod内。
当Selector和Class都进行了设置时,系统将选择两个条件同时满足的PV与之匹配另外,如果资源供应使用的是动态模式,即管理员没有预先定义PV,仅通过StorageClass交给系统自动完成PV的动态创建,那么PVC再设定Selector时,系统将无法为其供应任何存储资源。
在启用动态供应模式的情况下,一旦用户删除了PVC,与之绑定的PV也将根据其默认的回收策略“Delete”被删除。如果需要保留PV(用户数据),则在动态绑定成功后,用户需要将系统自动生成PV的回收策略从“Delete”改成“Retain”。
生命周期
Kubernetes支持两种资源的供应模式:静态模式(Static)和动态模式(Dynamic)。资源供应的结果就是创建好的PV。
◎ 静态模式:集群管理员手工创建许多PV,在定义PV时需要将后端存储的特性进行设置。◎ 动态模式:集群管理员无须手工创建PV,而是通过StorageClass的设置对后端存储进行描述,标记为某种类型。此时要求PVC对存储的类型进行声明,系统将自动完成PV的创建及与PVC的绑定。PVC可以声明Class为"",说明该PVC禁止使用动态模式。
下图描述了在静态资源供应模式下的 PV 和 PVC 原理:
下图描述了在动态资源供应模式下,通过StorageClass和PVC完成资源动态绑定(系统自动生成PV),并供Pod使用的存储管理机制。
在 Kubernetes 中,实际上存在着一个专门处理持久化存储的控制器,叫作 Volume Controller。这个 Volume Controller 维护着多个控制循环,其中有一个循环,扮演的就是撮合 PV 和 PVC 的“红娘”的角色。它的名字叫作 PersistentVolumeController。PersistentVolumeController 会不断地查看当前每一个 PVC,是不是已经处于 Bound(已绑定)状态。如果不是,那它就会遍历所有的、可用的 PV,并尝试将其与这个“单身”的 PVC 进行绑定。这样,Kubernetes 就可以保证用户提交的每一个 PVC,只要有合适的 PV 出现,它就能够很快进入绑定状态,从而结束“单身”之旅。而所谓将一个 PV 与 PVC 进行“绑定”,其实就是将这个 PV 对象的名字,填在了 PVC 对象的 spec.volumeName 字段上。所以,接下来 Kubernetes 只要获取到这个 PVC 对象,就一定能够找到它所绑定的 PV。