Kubernetes——持久存储卷
持久存储卷
通过前面使用持久存储卷(Persistent Volume)的示例可知,Kubernetes 用户必须要清晰了解所用到的网络存储系统的访问细节才能完成存储卷相关的配置任务,例如:NFS存储卷的 server 和 path 字段的配置就依赖于 NFS 服务器地址和共享目录路径。这与 Kubernetes 的向用户和开发隐藏底层架构的目标有所偏离,对存储资源的使用最好也能像使用计算资源一样,用户和开发人员无须了解 Pod 资源究竟运行于哪个节点,也无须了解存储系统是什么设备以及位于何处。
为此,Kubernetes 的 Persistent Volume 子系统在用户与管理员之间添加了一个抽象层,从而使得存储系统的使用和管理职能互相解耦。
尽管 PVC 使得用户可以以抽象的方式访问存储资源,但很多时候还是会涉及 PV 的不少属性,例如,用于不同场景时设置的性能参数等。为此,集群管理员不得不通过多种方式提供多种不同的 PV 以满足用户不同的使用需求,两者衔接上的偏差必然会导致用户的需求无法全部及时有效抵得到满足。
Kubernetes 自 1.4 版起引入了一个新的资源对象 StorageClass,可用于将存储资源定义为具有显著性的类别(Class)而不是具体的 PV,例如 "fast" "slow" 或 "glod" "silver" "bronze"等。用户通过 PVC 直接向意向的类别发出申请,匹配由管理员事先创建的 PV,或者由其按需为用户动态创建 PV,这样做甚至免去了需要事先创建 PV 的过程。
PV 对存储系统的支持可通过其插件来实现,目前,Kubernetes 支持如下类型的插件(https://kubernetes.io/docs/concepts/storage/persistent-volumes#reclaiming)。
-
awsElasticBlockStore
azureDisk
azureFile
cephfs
cinder
(已弃用于 v1.18)gcePersistentDisk
glusterfs
iscsi
nfs
quobyte
(已弃用于 v1.22)rbd
storageos
(已弃用于 v1.22)vsphereVolume
一、创建 PV
PersistentVolume Spec 字段定义如下:
[root@mh-k8s-master-247-10 ~]# kubectl explain pv
KIND: PersistentVolume
VERSION: v1
DESCRIPTION:
PersistentVolume (PV) is a storage resource provisioned by an
administrator. It is analogous to a node. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Spec defines a specification of a persistent volume owned by the cluster.
Provisioned by an administrator. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistent-volumes
status <Object>
Status represents the current information/status for the persistent volume.
Populated by the system. Read-only. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistent-volumes
[root@mh-k8s-master-247-10 ~]#
主要支持以下几个通用字段,用于定义 PV 的容量、访问模式和回收策略:
- capacity <map[string]string>:当前 PV 的容量;目前,Capacity 仅支持空间设定,将来应该还可以指定 IOPS 和 throughput。
- accessModes <[]string>:尽管在 PV 层看起来并无差别,但存储设备支持及启用的功能特性却可能不尽相同。例如 NFS 存储支持多客户端同时挂载及读写操作,但也可能是在共享时仅启用了只读操作,其他存储系统也存在类似的可配置特性。因此,PV 底层的设备或许存在其特有的访问模式,用户使用时必须在其特性范围内设定其功能:
ReadWriteOnce 卷可以被一个节点以读写方式挂载;命令行中简写为 RWO。
ReadWriteOnce 访问模式也允许运行在同一节点上的多个 Pod 访问卷;命令行中简写为 RWO。
ReadOnlyMany 卷可以被多个节点以只读方式挂载;命令行中简写 ROX。
ReadWriteMany 卷可以被多个节点以读写方式挂载;命令行中简写 RWX。
ReadWriteOncePod 卷可以被单个 Pod 以读写方式挂载;命令行中简写 RWOP。
如果你想确保整个集群中只有一个 Pod 可以读取或写入该 PVC, 请使用ReadWriteOncePod 访问模式。这只支持 CSI 卷以及需要 Kubernetes 1.22 以上版本。 - persistentVolumeReclaimPolicy <string>: PV 空间被释放时的处理机制;可用类型仅为 Retain(默认)、Recycle 或 Delete,具体说明如下:
- Retain:保持不动,由管理员随后手动回收。
- Recycle:空间回收,即删除存储卷目录下的所有文件(包括子目录和隐藏目录),目前仅 NFS 和 hostPath 支持此操作。
- Delete:删除存储卷,仅部分云端存储系统支持,如 AWS EBS、GCE PD、Azure Disk 和 Cinder。
- volumeMode <string>:卷模型,用于指定此卷可被用作文件系统还是裸格式的块设备;默认为Filesystem。
- storageClassName <string>:当前 PV 所属的 StorageClass 的名称;默认为空值,即不属于任何 StorageClass。
- mountOptions <[]string>:挂载选项组成的列表,如 ro、soft 和 hard 等。
重要提醒!
每个卷同一时刻只能以一种访问模式挂载,即使该卷能够支持多种访问模式。例如,一个 GCEPersistentDisk 卷可以被某节点以 ReadWriteOnce 模式挂载,或者被多个节点以 ReadOnlyMany 模式挂载,但不可以同时以两种模式挂载。
各 PV 支持的访问模式(https://kubernetes.io/docs/concepts/storage/persistent-volumes#reclaiming)
卷插件 | ReadWriteOnce | ReadOnlyMany | ReadWriteMany | ReadWriteOncePod |
---|---|---|---|---|
AWSElasticBlockStore | ✓ | - | - | - |
AzureFile | ✓ | ✓ | ✓ | - |
AzureDisk | ✓ | - | - | - |
CephFS | ✓ | ✓ | ✓ | - |
Cinder | ✓ | - | - | - |
CSI | 取决于驱动 | 取决于驱动 | 取决于驱动 | 取决于驱动 |
FC | ✓ | ✓ | - | - |
FlexVolume | ✓ | ✓ | 取决于驱动 | - |
Flocker | ✓ | - | - | - |
GCEPersistentDisk | ✓ | ✓ | - | - |
Glusterfs | ✓ | ✓ | ✓ | - |
HostPath | ✓ | - | - | - |
iSCSI | ✓ | ✓ | - | - |
Quobyte | ✓ | ✓ | ✓ | - |
NFS | ✓ | ✓ | ✓ | - |
RBD | ✓ | ✓ | - | - |
VsphereVolume | ✓ | - | - (Pod 运行于同一节点上时可行) | - |
PortworxVolume | ✓ | - | ✓ | - |
StorageOS | ✓ | - | - | - |
kind: PersistentVolume
apiVersion: v1
metadata:
name: pv-nfs-0001
labels:
release: stable
spec:
capacity:
storage: 5Gi
volumeModel: Filesystem
accessModes:
- ReadWrieMany
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfservers=4.1
nfs:
path: "/webdata/htdocs"
server: nfs.xxx.com
使用资源的查看命令可列出 PV 资源的相关信息。创建完成的 PV 资源可能处于下列四种状态中的某一种,它们代表着 PV 资源生命周期中的各个阶段。
-
- Available:可用状态的自有资源,尚未被 PVC 绑定。
- Bound:已经绑定至某 PVC。
- Released:绑定的 PVC 已经被删除,但资源尚未被集群回收。
- Failed:因自动回收资源失败而处于的故障状态。
二、创建 PVC
[root@mh-k8s-master-247-10 ~]# kubectl explain pvc
KIND: PersistentVolumeClaim
VERSION: v1
DESCRIPTION:
PersistentVolumeClaim is a user's request for and claim to a persistent
volume
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Spec defines the desired characteristics of a volume requested by a pod
author. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
status <Object>
Status represents the current information/status of a persistent volume
claim. Read-only. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
[root@mh-k8s-master-247-10 ~]#
spec 字段定义常见如下:
[root@mh-k8s-master-247-10 ~]# kubectl explain pvc.spec
KIND: PersistentVolumeClaim
VERSION: v1
RESOURCE: spec <Object>
DESCRIPTION:
Spec defines the desired characteristics of a volume requested by a pod
author. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
PersistentVolumeClaimSpec describes the common attributes of storage
devices and allows a Source for provider-specific attributes
FIELDS:
accessModes <[]string>
AccessModes contains the desired access modes the volume should have. More
info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
dataSource <Object>
This field can be used to specify either: * An existing VolumeSnapshot
object (snapshot.storage.k8s.io/VolumeSnapshot - Beta) * An existing PVC
(PersistentVolumeClaim) * An existing custom resource/object that
implements data population (Alpha) In order to use VolumeSnapshot object
types, the appropriate feature gate must be enabled
(VolumeSnapshotDataSource or AnyVolumeDataSource) If the provisioner or an
external controller can support the specified data source, it will create a
new volume based on the contents of the specified data source. If the
specified data source is not supported, the volume will not be created and
the failure will be reported as an event. In the future, we plan to support
more data source types and the behavior of the provisioner may change.
resources <Object>
Resources represents the minimum resources the volume should have. More
info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
selector <Object>
A label query over volumes to consider for binding.
storageClassName <string>
Name of the StorageClass required by the claim. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
volumeMode <string>
volumeMode defines what type of volume is required by the claim. Value of
Filesystem is implied when not included in claim spec.
volumeName <string>
VolumeName is the binding reference to the PersistentVolume backing this
claim.
[root@mh-k8s-master-247-10 ~]#
- accessModes <[]string>: 当前 PVC 的访问模式,其可用模式与 PV 相同。
-
dataSource <Object>:
此字段可用于指定:
*现有VolumeSnapshot对象(snapshot.storage.k8s.io/VolumeSnapshot-Beta)
*现有PVC(PersistentVolumeClaim)
*现有自定义资源/对象实现数据填充(Alpha)以使用VolumeSnapshot对象类型,则必须启用相应的功能门(VolumeSnapshotDataSource或AnyVolumeDataSource)
如果提供程序或外部控制器可以支持指定的数据源,它将创建基于指定数据源的内容创建新卷。
如果不支持指定的数据源,将不会创建卷,并且故障将作为事件报告。未来,我们计划支持可能会更改更多数据源类型和供应器的行为。 - resources <Object>: 绑定时对 PVC 存储卷需要占用的资源量最小值;目前,PVC 的资源限定仅指其空间大小。
- selector <Object>: 绑定时对 PV 应用的标签选择器(matchLabels)或匹配条件表达式(matchExpressions),用于挑选要绑定的 PV;如果同时指定了两种挑选机制,则必须同时满足两种选择机制的 PV 才能被选出。
- storageClassName <string>: 所依赖的存储类的名称。
- volumeMode <string>: volumeMode 定义了声明所需的卷类型。用于指定此卷可被用作文件系统还是裸格式的块设备;默认为 "Filesystem"。
- volumeName <string>: 用于直接指定要绑定的 PV 的卷名。
下面的配置清单(pvc-nfs-0001.yaml 文件)定义了一个 PVC 资源示例,其选择 PV 的挑选机制是使用了标签选择器,适配的标签是 release:stable, 存储类为 slow,这会关联到前面创建的 PV 资源 pv-nfs-0001:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-nfs-0001
labels:
release: "stable"
spec:
accessModes:
- ReadWrieMany
volumeMode: Filesystem
resources:
requests:
storage: 5Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
PV是集群级别的资源,而 PVC 是隶属于名称空间的,因此,PVC 在绑定目标 PV 时不受名称空间的限制,但 Pod 引用 PVC时,则只能是属于同一名称空间中的资源。
三、在 Pod 中使用 PVC
在 Pod 资源中调用 PVC 资源,只需要在定义 volumes 时使用 persistentVolumeClaims 字段嵌套指定两个字段即可,具体如下:
[root@mh-k8s-master-247-10 ~]# kubectl explain pod.spec.volumes.persistentVolumeClaim
KIND: Pod
VERSION: v1
RESOURCE: persistentVolumeClaim <Object>
DESCRIPTION:
PersistentVolumeClaimVolumeSource represents a reference to a
PersistentVolumeClaim in the same namespace. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
PersistentVolumeClaimVolumeSource references the user's PVC in the same
namespace. This volume finds the bound PV and mounts that volume for the
pod. A PersistentVolumeClaimVolumeSource is, essentially, a wrapper around
another type of volume that is owned by someone else (the system).
FIELDS:
claimName <string> -required-
ClaimName is the name of a PersistentVolumeClaim in the same namespace as
the pod using this volume. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
readOnly <boolean>
Will force the ReadOnly setting in VolumeMounts. Default false.
[root@mh-k8s-master-247-10 ~]#
举个例子:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim