1.共享存储机制
Kubernetes对于有状态的容器应用或者对数据需要持久化的应用,不仅需要将容器内的目录挂载到宿主机的目录或者emptyDir临时存储卷,而且需要更加可靠的存储来保障应用产生的重要数据,以便容器应用在重建后仍然可以使用以前的数据。为了能屏蔽底层存储实现的细节,让用户更加方便,Kubernetes引入PersistentVolume(PV)和PersistentVolumeClaim(PVC)两个资源对象来实现对存储的管理子系统。
PV是对底层网络共享存储的抽象,将共享存储定义为一种“资源”。PV由管理人员创建和配置,它与共享存储的具体实现直接相关,通过插件式的机制完成于共享存储的对接,以供应用访问和使用。
PVC是用户对存储资源的一个“申请”。就像Pod“消费”Node的资源一样,PVC能够“消费”PV资源。PVC可以申请特定的存储空间和访问模式。
使用PVC“申请”到一定的存储空间仍然不能满足应用对存储设备的各种需求。通常应用程序都会对存储设备的特性和性能有不同的要求,包括读写速度、并发性能、数据冗余等更高的要求,Kubernetes从1.4版本开始引入了一个新的资源对象StorageClass,用于标记存储资源的特性和性能。到1.6版本时,StorageClass和动态资源供应的机制得到完善,实现了存储卷的按需创建,在共享存储的自动化管理中实现了重要的一步。
通过StorageClass的定义,管理员可以将存储资源定义为某种类别(Class),正如存储设备对于自身的描述(Profile),例如“快速存储”“慢速存储”“有数据冗余存储”“无数据荣誉存储”等。用户根据StorageClass的描述能够直观地得知各种资源存储的特性,就可以根据应用对存储资源的需求去申请存储资源了。
Kubernetes从1.9版本开始引入容器存储接口Container StorageInterface(CSI)机制,目标是在Kubernetes和外部存储系统之间建立一套标准的存储管理接口,通过该接口为容器提供存储服务,类似于CRI(容器运行时接口)和CNI(容器网络接口)。
2.PV详解
PV作为存储资源,主要包括存储能力、访问模式、存储类型、回收策略、后端存储类型等关键信息的设置。
# 5GiB存储空间,访问模式为ReadWriteOnce,存储类型为slow(要求系统中已存在名为slow的StorageClass),回收策略为Recycle,并且后端存储类型为nfs(设置了NFS Server的IP地址和路径)
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
nfs:
path: /tmp
server: 172.17.0.2
Kubernetes支持的PV类型如下:
- FC(Fibre Channl):光纤存储设备。
- FlexVolume:一直插件式的存储机制
- GCEPersistentDisk:GCE公有云提供的PersistentDisk。
- Clusterfs:一种开源共享存储系统。
- HostPath:宿主机目录,仅用于单机测试。
- iSCSI:iSCSI存储设备。
- Local:本地存储设备,从Kubernetes1.7版本引入,到1.14版本时更新为稳定版,目前可以通过指定块(Block)设备提供LocalPV,或通过社区开发的 sig-storage-local-static-provisioner插件来管理Local PV的生命周期。
- NFS:网络文件系统。
- Portworx Volumes:Portworx提供的存储服务。
- Quobyte Volumes:Quobyte提供的存储服务。
- RBD(Ceph Block Device):Ceph块存储。
- ScaleIO Volumes:DellEMC的存储设备。
- StorageOS:StorageOS提供的存储服务。
-
2.1.PV关键配置参数
(1)存储能力(Capacity)
描述存储设备具备的能力,目前仅支持对存储空间的设置(storage=xx),未来可能加入IOPS、吞吐量等指标设置。
(2)存储卷模式(Volume Mode)
Kubernetes从1.13版本开始引入存储卷类型的设置(volumeMode=xxx),可选项包括Filesystem(文件系统)和Block(块设备),默认值为Filesystem。
(3)访问模式
用于描述用户的应用对存储资源的访问权限。访问模式如下: ReadWriteOnce(RWO):读写权限,并且只能被单个Node挂载。
- ReadOnlyMany(ROX):只读权限,允许被多个Node挂载。
- ReadWriteMany(RWX):读写权限,允许被多个Node挂载。
某些PV可能支持多种访问权限,但PV在挂载时只能使用一种访问模式,多种访问模式不同同时生效。
(4)存储类别(Class)
PV可以设置其存储类别,通过storageClassName参数指定一个StorageClass资源对象的名称。具有特定类别的PV只能与请求了该类别的PVC进行绑定。未设定类别的PV则只能与不请求任何类别的PVC进行绑定。
(5)回收策略(Reclaim Policy)
通过PV中定义的PersistentVolumeRecliaimPolicy字段进行设置,可选项如下:
- 保留:保留数据,需要手工处理。
- 回收空间:简单清楚文件的操作。
- 删除:与PV相连的后端存储完成Volume的删除操作。
目前,只有NFS和HostPath两种类型的存储支持Recycle策略;AWS EBS、GCE PD、Azure Disk和Cinder volumes支持Delete策略。
(6)挂载参数(Mount Options)
在将PV挂载到一个Node上时,根据后端存储的特点,可能需要设置额外的挂载参数,可以根据PV定义中的mountOptions字段进行设置。
(7)节点亲和性(Node Affinity)
PV可以设置节点亲和性来限制只能通过某些Node访问Volume,可以在PV定义中的nodeAffinity字段进行设置。使用这些Volume的Pod将被调度到满足条件的Node上。
2.2.PV生命周期的各个阶段
- Available:可用状态,还未与某个PVC绑定。
- Bound:已于某个PVC绑定。
- Released:绑定的PVC已经删除,资源已经释放,但没有被集群回收。
- Faild:自动资源回收失败。
3.PVC详解
PVC作为用户对存储资源的需求申请,主要包括存储空间请求、访问模式、PV选择条件和存储类别等信息的设置。
# 申请8GiB存储空间,访问模式未ReadWriteOnce,PV选择条件包含标签“release=stable”并且包含条件为“environment In [dev]”的标签,存储类别为“slow”。
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: stable
matchExpressions:
- key: environment
operator: In
values:
- dev
PVC的关键配置参数说明:
- 资源请求(Resources):描述对存储资源的请求,目前仅支持requests.storage的设置,及存储空间大小。
- 访问模式(Access Modes):用于描述用户应用对存储资源的访问权限。其三种访问模式的设置与PV的设置相同。
- 存储卷模式(Volume Modes):用于描述希望使用的PV存储卷模式,包括文件系统和块设备。
- PV选择条件(Selector):通过对Label Selector的设置,可使PVC对于系统中已存在的各种PV进行筛选。系统将根据标签选出合适的PV与该PVC进行绑定。选择条件可以使用matchLabels和matchExpressions进行设置,如果两个字段都设置了,则Selector的逻辑将是两组条件同时满足才能完成匹配。
- 存储类别(Class):PVC在定义时可以设置需要的后端存储的类别(通过storageClassName指定),以减少对后端存储的详细信息的依赖。只有设置了该Class的PV才能被系统选出,并于该PVC进行绑定。PVC也可以不设置Class需求。如果storageClassName字段的值被设置为空(storageClassName=””),则表示该PVC不要求特定的Class,系统将只选择未设定Class的PV与之匹配和绑定。PVC也可以完全不设置storageClassName字段,此时将根据系统是否启用了名为DefaultStorageClass的admission controller进行相应的操作
- 未启用DefaultStorageClass:等效于PVC设置storageClassName的值为空(storageClassName=””),即只能选择未设定Class的PV与之匹配和绑定。
- 启用DefaultStorageClass:要求集群管理员已定义默认的StorageClass。如果在系统中不存在默认的StorageClass,则等效于不启用DefaultStorageClass的情况。如果存在默认的StorageClass,则系统将自动为PVC创建一个PV(使用默认StorageClass的后端存储),并将它们进行绑定。集群管理员设置默认StorageClass的方法为,在StorageClass的定义中加上一个annotation“storageclass.kubernetes.io/isdefault-class= true”。如果管理员将多个StorageClass都定义为default,则由于不唯一,系统将无法为PVC创建相应的PV。