59. 持久化卷(Persistent Volume)
持久化卷(Persistent Volume)
本文档介绍了PersistentVolume
的当前状态。建议您在阅读本文档前先熟悉 volume。
介绍
对于管理计算资源来说,管理存储资源明显是另一个问题。PersistentVolume
子系统为用户和管理员提供了一个PersistentVolume
和 PersistentVolumeClaim
。
PersistentVolume
(PV)是由管理员设置的存储,它是集群的一部分。就像节点是集群中的资源一样,
PersistentVolumeClaim
(PVC)是用户存储的请求。它与
虽然 PersistentVolumeClaims
允许用户使用抽象存储资源,但用户需要具有不同性质(例如性能)的 PersistentVolume
来解决不同的问题。集群管理员需要能够提供各种各样的 PersistentVolume
,这些PersistentVolume
的大小和访问模式可以各有不同,但不需要向用户公开实现这些卷的细节。对于这些需求,StorageClass
资源可以实现。
请参阅工作示例的详细过程。
卷和声明的生命周期
配置(Provision)
有两种方式来配置
静态
集群管理员创建一些
动态
根据 StorageClasses
,当管理员创建的静态PersistentVolumeClaim
时,集群可能会尝试动态地为
绑定
在动态配置的情况下,用户创建或已经创建了具有特定存储量的 PersistentVolumeClaim
以及某些访问模式。PersistentVolumeClaim
绑定是排他性的,不管它们是如何绑定的。
如果没有匹配的卷,声明将无限期地保持未绑定状态。随着匹配卷的可用,声明将被绑定。例如,配置了许多
使用
用户进行了声明,并且该声明是绑定的,则只要用户需要,绑定的persistentVolumeClaim
来调度
持久化卷声明的保护
注意:当Pending
并且Running
状态时,
当启用
您可以看到,当Teminatiing
时,Finalizers
列表中包含 kubernetes.io/pvc-protection
:
kubectl described pvc hostpath
Name: hostpath
Namespace: default
StorageClass: example-hostpath
Status: Terminating
Volume:
Labels: <none>
Annotations: volume.beta.kubernetes.io/storage-class=example-hostpath
volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers: [kubernetes.io/pvc-protection]
...
回收
用户用完PersistentVolume
的回收策略告诉集群在存储卷声明释放后应如何处理该卷。目前,
保留
保留回收策略允许手动回收资源。当 PersistentVolumeClaim
被删除时,PersistentVolume
仍然存在,
- 删除
PersistentVolume
。在删除PV 后,外部基础架构中的关联存储资产(如AWS EBS 、GCE PD、Azure Disk 或Cinder 卷)仍然存在。 - 手动清理相关存储资产上的数据。
- 手动删除关联的存储资产,或者如果要重新使用相同的存储资产,请使用存储资产定义创建新的
PersistentVolume
。
回收
如果存储卷插件支持,回收策略会在rm -rf / thevolume / *
但是,管理员可以使用如此处所述的volumes
规范,如下面的示例所示:
apiVersion: v1
kind: Pod
metadata:
name: pv-recycler
namespace: default
spec:
restartPolicy: Never
volumes:
- name: vol
hostPath:
path: /any/path/it/will/be/replaced
containers:
- name: pv-recycler
image: "k8s.gcr.io/busybox"
command:
[
"/bin/sh",
"-c",
'test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z "$(ls -A /scrub)" || exit 1',
]
volumeMounts:
- name: vol
mountPath: /scrub
但是,volumes
部分的自定义回收站模块中指定的特定路径将被替换为正在回收的卷的特定路径。
删除
对于支持删除回收策略的卷插件,删除操作将从PersistentVolume
对象,并删除外部基础架构(如StorageClass
,默认为StorageClass
,否则就必须要在
扩展持久化卷声明
- gcePersistentDisk
- awsElasticBlockStore
- Cinder
- glusterfs
- rbd
管理员可以通过将 ExpandPersistentVolumes
特性门设置为PersistentVolumeClaimResize
准入控制插件来执行对可调整大小的卷的其他验证。
一旦 PersistentVolumeClaimResize
准入插件已打开,将只允许其 allowVolumeExpansion
字段设置为
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gluster-vol-default
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://192.168.10.100:8080"
restuser: ""
secretNamespace: ""
secretName: ""
allowVolumeExpansion: true
一旦功能门和前述准入插件打开后,用户就可以通过简单地编辑声明以请求更大的 PersistentVolumeClaim
卷。这反过来将触发 PersistentVolume
后端的卷扩展。
在任何情况下都不会创建新的 PersistentVolume
来满足声明。
对于扩展包含文件系统的卷,只有在PersistentVolumeClaim
启动新的
- XFS
- Ext3、Ext4
注意:扩展
持久化卷类型
PersistentVolume
类型以插件形式实现。
- GCEPersistentDisk
- AWSElasticBlockStore
- AzureFile
- AzureDisk
- FC (Fibre Channel)
- FlexVolume
- Flocker
- NFS
- iSCSI
- RBD (Ceph Block Device)
- CephFS
- Cinder (OpenStack block storage)
- Glusterfs
- VsphereVolume
- Quobyte Volumes
- HostPath (仅限于但节点测试—— 不会以任何方式支持本地存储,也无法在多节点集群中工作)
- VMware Photon
- Portworx Volumes
- ScaleIO Volumes
- StorageOS
原始块支持仅适用于以上这些插件。
持久化卷
每个
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
容量
通常,capacity
预期。
目前,存储大小是可以设置或请求的唯一资源。未来的属性可能包括
卷模式
在
注意:该功能在
访问模式
PersistentVolume
可以以资源提供者支持的任何方式挂载到主机上。如下表所示,供应商具有不同的功能,每个
存储模式包括:
- ReadWriteOnce——该卷可以被单个节点以读
/ 写模式挂载 - ReadOnlyMany——该卷可以被多个节点以只读模式挂载
- ReadWriteMany——该卷可以被多个节点以读
/ 写模式挂载
在命令行中,访问模式缩写为:
- RWO - ReadWriteOnce
- ROX - ReadOnlyMany
- RWX - ReadWriteMany
重要!一个卷一次只能使用一种访问模式挂载,即使它支持很多访问模式。例如,
GCEPersistentDisk 可以由单个节点作为ReadWriteOnce 模式挂载,或由多个节点以ReadOnlyMany 模式挂载,但不能同时挂载。
ReadWriteOnce | ReadOnlyMany | ReadWriteMany | |
---|---|---|---|
AWSElasticBlockStore | ✓ | - | - |
AzureFile | ✓ | ✓ | ✓ |
AzureDisk | ✓ | - | - |
CephFS | ✓ | ✓ | ✓ |
Cinder | ✓ | - | - |
FC | ✓ | ✓ | - |
FlexVolume | ✓ | ✓ | - |
Flocker | ✓ | - | - |
GCEPersistentDisk | ✓ | ✓ | - |
Glusterfs | ✓ | ✓ | ✓ |
HostPath | ✓ | - | - |
iSCSI | ✓ | ✓ | - |
PhotonPersistentDisk | ✓ | - | - |
Quobyte | ✓ | ✓ | ✓ |
NFS | ✓ | ✓ | ✓ |
RBD | ✓ | ✓ | - |
VsphereVolume | ✓ | - | - (当 |
PortworxVolume | ✓ | - | ✓ |
ScaleIO | ✓ | ✓ | - |
StorageOS | ✓ | - | - |
类
storageClassName
属性设置为 StorageClass 的名称来指定该类。一个特定类别的storageClassName
的
过去,使用的是 volume.beta.kubernetes.io/storage-class
注解而不是 storageClassName
属性。这个注解仍然有效,但是将来的
回收策略
当前的回收策略包括:
- Retain(保留)——手动回收
- Recycle(回收)——基本擦除(
rm -rf /thevolume/*
) - Delete(删除)——关联的存储资产(例如
AWS EBS 、GCE PD、Azure Disk 和OpenStack Cinder 卷)将被删除
当前,只有
挂载选项
注意:不是所有的持久化卷类型都支持挂载选项。
以下卷类型支持挂载选项:
- GCEPersistentDisk
- AWSElasticBlockStore
- AzureFile
- AzureDisk
- NFS
- iSCSI
- RBD (Ceph Block Device)
- CephFS
- Cinder (
OpenStack 卷存储) - Glusterfs
- VsphereVolume
- Quobyte Volumes
- VMware Photon
挂载选项没有校验,如果挂载选项无效则挂载失败。
过去,使用 volume.beta.kubernetes.io/mount-options
注解而不是 mountOptions
属性。这个注解仍然有效,但在将来的
状态
卷可以处于以下的某种状态:
- Available(可用)——一块空闲资源还没有被任何声明绑定
- Bound(已绑定)——卷已经被声明绑定
- Released(已释放)——声明被删除,但是资源还未被集群重新声明
- Failed(失败)——该卷的自动回收失败
命令行会显示绑定到
PersistentVolumeClaim
每个
kind: PersistentVolumeClaim
apiVersion: v1
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] }
访问模式
在请求具有特定访问模式的存储时,声明使用与卷相同的约定。
卷模式
声明使用与卷相同的约定,指示将卷作为文件系统或块设备使用。
资源
像
选择器
声明可以指定一个标签选择器来进一步过滤该组卷。只有标签与选择器匹配的卷可以绑定到声明。选择器由两个字段组成:
- matchLabels:
volume 必须有具有该值的标签 - matchExpressions:这是一个要求列表,通过指定关键字,值列表以及与关键字和值相关的运算符组成。有效的运算符包括
In 、NotIn、Exists 和DoesNotExist 。
所有来自 matchLabels
和 matchExpressions
的要求都被“与”在一起——它们必须全部满足才能匹配。
类
声明可以通过使用属性 storageClassName
指定 StorageClass 的名称来请求特定的类。只有所请求的类与storageClassName
的
storageClassName
设置为 ""
的""
storageClassName
的DefaultStorageClass
准入控制插件,集群对其进行不同处理。
- 如果打开了准入控制插件,管理员可以指定一个默认的
StorageClass
。所有没有StorageClassName
的PVC 将被绑定到该默认的PV 。通过在StorageClass
对象中将注解storageclass.kubernetes.io/is-default-class
设置为 “true” 来指定默认的StorageClass
。如果管理员没有指定缺省值,那么集群会响应PVC 创建,就好像关闭了准入控制插件一样。如果指定了多个默认值,则准入控制插件将禁止所有PVC 创建。 - 如果准入控制插件被关闭,则没有默认
StorageClass
的概念。所有没有storageClassName
的PVC 只能绑定到没有类的PV 。在这种情况下,没有storageClassName
的PVC 的处理方式与storageClassName
设置为""
的PVC 的处理方式相同。
根据安装方法的不同,默认的 StorageClass
可以在安装过程中通过插件管理器部署到
当selector
,除了请求一个 StorageClass
之外,这些需求被“与”在一起:只有被请求的类的
注意:目前,具有非空 selector
的
过去,使用注解 volume.beta.kubernetes.io/storage-class
而不是 storageClassName
属性。这个注解仍然有效,但是在未来的
声明作为卷
通过将声明用作卷来访问存储。声明必须与使用声明的PersistentVolume
。该卷然后被挂载到主机的
kind: Pod
apiVersion: v1
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: dockerfile/nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
命名空间注意点
PersistentVolumes
绑定是唯一的,并且由于 PersistentVolumeClaims
是命名空间对象,因此只能在一个命名空间内挂载具有“多个”模式(ROX
RWX
)的声明。
原始块卷支持
原始块卷的静态配置在
使用原始块卷作为持久化卷
apiVersion: v1
kind: PersistentVolume
metadata:
name: block-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
volumeMode: Block
persistentVolumeReclaimPolicy: Retain
fc:
targetWWNs: ["50060e801049cfd1"]
lun: 0
readOnly: false
持久化卷声明请求原始块卷
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
resources:
requests:
storage: 10Gi
在Pod 规格配置中为容器添加原始块设备
apiVersion: v1
kind: Pod
metadata:
name: pod-with-block-volume
spec:
containers:
- name: fc-container
image: fedora:26
command: ["/bin/sh", "-c"]
args: ["tail -f /dev/null"]
volumeDevices:
- name: data
devicePath: /dev/xvda
volumes:
- name: data
persistentVolumeClaim:
claimName: block-pvc
注意:当为
绑定块卷
如果用户通过使用 PersistentVolumeClaim
规范中的 volumeMode
字段指示此请求来请求原始块卷,则绑定规则与以前不认为该模式为规范一部分的版本略有不同。
下面是用户和管理员指定请求原始块设备的可能组合的表格。该表指示卷是否将被绑定或未给定组合。静态设置的卷的卷绑定矩阵:
PV volumeMode | PVC volumeMode | 结果 |
---|---|---|
unspecified | unspecified | 绑定 |
unspecified | Block | 不绑定 |
unspecified | Filesystem | 绑定 |
Block | unspecified | 不绑定 |
Block | Block | 绑定 |
Block | Filesystem | 不绑定 |
Filesystem | Filesystem | 绑定 |
Filesystem | Block | 不绑定 |
Filesystem | unspecified | 绑定 |
注意:
编写可移植配置
如果您正在编写在多种集群上运行并需要持久存储的配置模板或示例,我们建议您使用以下模式:
- 要在您的在配置组合中包含
PersistentVolumeClaim
对象(与Deployment 、ConfigMap 等一起) 。 - 不要在配置中包含
PersistentVolume
对象,因为用户实例化配置可能没有创建PersistentVolume
的权限。 - 给用户在实例化模板时提供存储类名称的选项。
- 如果用户提供存储类名称,则将该值放入
persistentVolumeClaim.storageClassName
字段中。如果集群具有由管理员启用的StorageClass ,这将导致PVC 匹配正确的存储类别。 - 如果用户未提供存储类名称,则将
persistentVolumeClaim.storageClassName
字段保留为nil 。- 这将导致使用集群中默认的
StorageClass 为用户自动配置PV 。许多集群环境都有默认的StorageClass ,或者管理员可以创建自己的默认StorageClass 。
- 这将导致使用集群中默认的
- 如果用户提供存储类名称,则将该值放入
- 在您的工具中,请注意一段时间之后仍未绑定的
PVC ,并向用户展示它们,因为这表示集群可能没有动态存储支持(在这种情况下用户应创建匹配的PV ) ,或集群没有存储系统(在这种情况下用户不能部署需要PVC 的配置) 。
原文地址:https://kubernetes.io/docs/concepts/storage/persistent-volumes/
译者:rootsongjc