原文地址: https://kubernetes.io/docs/concepts/storage/persistent-volumes/
文档描述PersistentVolume目前在k8s中的使用情况。
管理计算实例的直接问题就是管理存储,引入PersisitentVolume子系统提供给用户和管理员,抽象描述了存储如何被提供。为此,提供了PersistentVolume和PersistentVolumeClaim资源对象。以下统称PV,PVC。
名词概念
PV是集群中已初始化的一块存储。一般由管理员或动态配置使用Storage Classes初始化。PV是集群资源,类似volumes的存储插件,但是他的生命周期是独立于pod的,这里与volume行为不同。 它可获取NFS、iSCSI等存储系统的存储实现的详细信息。
PVC是用户容器对存储的需求,它类似于pod。pod消耗节点资源而PVC消耗PV资源。PVC可以请求具体大小的PV资源和挂载方式。
通过针对不同问题使用PV的多种特性。集群管理员需要提供多种功能不同的PV(不仅限于对一种存储的大小和访问模式不同),这些PV不需要用户了解存储类别实现,由此引入了StorageClass。
多种存储类型抽象为StorageClass, 多种StorageClass整合为集群PV资源,Pod根据模板定义创建PVC来使用这些PV资源。
volume和Claim的生命周期
资源供应
- 静态
集群管理员创建一些PV,他们带有实际存储的详细信息供用户使用。 - 动态
用户通过PVC声明需要绑定的静态PV,如果没有匹配到,将尝试为PVC动态创建卷。动态创建建立在StorageClass的基础上:PVC必须请求了具体类型的StorageClass并且集群管理员预先设置了这个class才能完成动态创建。
使用StorageClass需要在apiServer的启动参数--enable-admisson-plugins的列表中添加DefaultStorageClass来开启。
绑定
一个具有确定大小和访问模式的PVC被创建后,controlLoop将watch到此PVC并为其匹配已存在PV,匹配到时执行bind。
如果这个PV是由PVC需求而被动态创建的,controllerLoop将总是将这两个bind。
非动态创建时,用户可能获得 size大于等于所需的PV。
之后PVC和PV绑定是一对一映射的,使用ClaimRef来双向验证。
如果没有符合添加的PV,PVC将无限期保持非绑定状态直到有OK的PV可绑定转为可用状态。
使用
pod将PVC视为存储卷,集群会检查PVC绑定的存储卷并将其载入pod。其中用户可指定期望的访问模式。
一旦用户绑定了某个PVC,将可以在需要的时候无限使用
使用中的存储对象保护
这里指的是 确保在使用的pod绑定的PVC和该PVC绑定的PV不会被系统移除,造成数据的丢失。
如果用户删除Pod正在使用的PVC,这个PVC将被延迟到不再有任何pod使用它才删除。
如果管理员删除了PV,这个PV将被延迟到不再有任何PVC绑定它才删除。
当在PV、PVC中配置了Finalizers: [kubernetes.io/pvc-protection],如果被删除,将收到删除保护行为。
存储资源回收
当用户使用完卷,就可以删除这个PVC去释放资源,PVC配置的Reclaim Policy标识处理已被Claim释放的卷应该如何处理,有保留、删除、回收三种方式。
保留
保留回收策略允许手动回收资源。当PVC被删除时,对应的PV将一直存在并转为released态,但是它不能被下一个PVC使用因为上一个的数据还在,管理员可以通过以下方式手动回收:
- 删除
PV。删除后, 外部基础架构中关联的存储(例如AWS EBS,GCE PD,Azure Disk或Cinder卷)依然存在。 - 手动清理关联外部存储上的数据。
- 手动删除存储。如果要重新使用,使用外部存储创建一个新的PV。
删除
对于支持Delete Policy的存储插件,删除操作将会同时删除PV对象和外部存储(例如AWS EBS,GCE PD,Azure Disk或Cinder卷)。被动态创建的存储将继承他们的StorageClass的回收行为,默认为删除。这里根据用户期望来配置StorageClass, 否则就要在PV创建后去更新PV了。
回收 (不推荐使用) 下面的例子还没测过
如果底层存储插件支持,Recycle策略将在那块存储上执行一个基本的清理(rm -rf /thevolume/*)使其可以被下一个claim绑定。
管理与那可以将清理操作配置在pod里,让k8sControllerManager去处理它。配置方式如下:
apiVersion: v1
kind: Pod
metadata:
name: pv-recycler
namespace: default
spec:
restartPolicy: Never
volumes:
- name: vol
hostPath:
path: /any/path/it/will/be/replaced
containers:
- name: pv-recycler
image: "k8s.gcr.io/busybox"
command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"]
volumeMounts:
- name: vol
mountPath: /scrub
扩展PVC
k8s-v1.11之后,PVC默认开启可使用扩展存储。支持类型如下:
gcePersistentDisk、awsElasticBlockStore、Cinder、glusterfs、rbd、AzureFile、AzureDisk、Portworx、FlexVolume、CSI
对于底层存储StorageClass,只有配置了allowVolumeExpansion才可被PVC使用。
如果更新了PVC的大小,将触发底层存储大小的扩展。注意这里:不是去创建一个新size的PV,而是重新调整已存在存储的大小。
调整包含文件系统的卷的大小
仅当包含的文件系统为XFS、Ext3或Ext4 并且绑定的PVC为读写模式时,可以重新调整存储大小,当Pod启动时或pod运行并且基础文件系统支持联机扩展时,完成文件系统扩展。
如果将RequiresFSResize设置为true,则可以在pod重启动时调整FlexVolume大小。
调整在使用的PVC的大小
v1.15后,ExpandInUsePersistentVolume功能被开启。
当文件系统扩展后,所有使用中的PVC都将自动供其pod使用,此功能对未使用的·PVC`无效。与其他卷类型类似-当由pod使用时,flexVolume卷也可以扩展。
PV类型
每个PV对象包含spec和status描述存储卷的信息和状态,pv.name必须是一个有效的dns域名,下面是个简单的pv
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
capacity
通常,PV将有指定的大小。请参阅这里以了解容量相关的单位。
当前,存储大小是可以设置或请求的唯一资源。将来的属性可能包括IOPS,吞吐量等。
volumeMode
V1.9之前,所有PV都被创建了文件系统。现在可以设置volumeMode=block使用原始的块设备,或者设置volumeMode=filesystem去使用文件系统的。
accessModes
可对根据底层存储可支持的访问模式去选择指定PV的访问模式。例如NFS支持多种读/写模式,但NFS PV仅支持只读。
访问模式共三种:
ReadWriteOnce 存储可被挂载在单独node上进行读写
ReadOnlyMany 存储可被挂载到多个node上读
ReadWriteMany 存储可被挂载到多个node上读写
具体还得看底层存储支持情况,上层PV才能支持。
Class
通过StorageClassName指定要使用的StorageClass,指定了class的PV将绑定给明确需求此class类型的PVC。如果不指定此值,将绑定给不明确需求的PVC。
mount Options
k8s可为某些存储类型的PV指定挂载参数
Node Affinity
节点亲和性,通过selector方式限制node是否可访问。
Phase
共四种状态
Available 尚未绑定到claim的空闲资源
Bound 已绑定到claim的存储
Released 绑定的claim已经被删除,但资源还被保留在集群中
Failed 该卷自动回收失败
PVC
同PV,包含spec和status,且pvc.name必须是个有效的dns子域名
访问模式 ~
卷模式 选择以 块设备模式 或者 文件系统模式 使用PV
资源 通过storage: 8Gi 指定所需大小
选择器 其下指定selector规则匹配volume,匹配才能使用
Class
这个还是通过StorageClassName指定,分三种情况
- 指定StorageClass, 仅绑定相同class的PV
- SCName=”“ 仅绑定class=”“的PV
- 未指定SCname 如果开启了admissionPlugin并设置了DefaultStorageClass,PVC将按默认配置绑定。如果不开启或未设置,将按 =""处理。
原生块设备支持
以下卷支持原始块设备模式,包括自动创建需求。
AWSWlasticBlockStore、AzureDisk、FC、GCEPersisitentDisk、iScsi、Localvolume、RBD(Ceph Block Device)、VsphereVolume
只要底层存储类型支持,只要在对应PV、PVC的volumeMode填写Block即可
卷快照和从快照恢复卷
通过pvc中的dataSource.kind = VolumeSnapshot来配置支持从存储卷快照 中 恢复存储卷。
卷克隆
通过设置dataSource.kind = PersistentVolumeClaim ,由一个有已存在pvc克隆另一个

本文深入解析Kubernetes中PersistentVolume(PV)与PersistentVolumeClaim(PVC)的工作原理,介绍PV作为集群存储资源,PVC作为用户容器存储需求的概念,以及二者绑定机制、存储生命周期管理、动态卷供给、存储资源回收策略等内容。
589

被折叠的 条评论
为什么被折叠?



