Kubernetes的pod本身是无状态的(stateless),生命周期通常比较短,只要出现了异常,Kubernetes就会自动创建一个新的Pod来代替它。而容器产生的数据,会随着Pod消亡而自动消失。
为了实现Pod内数据的存储管理,Kubernetes引入了两个API资源:Persistent Volume(持久卷,以下简称PV)和Persistent Volume Claim(持久卷申请,以下简称PVC)。
PV是Kubernetes集群中的一种网络存储实现,跟Node一样,也是属于集群的资源。
PV跟Docker里的Volume(卷)类似,不过会有独立于Pod的生命周期;而PVC是用户的一个存储请求,跟Pod类似。Pod消费Node的资源,PVC消费PV的资源。
PersistentVolume和PersistentVolumeClaim的正确使用方法
PersistentVolume应由集群管理员创建,而集群用户通过PersistentVolumeClaim使用管理员创建的PersistentVolume。用户不关心PersistentVolume的具体位置和具体实现,只管使用。
集群管理员创建由物理存储支持的 PersistentVolume。管理员不将卷与任何 Pod 关联。
群集用户创建一个 PersistentVolumeClaim,它将自动绑定到合适的 PersistentVolume。
用户创建使用 PersistentVolumeClaim 作为存储的 Pod。
PersistentVolume和PersistentVolumeClaim的删除顺序
显然,现有PersistentVolume后有PersistentVolumeClaim。在K8S中,PersistentVolume的删除命令kubectl delete pv <pv名>
会阻塞直到与这个PV绑定的所有PVC被删除。
PersistentVolume
不管三七二十一先放个示例:
apiVersion: v1
kind: PersistentVolume
metadata:
name: the-pv
spec:
hostPath: #这是个位于本地某个文件夹的PV
path: "/mnt/data" #文件夹的路径
capacity: #存储容量
storage: 5Gi #存储容量为5G
volumeMode: Filesystem
accessModes: #访问模式
- ReadWriteOnce #访问模式为只能由一个Pod以读写模式挂载
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
下面来一个个介绍这里面的字段。
PV的类型
上面这个PV spec
字段中的第一个hostPath
表示这个PV是个位于本地某个文件夹中。除hostPath
外,PV还支持以下类型:
GCEPersistentDisk
AWSElasticBlockStore
AzureFile
AzureDisk
CSI
FC (Fibre Channel)
FlexVolume
Flocker
NFS
iSCSI
RBD (Ceph Block Device)
CephFS
Cinder (OpenStack block storage)
Glusterfs
VsphereVolume
Quobyte Volumes
HostPath (Single node testing only -- local storage is not supported in any way and WILL NOT WORK in a multi-node cluster)
Portworx Volumes
ScaleIO Volumes
StorageOS
这些类型的在PV中的定义和在Pod的Volumes里的定义都是一回事
capacity
顾名思义,这是指这个PV的容量限制。它的单位有:T
,P
,G
,M
,K
或 Ti
,Pi
,Gi
,Mi
,Ki
,其中加i的是以1024为换算单位的。
For example, the following represent roughly the same value: 128974848, "129e6", "129M" , "123Mi".
volumeMode
volumeMode
用于指定这个PV上要不要有文件系统。volumeMode
有两种值:
Block
:PV上没有文件系统。这意味着PV挂载到容器中时是一个块设备,容器中的程序必须有处理块设备的能力才能正常使用这种PVFilesystem
:PV上有文件系统。PV挂载到容器中时是一个正常的挂载点,此为默认值。
accessModes
accessModes
指定了这个PV可以提供的访问模式。它有以下三种值:
ReadWriteOnce
-- 只能被单个节点以读写模式挂载ReadOnlyMany
-- 只能由多个节点以只读模式挂载ReadWriteMany
-- 能由多个节点以读写模式挂载
但是并不是所有的网络文件系统都支持上面这些挂载方式,因此不同类型的PV也有所不同。各种PV各自支持的accessModes
如表:
persistentVolumeReclaimPolicy
若Pod绑定了一个PVC,PVC绑定了一个PV,后来Pod删除了,那么PV中的数据要怎么处理?
Retain
-- 默认回收策略,即这些数据保留着,以便Pod再次创建时还能使用Recycle
-- 清空里面的数据,允许其他Pod绑定使用Delete
-- 不仅清空里面的数据,还把PV直接一起删了
storageClassName
StorageClass 为管理员提供了描述存储 "类" 的方法。 不同的类型可能会映射到不同的服务质量等级或备份策略,或是由集群管理员制定的任意策略。 Kubernetes 本身并不清楚各种类代表的什么。这个类的概念在其他存储系统中有时被称为 "配置文件"。
A PV with no storageClassName has no class and can only be bound to PVCs that request no particular class.
mountOptions
mountOptions
是针对不同类型PV的额外配置。目前有额外配置的类型有:
AWSElasticBlockStore
AzureDisk
AzureFile
CephFS
Cinder (OpenStack block storage)
GCEPersistentDisk
Glusterfs
NFS
Quobyte Volumes
RBD (Ceph Block Device)
StorageOS
VsphereVolume
iSCSI
Node Affinity
Note: For most volume types, you do not need to set this field. It is automatically populated for AWS EBS, GCE PD and Azure Disk volume block types. You need to explicitly set this for local volumes.
A PV can specify node affinity to define constraints that limit what nodes this volume can be accessed from. Pods that use a PV will only be scheduled to nodes that are selected by the node affinity.
PersistentVolumeClaim
不管三七二十一先放个示例:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: stable
matchExpressions:
- key: environment
operator: In
values:
- dev
创建 PersistentVolumeClaim 之后,Kubernetes 控制平面将查找满足申领要求的 PersistentVolume。 如果控制平面找到具有相同 StorageClass 的适当的 PersistentVolume,则将 PersistentVolumeClaim 绑定到该 PersistentVolume 上。
和上面的PV定义对比一下就可以发现,定义PVC的字段和定义PV的字段基本相同。不同的是,PV中的accessModes
、volumeMode
、storageClassName
是定义了PV的性质,而PVC中的这些字段是用来查找合适的PV进行绑定。
除了accessModes
、volumeMode
、storageClassName
外,还有一个用于查询PV标签的selector
和资源请求的resources
。
selector
selector
字段用于指定要绑定的PV的标签,只有标签全部匹配到的PV才能绑定。
其中的matchLabels
和matchExpressions
都是标签的匹配规则。
resources
resources
字段用于指定PVC需要的资源量,比如上面那个.spec.resources.requests.storage
表示这个PVC绑定的PV至少要有7G。