网页
综合
更新时间 2026-11-13 16:49:30
持久卷 | Kubernetes
自动蜘蛛
kubernetes.io
正文约 5027 字
本文描述 Kubernetes 中的持久卷(Persistent Volumes)。 建议先熟悉卷(Volume)、 存储类(StorageClass)和 卷属性类(VolumeAttributesClass)。
存储的管理是一个与计算实例的管理完全不同的问题。 PersistentVolume 子系统为用户和管理员提供了一组 API, 将存储如何制备的细节从其如何被使用中抽象出来。 为了实现这点,我们引入了两个新的 API 资源:PersistentVolume 和 PersistentVolumeClaim。
持久卷(PersistentVolume,PV) 是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样, 也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。
持久卷申领(PersistentVolumeClaim,PVC) 表达的是用户对存储的请求,概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存)。同样 PVC 申领也可以请求特定的大小和访问模式 (例如,可以挂载为 ReadWriteOnce、ReadOnlyMany、ReadWriteMany 或 ReadWriteOncePod, 请参阅访问模式)。
尽管 PersistentVolumeClaim 允许用户消耗抽象的存储资源, 常见的情况是针对不同的问题用户需要的是具有不同属性(如,性能)的 PersistentVolume 卷。 集群管理员需要能够提供不同性质的 PersistentVolume, 并且这些 PV 卷之间的差别不仅限于卷大小和访问模式,同时又不能将卷是如何实现的这些细节暴露给用户。 为了满足这类需求,就有了存储类(StorageClass) 资源。
PV 卷是集群中的资源。PVC 申领是对这些资源的请求,也被用来执行对资源的申领检查。 PV 卷和 PVC 申领之间的互动遵循如下生命周期:
PV 卷的制备有两种方式:静态制备或动态制备。
集群管理员创建若干 PV 卷。这些卷对象带有真实存储的细节信息, 并且对集群用户可用(可见)。PV 卷对象存在于 Kubernetes API 中,可供用户消费(使用)。
如果管理员所创建的所有静态 PV 卷都无法与用户的 PersistentVolumeClaim 匹配, 集群可以尝试为该 PVC 申领动态制备一个存储卷。 这一制备操作是基于 StorageClass 来实现的:PVC 申领必须请求某个 存储类, 同时集群管理员必须已经创建并配置了该类,这样动态制备卷的动作才会发生。 如果 PVC 申领指定存储类为 "",则相当于为自身禁止使用动态制备的卷。
为了基于存储类完成动态的存储制备,集群管理员需要在 API 服务器上启用 DefaultStorageClass 准入控制器。 举例而言,可以通过保证 DefaultStorageClass 出现在 API 服务器组件的 --enable-admission-plugins 标志值中实现这点;该标志的值可以是逗号分隔的有序列表。 关于 API 服务器标志的更多信息,可以参考 kube-apiserver 文档。
用户创建一个带有特定存储容量和特定访问模式需求的 PersistentVolumeClaim 对象; 在动态制备场景下,这个 PVC 对象可能已经创建完毕。 控制平面中的控制回路监测新的 PVC 对象,寻找与之匹配的 PV 卷(如果可能的话), 并将二者绑定到一起。如果为了新的 PVC 申领动态制备了 PV 卷,则控制回路总是将该 PV 卷绑定到这一 PVC 申领。 否则,用户总是能够获得他们所请求的资源,只是所获得的 PV 卷可能会超出所请求的配置。 一旦绑定关系建立,则 PersistentVolumeClaim 绑定就是排他性的, 无论该 PVC 申领是如何与 PV 卷建立的绑定关系。PVC 申领与 PV 卷之间的绑定是一种一对一的映射, 实现上使用 ClaimRef 来记述 PV 卷与 PVC 申领间的双向绑定关系。
如果找不到匹配的 PV 卷,PVC 申领会无限期地处于未绑定状态。 当与之匹配的 PV 卷可用时,PVC 申领会被绑定。 例如,即使某集群上制备了很多 50 Gi 大小的 PV 卷,也无法与请求 100 Gi 大小的存储的 PVC 匹配。当新的 100 Gi PV 卷被加入到集群时, 该 PVC 才有可能被绑定。
Pod 将 PVC 申领当做存储卷来使用。集群会检视 PVC 申领,找到所绑定的卷, 并为 Pod 挂载该卷。对于支持多种访问模式的卷, 用户要在 Pod 中以卷的形式使用申领时指定期望的访问模式。
一旦用户有了申领对象并且该申领已经被绑定, 则所绑定的 PV 卷在用户仍然需要它期间一直属于该用户。 用户通过在 Pod 的 volumes 块中包含 persistentVolumeClaim 节区来调度 Pod,访问所申领的 PV 卷。 相关细节可参阅使用申领作为卷。
保护使用中的存储对象(Storage Object in Use Protection) 这一功能特性的目的是确保仍被 Pod 使用的 PersistentVolumeClaim(PVC) 对象及其所绑定的 PersistentVolume(PV)对象在系统中不会被删除,因为这样做可能会引起数据丢失。
当使用某 PVC 的 Pod 对象仍然存在时,认为该 PVC 仍被此 Pod 使用。
如果用户删除被某 Pod 使用的 PVC 对象,该 PVC 不会被立即移除。 PVC 对象的移除会被推迟,直至其不再被任何 Pod 使用。 此外,如果管理员删除已绑定到某 PVC 的 PV 卷,该 PV 卷也不会被立即移除。 PV 对象的移除也要推迟到该 PV 不再绑定到 PVC。
你可以看到当 PVC 的状态为 Terminating 且其 Finalizers 列表中包含 kubernetes.io/pvc-protection 时,PVC 对象是处于被保护状态的。
你也可以看到当 PV 对象的状态为 Terminating 且其 Finalizers 列表中包含 kubernetes.io/pv-protection 时,PV 对象是处于被保护状态的。
当用户不再使用其存储卷时,他们可以从 API 中将 PVC 对象删除, 从而允许该资源被回收再利用。PersistentVolume 对象的回收策略告诉集群, 当其被从申领中释放时如何处理该数据卷。 目前,数据卷可以被 Retained(保留)、Recycled(回收)或 Deleted(删除)。
回收策略 Retain 使得用户可以手动回收资源。当 PersistentVolumeClaim 对象被删除时,PersistentVolume 卷仍然存在,对应的数据卷被视为"已释放(released)"。 由于卷上仍然存在这前一申领人的数据,该卷还不能用于其他申领。 管理员可以通过下面的步骤来手动回收该卷:
如果你希望重用该存储资产,可以基于存储资产的定义创建新的 PersistentVolume 卷对象。
对于支持 Delete 回收策略的卷插件,删除动作会将 PersistentVolume 对象从 Kubernetes 中移除,同时也会从外部基础设施中移除所关联的存储资产。 动态制备的卷会继承其 StorageClass 中设置的回收策略, 该策略默认为 Delete。管理员需要根据用户的期望来配置 StorageClass; 否则 PV 卷被创建之后必须要被编辑或者修补。 参阅更改 PV 卷的回收策略。
回收策略 Recycle 已被废弃。取而代之的建议方案是使用动态制备。
如果下层的卷插件支持,回收策略 Recycle 会在卷上执行一些基本的擦除 (rm -rf /thevolume/*)操作,之后允许该卷用于新的 PVC 申领。
不过,管理员可以按参考资料中所述, 使用 Kubernetes 控制器管理器命令行参数来配置一个定制的回收器(Recycler) Pod 模板。此定制的回收器 Pod 模板必须包含一个 volumes 规约,如下例所示:
请注意,定制回收器 Pod 模板中在 volumes 部分所指定的特定路径要替换为正被回收的卷的路径。
This is a stable feature in Kubernetes, and has been since the 1.33 release. You can no longer toggle this feature (the associated feature gate has been removed).
可以在 PersistentVolume 上添加终结器(Finalizer), 以确保只有在删除对应的存储后才删除具有 Delete 回收策略的 PersistentVolume。
(在 v1.31 中引入的)终结器 external-provisioner.volume.kubernetes.io/finalizer 被同时添加到动态制备和静态制备的 CSI 卷上。
(在 v1.31 中引入的)终结器 kubernetes.io/pv-controller 被添加到动态制备的树内插件卷上,而对于静态制备的树内插件卷,此终结器将被忽略。
终结器 external-provisioner.volume.kubernetes.io/finalizer 会被添加到 CSI 卷上。下面是一个例子:
当为特定的树内卷插件启用了 CSIMigration{provider} 特性标志时,kubernetes.io/pv-controller 终结器将被替换为 external-provisioner.volume.kubernetes.io/finalizer 终结器。
这些终结器确保只有在从存储后端删除卷后,PV 对象才会被移除, 前提是 PV 的回收策略为 Delete。 这也确保了无论 PV 和 PVC 的删除顺序如何,此卷都会从存储后端被删除。
控制平面可以在集群中将 PersistentVolumeClaim 绑定到匹配的 PersistentVolume。 但是,如果你希望 PVC 绑定到特定 PV,则需要预先绑定它们。
通过在 PersistentVolumeClaim 中指定 PersistentVolume,你可以声明该特定 PV 与 PVC 之间的绑定关系。如果该 PersistentVolume 存在且未被通过其 claimRef 字段预留给 PersistentVolumeClaim,则该 PersistentVolume 会和该 PersistentVolumeClaim 绑定到一起。
绑定操作不会考虑某些卷匹配条件是否满足,包括节点亲和性等等。 控制面仍然会检查存储类、 访问模式和所请求的存储尺寸都是合法的。
此方法无法对 PersistentVolume 的绑定特权做出任何形式的保证。 如果有其他 PersistentVolumeClaim 可以使用你所指定的 PV, 则你应该首先预留该存储卷。你可以将 PV 的 claimRef 字段设置为相关的 PersistentVolumeClaim 以确保其他 PVC 不会绑定到该 PV 卷。
如果你想要使用 persistentVolumeReclaimPolicy 属性设置为 Retain 的 PersistentVolume 卷时,包括你希望复用现有的 PV 卷时,这点是很有用的。
现在,对扩充 PVC 申领的支持默认处于被启用状态。你可以扩充以下类型的卷:
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。