一 共享存储
1.1 共享存储作用
Kubernetes 对于有状态的容器应用或者对数据需要持久化的应用, 不仅需要将容器内的目录挂载到宿主机的目录或者 emptyDir 临时存储卷, 而且需要更加可靠的存储来保存应用产生的重要数据, 以便容器应用在重建之后仍然可以使用之前的数据.
1.2 共享存储资源
为了能够屏蔽底层存储实现的细节, 便于使用和管理, Kubernetes 从 1.0 版本就引入 PersistentVolume(PV)和 PersistentVolumeClaim(PVC)两个资源对象来实现对存储的管理子系统.
PV 是对底层网络共享存储的抽象, 将共享存储定义为一种 "资源", 比如 Node 也是一种容器应用可以 "消费" 的资源. PV 由管理员创建和配置, 它与共享存储的具体实现直接相关, 例如 GlusterFS,iSCSI,RBD 或 GCE 或 AWS 公有云提供的共享存储, 通过插件式的机制完成与共享存储的对接, 以供应用访问和使用.
PVC 则是用户对存储资源的一个 "申请". 就像 Pod"消费"Node 的资源一样, PVC 能够 "消费"PV 资源. PVC 可以申请特定的存储空间和访问模式.
若使用 PVC"申请" 到一定的存储空间仍然不能满足应用对存储设备的需求. 比如通常应用程序都会对存储设备的特性和性能有不同的要求, 包括读写速度, 并发性能, 数据冗余等更高的要求, 因此 Kubernetes 从 1.4 版本开始引入了一个新的资源对象 StorageClass, 用于标记存储资源的特性和性能.
Kubernetes 1.6 版本时, StorageClass 和动态资源供应的机制得到了完善, 实现了存储卷的按需创建. 通过 StorageClass 的定义, 管理员可以将存储资源定义为某种类别(Class), 正如存储设备对于自身的配置描述(Profile), 例如 "快速存储"" 慢速存储 ""有数据冗余"" 无数据冗余 " 等. 用户根据 StorageClass 的描述就能够直观地得知各种存储资源的特性, 就可以根据应用对存储资源的需求去申请存储资源.
Kubernetes 从 1.9 版本开始引入容器存储接口 Container Storage Interface(CSI)机制, 目标是在 Kubernetes 和外部存储系统之间建立一套标准的存储管理接口, 通过该接口为容器提供存储服务, 类似于 CRI(容器运行时接口)和 CNI(容器网络接口).
二 PV
2.1 PV 详解
PV 作为存储资源, 主要包括存储能力, 访问模式, 存储类型, 回收策略, 后端存储类型等关键信息的设置.
示例 1: 如下声明的 PV 具有如下属性: 5GiB 存储空间, 访问模式为 ReadWriteOnce, 存储类型为 slow(要求在系统中已存在名为 slow 的 StorageClass), 回收策略为 Recycle, 并且后端存储类型为 nfs(设置了 NFS Server 的 IP 地址和路径).
- [root@k8smaster01 study]# vi nfspv01.YAML
- 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 类型如下:
AWSElasticBlockStore:AWS 公有云提供的 ElasticBlockStore.
AzureFile:Azure 公有云提供的 File.
AzureDisk:Azure 公有云提供的 Disk.
CephFS: 一种开源共享存储系统.
FC(FibreChannel): 光纤存储设备.
FlexVolume: 一种插件式的存储机制.
Flocker: 一种开源共享存储系统.
GCEPersistentDisk:GCE 公有云提供的 PersistentDisk.
Glusterfs: 一种开源共享存储系统.
HostPath: 宿主机目录, 仅用于单机测试.
iSCSI:iSCSI 存储设备.
Local: 本地存储设备, 从 Kubernetes1.7 版本引入, 到 1.14 版本时更新为稳定版, 目前可以通过指定块 (Block) 设备提供 LocalPV, 或通过社区开发的 sig-storage-local-static-provisioner 插件 (https://github.com/kubernetes-sigs/sigstorage-local-static-provisioner) 来管理 LocalPV 的生命周期.
NFS: 网络文件系统.
PortworxVolumes:Portworx 提供的存储服务.
QuobyteVolumes:Quobyte 提供的存储服务.
RBD(CephBlockDevice):Ceph 块存储.
ScaleIOVolumes:DellEMC 的存储设备.
StorageOS:StorageOS 提供的存储服务.
VsphereVolume:VMWare 提供的存储系统.
2.2 PV 配置参数
存储能力(Capacity)
描述存储设备具备的能力, 目前仅支持对存储空间的设置(storage=xx), 未来可能加入 IOPS, 吞吐率等指标的设置.
存储卷模式(VolumeMode)
Kubernetes 从 1.13 版本开始引入存储卷类型的设置 (volumeMode=xxx), 可选项包括 Filesystem(文件系统) 和 Block(块设备), 默认值为 Filesystem. 目前有以下 PV 类型支持块设备类型:
- AWSElasticBlockStore
- AzureDisk
- FC
- GCEPersistentDisk
- iSCSI
- Localvolume
- RBD(CephBlockDevice)
- VsphereVolume(alpha)
示例 1: 使用块设备的 PV 定义.
- [root@k8smaster01 study]# vi blockpv01.YAML
- apiVersion: v1
- kind PersistentVolume
- metadata:
- name: block-pv
- spec:
- capacity:
- storage: 10Gi
- accessNodes:
- - ReadWriteOnce
- persistentVolumeReclaimPolicy: Retain
- volumeMode: Block
- fc:
- targetWWNs: ["50060e801049cfd1"]
- lun: 0
- readOnly: false
访问模式(Access Modes)
对 PV 进行访问模式的设置, 用于描述用户的应用对存储资源的访问权限, 访问模式如下:
ReadWriteOnce(RWO): 读写权限, 并且只能被单个 Node 挂载.
ReadOnlyMany(ROX): 只读权限, 允许被多个 Node 挂载.
ReadWriteMany(RWX): 读写权限, 允许被多个 Node 挂载.
某些 PV 可能支持多种访问模式, 但 PV 在挂载时只能使用一种访问模式, 多种访问模式不能同时生效.
存储类别(Class)PV
可以设定其存储的类别, 通过 storageClassName 参数指定一个 StorageClass 资源对象的名称. 具有特定类别的 PV 只能与请求了该类别的 PVC 进行绑定. 未设定类别的 PV 则只能与不请求任何类别的 PVC 进行绑定.
回收策略(ReclaimPolicy)
通过 PV 定义中的 persistentVolumeReclaimPolicy 字段进行设置, 可选项保留 (Retain), 回收(Recycle) 和删除(Delete).
保留: 保留数据, 需要手工处理.
回收空间: 简单清除文件的操作(例如执行 rm-rf/thevolume/* 命令).
删除: 与 PV 相连的后端存储完成 Volume 的删除操作(如 AWSEBS,GCEPD,AzureDisk,OpenStackCinder 等设备的内部 Volume 清理).
目前, 只有 NFS 和 HostPath 两种类型的存储支持 Recycle 策略;
AWSEBS,GCEPD,Azure Disk 和 Cinder volumes 支持 Delete 策略.
挂载参数(MountOptions)
在将 PV 挂载到一个 Node 上时, 根据后端存储的特点, 可能需要设置额外的挂载参数, 可以根据 PV 定义中的 mountOptions 字段进行设置.
示例 2: 对一个类型为 gcePersistentDisk 的 PV 设置挂载参数.
- [root@k8smaster01 study]# vi gccpv01.YAML
- apiVersion: "v1"
- kind: "PersistentVolume"
- metadata:
- name: gce-disk-1
- spec:
- capacity:
- storage: "10Gi"
- accessModes:
- - "ReadWriteOnce"
- mountOptions:
- - hard
- - nolock
- - nfsvers=3
- gcePersistentDisk:
- fsType: "ext4"
- pdName: "gce-disk-1"
提示: 以下 PV 类型支持设置挂载参数:
- AWSElasticBlockStore
- AzureDisk
- AzureFile
- CephFS
- Cinder(OpenStackblockstorage)
- GCEPersistentDisk
- Glusterfs
- NFS
- QuobyteVolumes
- RBD(CephBlockDevice)
- StorageOS
- VsphereVolume
- iSCSI
节点亲和性(NodeAffinity)
PV 可以设置节点亲和性来限制只能通过某些 Node 访问 Volume, 可以在 PV 定义中的 nodeAffinity 字段进行设置. 使用这些 Volume 的 Pod 将被调度到满足条件的 Node 上.
示例 3:
- [root@k8smaster01 study]# vi affpv01.YAML
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: example-local-pv
- spec:
- capacity:
- storage: 5Gi
- accessModes:
- - ReadWriteOnce
- persistentVolumeReclaimPolicy: Delete
- storageClassName: local-storage
- local:
- path: /mnt/disks/ssd1
- nodeAffinity:
- required:
- nodeSelectorTerms:
- - mathExpressions:
- - key: kubernetes.io/hostname
- operator: In
- values:
- - my-node
注意: 这个参数仅用于 Local 类型的存储卷.
三 PVC 详解
3.1 PVC 使用
PVC 作为用户对存储资源的需求申请, 主要包括存储空间请求, 访问模式, PV 选择条件和存储类别等信息的设置.
示例 1: 申明 PVC, 具有如下属性: 申请 8GiB 存储空间, 访问模式为 ReadWriteOnce,PV 选择条件为包含标签 "release=stable" 并且包含条件为 "environment In [dev]" 的标签, 存储类别为 "slow"(要求在系统中已存在名为 slow 的 StorageClass).
- [root@k8smaster01 study]# vi myclaim01.YAML
- kind: PersistentVolumeClaim
- apiVersion: v1
- metadata:
- name: myclaim
- spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 8Gi
- storageClassName: slow
- selector:
- matchLabels:
- release: "stable"
- matchExpressions:
- - {key: enviroment, operator: In, values: [dev] }
3.2 PVC 配置详解
PVC 的关键配置参数说明如下:
资源请求(Resources): 描述对存储资源的请求, 目前仅支持 request.storage 的设置, 即存储空间大小.
访问模式(AccessModes):PVC 也可以设置访问模式, 用于描述用户应用对存储资源的访问权限. 其三种访问模式的设置与 PV 的设置相同.
存储卷模式(VolumeModes):PVC 也可以设置存储卷模式, 用于描述希望使用的 PV 存储卷模式, 包括文件系统和块设备.
PV 选择条件(Selector): 通过对 LabelSelector 的设置, 可使 PVC 对于系统中已存在的各种 PV 进行筛选. 系统将根据标签选出合适的 PV 与该 PVC 进行绑定. 选择条件可以使用 matchLabels 和 matchExpressions 进行设置, 如果两个字段都设置了, 则 Selector 的逻辑将是两组条件同时满足才能完成匹配.
存储类别(Class):PVC 在定义时可以设定需要的后端存储的类别(通过 storageClassName 字段指定), 以减少对后端存储特性的详细信息的依赖. 只有设置了该 Class 的 PV 才能被系统选出, 并与该 PVC 进行绑定. PVC 也可以不设置 Class 需求. 如果 storageClassName 字段的值被设置为空(storageClassName=""), 则表示该 PVC 不要求特定的 Class, 系统将只选择未设定 Class 的 PV 与之匹配和绑定. PVC 也可以完全不设置 storageClassName 字段, 此时将根据系统是否启用了名为 DefaultStorageClass 的 admissioncontroller 进行相应的操作.
未启用 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.
注意, 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".
四 PV 和 PVC 生命周期管理
4.1 PV 生命周期
某个 PV 在生命周期中可能处于以下 4 个阶段 (Phaes) 之一.
Available: 可用状态, 还未与某个 PVC 绑定.
Bound: 已与某个 PVC 绑定.
Released: 绑定的 PVC 已经删除, 资源已释放, 但没有被集群回收.
Failed: 自动资源回收失败.
4.2 PVC 生命周期
将 PV 看作可用的存储资源, PVC 则是对存储资源的需求, PV 和 PVC 的相互关系遵循如下所示关系:
4.3 资源供应
Kubernetes 支持两种资源的供应模式: 静态模式 (Static) 和动态模式(Dynamic), 资源供应的目的就是创建好 PV.
静态模式: 集群管理员手工创建许多 PV, 在定义 PV 时需要将后端存储的特性进行设置.
动态模式: 集群管理员无须手工创建 PV, 而是通过 StorageClass 的设置对后端存储进行描述, 标记为某种类型. 此时要求 PVC 对存储的类型进行声明, 系统将自动完成 PV 的创建及与 PVC 的绑定.
注意; PVC 可以声明 Class 为 "", 说明该 PVC 禁止使用动态模式.
4.4 资源绑定
在用户定义好 PVC 之后, 系统将根据 PVC 对存储资源的请求 (存储空间和访问模式) 在已存在的 PV 中选择一个满足 PVC 要求的 PV, 一旦找到, 就将该 PV 与用户定义的 PVC 进行绑定, 用户的 Pod 应用就可以使用这个 PVC 了.
如果在系统中没有满足 PVC 要求的 PV,PVC 则会无限期处于 Pending 状态, 直到等到系统管理员创建了一个符合其要求的 PV.
PV 一旦绑定到某个 PVC 上, 就会被这个 PVC 独占, 不能再与其他 PVC 进行绑定了. 在这种情况下, 当 PVC 申请的存储空间比 PV 的少时, 整个 PV 的空间就都能够为 PVC 所用, 可能会造成资源的浪费.
如果资源供应使用的是动态模式, 则系统在为 PVC 找到合适的 StorageClass 后, 将自动创建一个 PV 并完成与 PVC 的绑定.
4.5 资源使用
Pod 使用 Volume 的定义, 将 PVC 挂载到容器内的某个路径进行使用. Volume 的类型为 persistentVolumeClaim. 在容器应用挂载了一个 PVC 后, 就能被持续独占使用.
不过, 多个 Pod 可以挂载同一个 PVC, 由应用程序自身考虑多个实例共同访问一块存储空间的问题.
4.6 资源释放
当用户对存储资源使用完毕后, 用户可以删除 PVC, 与该 PVC 绑定的 PV 将会被标记为 "已释放", 但还不能立刻与其他 PVC 进行绑定. 通过之前 PVC 写入的数据可能还被留在存储设备上, 只有在清除之后该 PV 才能再次使用.
4.7 资源回收
对于 PV, 可以设定回收策略, 用于设置与之绑定的 PVC 释放资源之后如何处理遗留数据的问题. 只有 PV 的存储空间完成回收, 才能供新的 PVC 绑定和使用.
静态资源供应模式下, PV,PVC,StorageClass 及 Pod 使用 PVC 的原理释义说明:
动态资源供应模式下, PV,PVC,StorageClass 及 Pod 使用 PVC 的原理释义说明:
提示: 更多 StorageClass 见《044. 集群存储 - StorageClass》.
更多存储类型参考: https://www.cnblogs.com/Irving/p/9847060.html
来源: https://www.cnblogs.com/itzgr/p/12573644.html