在k8s上如果直接在pod上,以Volumes的形式定义存储卷然后挂载,那就要求所有使用挂载卷的用户必须对所使用的存储有所了解,否则用户将无法使用存储卷。k8s为了解决这种使用门槛,从而引入了PV和PVC的概念,让用户无需直接面对存储。

PV和PVC概念

PVC:Persistent Volume Claim,持久卷申请,简称PVC;k8s上标准的资源类型之一;由用户使用;名称空间级别;

PV:Persistent Volume,持久卷,可被PVC绑定;而PV一定要与某个真正的存储空间(一般是网络存储服务上的存储空间)对应起来,才能真正存储数据。由集群管理员负责管理。集群级别。

pv和pvc的使用逻辑

pv&pvc

为了更方便用户的使用,k8s在存储卷上加入了中间层,用户需要使用存储卷时,只需要向PVC申请所需要的存储卷大小和相关参数,PVC会从后端的PV中自动挑出一个符合的PV将其绑定到pod之上。但是这种方式还存在一个弊端,PV必须要预先创建好,如果PV没有创建,那么PVC将无法从后段的PV中跳出可用的存储。从而让容器处于pending状态。

pv&pvc

k8s为了解决上述问题,还引入了Storage Class,按用户的需求动态的生成PV。

StorageClass

StorageClass是为pv和pvc额外模拟出一层名称空间。PV是集群级别的,而PVC是名称空间级别的,其可以绑定任何PV,但为了能收束以下PVC的作用范围,所以使用模板来进行定义。

StorageClass的作用:

  • 一个PVC一旦属于某个模板(StorageClass)。那么其只能在当前的SC下找PV。
  • 作为创建PV的模板,可以将某个存储服务与SC关联起来,并且将该存储服务的管理接口提供给SC,从而让SC能狗仔存储服务上CRUD存储单元。
  • 在同一个SC上声明PVC时,若无现存可匹配的PV,则SC能够调用管理接口直接创建出一个符合PVC声明的需求的PV来,这种PV的提供机制就称为Dynamic Provision(动态预配)。

存储卷使用逻辑

正常逻辑如下:

存储卷使用逻辑

Pod的使用步骤

Pod使用这类存储的步骤:

  1. Admin:创建好PV;
  2. User: 按需创建PVC,而后创建Pod,在Pod调用persistentVolumeClaim类型的存储卷插件调用同一个名称空间中的PVC资源;

PV资源清单字段

除了存储卷插件之外,PersistentVolume资源规范Spec字段主要支持嵌套以下几个通用字段,它们用于定义PV的容量、访问模式和回收策略等属性。

1
2
3
4
5
6
7
capacity <map[string]string>:指定PV的容量;目前,Capacity仅支持存储容量设定,将来还应该可以指定IOPS和吞吐量(throughput)。
accessModes <[]string>:指定当前PV支持访问模式;存储系统支持存取能力大体可分为ReadWriteOnce(单路读写)、ReadOnlyMany(多路只读)和ReadWriteMany(多路读写)三种类型,某个特定的存储系统可能会支持其中的部分或全部的能力。
persistentVolumeReclaimPolicy <string>:PV空间被释放时的处理机制;可用类型仅为Retain(默认)、Recycle或Delete。目前,仅nfs和hostPath支持Recycle策略,也仅有部分存储系统支持Delete策略。
volumeMode <string>:该PV的卷模型,用于指定此存储卷被格式化为文件系统使用还是直接使用裸格式的块设备;默认值为Filesystem,仅块设备接口的存储系统支持该功能。
storageClassName <string>:当前PV所属的StorageClass资源的名称,指定的存储类需要事先存在;默认为空值,即不属于任何存储类。
mountOptions <string>:挂载选项组成的列表,例如ro、soft和hard等。
nodeAffinity <Object>:节点亲和性,用于限制能够访问该PV的节点,进而会影响到使用与该PV关联的PVC的Pod的调度结果。

PVC资源清单字段

定义PVC时,用户可通过访问模式(accessModes)、数据源(dataSource)、存储资源空间需求和限制(resources)、存储类、标签选择器、卷模型和卷名称等匹配标准来筛选集群上的PV资源,其中,resources和accessModes是最重的筛选标准。PVC的Spec字段的可嵌套字段有如下几个。

accessModes <[]string>:PVC的访问模式;它同样支持RWO、RWX和ROX三种模式;

1
2
3
4
5
6
dataSources <Object>:用于从指定的数据源恢复该PVC卷,它目前支持的数据源包括一个现在卷快照对象(snapshot.storage.k8s.io/VolumeSnapshot)、一个既有PVC对象(PersistentVolumeClaim)或一个既有的用于数据转存的自定义资源对象(resource/object);
resources <Object>:声明使用的存储空间的最小值和最大值;目前,PVC的资源限定仅支持空间大小一个维度;
selector <Object>:筛选PV时额外使用的标签选择器(matchLabels)或匹配条件表达式(matchExpressions);
storageClassName <string>:该PVC资源隶属的存储类资源名称;指定了存储类资源的PVC仅能在同一个存储类下筛选PV资源,否则,就只能从所有不具有存储类的PV中进行筛选;
volumeMode <string>:卷模型,用于指定此卷可被用作文件系统还是裸格式的块设备;默认值为Filesystem;
volumeName <string>:直接指定要绑定的PV资源的名称。

StorageClass资源清单字段

StorageClass资源的期望状态直接与apiVersion、kind和metadata定义于同一级别而无须嵌套于spec字段中,它支持使用的字段包括如下几个:

1
2
3
4
5
6
7
allowVolumeExpansion <boolean>:是否支持存储卷空间扩展功能;
allowedTopologies <[]Object>:定义可以动态配置存储卷的节点拓扑,仅启用了卷调度功能的服务器才会用到该字段;每个卷插件都有自己支持的拓扑规范,空的拓扑选择器表示无拓扑限制;
provisioner <string>:必选字段,用于指定存储服务方(provisioner,或称为预备器),存储类要依赖该字段值来判定要使用的存储插件以便适配到目标存储系统;Kubernetes内建支持许多的Provisioner,它们的名字都以kubernetes.io/为前缀,例如kubernetes.io/glusterfs等;
parameters <map[string]string>:定义连接至指定的Provisioner类别下的某特定存储时需要使用的各相关参数;不同Provisioner的可用的参数各不相同;
reclaimPolicy <string>:由当前存储类动态创建的PV资源的默认回收策略,可用值为Delete(默认)和Retain两个;但那些静态PV的回收策略则取决于它们自身的定义;
volumeBindingMode <string>:定义如何为PVC完成预配和绑定,默认值为VolumeBindingImmediate;该字段仅在启用了存储卷调度功能时才能生效;
mountOptions <[]string>:由当前类动态创建的PV资源的默认挂载选项列表。