Kubernetes 1.32:卷组快照进入 Beta 阶段
卷组快照作为 Alpha 功能随 Kubernetes 1.27 版本引入。Kubernetes v1.32 最近的版本将该支持移至Beta阶段。卷组快照的支持依赖于一组用于组快照的扩展 API。这些 API 允许用户对一组卷进行崩溃一致性快照。在幕后,Kubernetes 使用标签选择器对多个 PersistentVolumeClaims 进行分组以创建快照。一个关键目标是允许你将这组快照恢复到新的卷中,并基于崩溃一致性恢复点恢复你的工作负载。
这项新功能仅支持CSI卷驱动程序。
卷组快照概述
一些存储系统提供了创建多个卷的崩溃一致性快照的能力。组快照表示对多个卷在同一时间点创建的副本。组快照可以用于创建新的卷(预填充快照数据)或将现有卷恢复到之前的状态(由快照表示)。
为什么要将卷组快照添加到 Kubernetes?
Kubernetes 卷插件系统已经提供了一个强大的抽象,自动化了块存储和文件存储的供应、附加、挂载、调整大小和快照功能。
支持所有这些功能的是 Kubernetes 工作负载可移植性的目标:Kubernetes 旨在在分布式应用和底层集群之间创建一个抽象层,以便应用可以不关心其运行集群的具体细节,且应用部署不需要集群特定知识。
已有一个VolumeSnapshot API,它提供了对持久卷创建快照的能力,以防止数据丢失或数据损坏。然而,还有一些快照功能未被 VolumeSnapshot API 覆盖。
一些存储系统支持一致性组快照,允许在同一时间点对多个卷进行快照以实现写入顺序一致性。这对于包含多个卷的应用非常有用。例如,一个应用可能将数据存储在一个卷中,将日志存储在另一个卷中。如果数据卷和日志卷的快照在不同时间创建,那么当发生灾难时,如果从这些快照恢复,应用将无法保持一致性,也无法正常工作。
确实,你可以先静默应用,然后依次对应用中的每个卷创建单独的快照,并在所有单独快照创建完成后解除应用静默。这样,你将获得应用一致性快照。
然而,有时应用静默会非常耗时,以至于你希望减少静默频率,或者根本不可能静默应用。例如,用户可能希望每周进行一次应用静默的备份,而每晚进行一次不静默应用但具有一致性组支持的备份,后者可以为组中的所有卷提供崩溃一致性。
Kubernetes 卷组快照 API
Kubernetes 对卷组快照的支持依赖于用于管理快照的三种 API 类型
- VolumeGroupSnapshot
- 由 Kubernetes 用户(或你自己的自动化工具)创建,用于请求为多个持久卷声明创建卷组快照。它包含卷组快照操作的信息,例如创建快照的时间戳以及是否已准备好使用。此对象的创建和删除代表了创建或删除集群资源(一个组快照)的意愿。
- VolumeGroupSnapshotContent
- 由快照控制器为动态创建的 VolumeGroupSnapshot 创建。它包含卷组快照的信息,包括卷组快照 ID。此对象代表集群上已供应的资源(一个组快照)。VolumeGroupSnapshotContent 对象与其创建所对应的 VolumeGroupSnapshot 具有一对一的映射关系。
- VolumeGroupSnapshotClass
- 由集群管理员创建,用于描述如何创建卷组快照,包括驱动程序信息、删除策略等。
这三种 API 类型被定义为CustomResourceDefinitions (CRD)。这些 CRD 必须安装在 Kubernetes 集群中,CSI 驱动程序才能支持卷组快照。
支持卷组快照需要哪些组件
卷组快照在external-snapshotter仓库中实现。实现卷组快照意味着添加或更改了几个组件
- 为 VolumeGroupSnapshot 和两个支持 API 添加了新的 CustomResourceDefinitions。
- 卷组快照控制器逻辑被添加到通用快照控制器中。
- 添加逻辑以便快照程序边车控制器调用 CSI。
卷快照控制器和 CRD 在每个集群中部署一次,而边车(sidecar)与每个 CSI 驱动程序捆绑在一起。
因此,将卷快照控制器和 CRD 作为集群附加组件(addon)部署是有意义的。
Kubernetes 项目建议 Kubernetes 发行版将卷快照控制器和 CRD 作为其 Kubernetes 集群管理过程的一部分进行打包和部署(与任何 CSI 驱动程序无关)。
Beta 版本中有哪些新内容?
CSI 规范中的 VolumeGroupSnapshot 功能在v1.11.0 版本中移至 GA。
快照验证 webhook 在 external-snapshotter v8.0.0 中已弃用,现在已被移除。大部分验证 webhook 逻辑已作为验证规则添加到 CRD 中。这些验证规则所需的最低 Kubernetes 版本是 1.25。验证 webhook 中未移至 CRD 的一点是防止为同一个 CSI 驱动程序创建多个默认卷快照类和多个默认卷组快照类。移除验证 webhook 后,当为同一个 CSI 驱动程序存在多个默认卷快照类或多个默认卷组快照类时,动态供应 VolumeSnapshot 或 VolumeGroupSnapshot 仍会引发错误。
snapshot-controller
和 CSI 快照程序边车中的enable-volumegroup-snapshot
标志已被功能门控 (feature gate) 替换。由于 VolumeGroupSnapshot 是一个新 API,该功能移至 Beta,但功能门控默认是禁用的。要使用此功能,请在启动snapshot-controller
和 CSI 快照程序边车时添加标志--feature-gates=CSIVolumeGroupSnapshot=true
来启用功能门控。动态创建 VolumeGroupSnapshot 及其对应的独立 VolumeSnapshot 和 VolumeSnapshotContent 对象的逻辑已从 CSI 快照程序移至通用
snapshot-controller
。相应的,新的 RBAC 规则已添加到通用snapshot-controller
中,并从 CSI 快照程序边车中移除了一些 RBAC 规则。
如何使用 Kubernetes 卷组快照
使用 Kubernetes 创建新的组快照
定义 VolumeGroupSnapshotClass 对象并拥有需要一起创建快照的卷后,你可以通过创建 VolumeGroupSnapshot 对象来请求新的组快照。
组快照的源指定底层组快照应是动态创建的,还是使用预先存在的 VolumeGroupSnapshotContent。
预先存在的 VolumeGroupSnapshotContent 由集群管理员创建。它包含存储系统上真实卷组快照的详细信息,可供集群用户使用。
组快照源中的以下成员之一必须设置。
selector
- 一个标签查询,用于选择需要一起创建快照的 PersistentVolumeClaims。此选择器将用于匹配添加到 PVC 的标签。volumeGroupSnapshotContentName
- 指定表示现有卷组快照的预先存在的 VolumeGroupSnapshotContent 对象的名称。
动态配置卷组快照
在以下示例中,有两个 PVC。
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
pvc-0 Bound pvc-6e1f7d34-a5c5-4548-b104-01e72c72b9f2 100Mi RWO csi-hostpath-sc <unset> 2m15s
pvc-1 Bound pvc-abc640b3-2cc1-4c56-ad0c-4f0f0e636efa 100Mi RWO csi-hostpath-sc <unset> 2m7s
标记 PVC。
% kubectl label pvc pvc-0 group=myGroup
persistentvolumeclaim/pvc-0 labeled
% kubectl label pvc pvc-1 group=myGroup
persistentvolumeclaim/pvc-1 labeled
对于动态配置,必须设置选择器,以便快照控制器能够找到具有匹配标签的 PVC 并一起进行快照。
apiVersion: groupsnapshot.storage.k8s.io/v1beta1
kind: VolumeGroupSnapshot
metadata:
name: snapshot-daily-20241217
namespace: demo-namespace
spec:
volumeGroupSnapshotClassName: csi-groupSnapclass
source:
selector:
matchLabels:
group: myGroup
在 VolumeGroupSnapshot spec 中,用户可以指定 VolumeGroupSnapshotClass,其中包含用于创建卷组快照的 CSI 驱动程序信息。动态配置需要 VolumeGroupSnapshotClass。
apiVersion: groupsnapshot.storage.k8s.io/v1beta1
kind: VolumeGroupSnapshotClass
metadata:
name: csi-groupSnapclass
annotations:
kubernetes.io/description: "Example group snapshot class"
driver: example.csi.k8s.io
deletionPolicy: Delete
创建卷组快照后,将创建一个相应的 VolumeGroupSnapshotContent 对象,其中包含指向存储系统资源的 volumeGroupSnapshotHandle。
作为卷组快照创建的一部分,将创建两个单独的卷快照。
NAME READYTOUSE SOURCEPVC RESTORESIZE SNAPSHOTCONTENT AGE
snapshot-0962a745b2bf930bb385b7b50c9b08af471f1a16780726de19429dd9c94eaca0 true pvc-0 100Mi snapcontent-0962a745b2bf930bb385b7b50c9b08af471f1a16780726de19429dd9c94eaca0 16m
snapshot-da577d76bd2106c410616b346b2e72440f6ec7b12a75156263b989192b78caff true pvc-1 100Mi snapcontent-da577d76bd2106c410616b346b2e72440f6ec7b12a75156263b989192b78caff 16m
使用 Kubernetes 导入现有卷组快照
要将预先存在的卷组快照导入 Kubernetes,还必须导入相应的单独卷快照。
首先识别各个卷快照句柄,手动构建 VolumeSnapshotContent 对象,然后创建指向 VolumeSnapshotContent 对象的 VolumeSnapshot 对象。为每个单独的卷快照重复此操作。
然后手动创建一个 VolumeGroupSnapshotContent 对象,指定存储系统上已有的 volumeGroupSnapshotHandle 和各个 volumeSnapshotHandle。
apiVersion: groupsnapshot.storage.k8s.io/v1beta1
kind: VolumeGroupSnapshotContent
metadata:
name: static-group-content
spec:
deletionPolicy: Delete
driver: hostpath.csi.k8s.io
source:
groupSnapshotHandles:
volumeGroupSnapshotHandle: e8779136-a93e-11ef-9549-66940726f2fd
volumeSnapshotHandles:
- e8779147-a93e-11ef-9549-66940726f2fd
- e8783cd0-a93e-11ef-9549-66940726f2fd
volumeGroupSnapshotRef:
name: static-group-snapshot
namespace: demo-namespace
之后创建一个指向 VolumeGroupSnapshotContent 对象的 VolumeGroupSnapshot 对象。
apiVersion: groupsnapshot.storage.k8s.io/v1beta1
kind: VolumeGroupSnapshot
metadata:
name: static-group-snapshot
namespace: demo-namespace
spec:
source:
volumeGroupSnapshotContentName: static-group-content
如何在 Kubernetes 中使用卷组快照进行恢复
恢复时,用户可以请求从属于 VolumeGroupSnapshot 的 VolumeSnapshot 对象创建新的 PersistentVolumeClaim。这将触发新卷的配置,新卷将预先填充指定快照中的数据。用户应重复此操作,直到从属于卷组快照的所有快照中创建所有卷为止。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: examplepvc-restored-2024-12-17
namespace: demo-namespace
spec:
storageClassName: example-foo-nearline
dataSource:
name: snapshot-0962a745b2bf930bb385b7b50c9b08af471f1a16780726de19429dd9c94eaca0
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOncePod
resources:
requests:
storage: 100Mi # must be enough storage to fit the existing snapshot
作为存储供应商,如何向我的 CSI 驱动程序添加卷组快照支持?
为了实现卷组快照功能,CSI 驱动程序必须
- 实现新的组控制器服务。
- 实现组控制器 RPC:
CreateVolumeGroupSnapshot
、DeleteVolumeGroupSnapshot
和GetVolumeGroupSnapshot
。 - 添加组控制器功能
CREATE_DELETE_GET_VOLUME_GROUP_SNAPSHOT
。
有关更多详细信息,请参阅 CSI 规范和 Kubernetes-CSI 驱动程序开发人员指南。
如前所述,强烈建议 Kubernetes 分发商将其 Kubernetes 集群管理过程的一部分(独立于任何 CSI 驱动程序)打包和部署卷快照控制器和 CRD。
作为此推荐部署过程的一部分,Kubernetes 团队提供了一些 Sidecar(辅助)容器,其中包括已更新以支持卷组快照的 external-snapshotter Sidecar 容器。
external-snapshotter 监视 Kubernetes API 服务器上的 VolumeGroupSnapshotContent 对象,并针对 CSI 端点触发 CreateVolumeGroupSnapshot
和 DeleteVolumeGroupSnapshot
操作。
有哪些限制?
Kubernetes 的卷组快照 beta 实现具有以下限制
- 不支持将现有 PVC 恢复到快照表示的早期状态(仅支持从快照配置新卷)。
- 除了存储系统提供的任何保证(例如崩溃一致性)之外,没有应用程序一致性保证。有关应用程序一致性的更多讨论,请参阅此文档。
后续计划?
根据反馈和采用情况,Kubernetes 项目计划在未来的版本中将卷组快照实现推向正式发布 (GA)。
我如何了解更多信息?
如何参与?
像所有 Kubernetes 项目一样,本项目是来自不同背景的众多贡献者共同努力的结果。我代表 SIG Storage,衷心感谢在过去几个季度中挺身而出帮助项目达到 beta 阶段的贡献者们。
- Ben Swartzlander (bswartz)
- Cici Huang (cici37)
- Hemant Kumar (gnufied)
- James Defelice (jdef)
- Jan Šafránek (jsafrane)
- Madhu Rajanna (Madhu-1)
- Manish M Yathnalli (manishym)
- Michelle Au (msau42)
- Niels de Vos (nixpanic)
- Leonardo Cecchi (leonardoce)
- Rakshith R (Rakshith-R)
- Raunak Shah (RaunakShah)
- Saad Ali (saad-ali)
- Xing Yang (xing-yang)
- Yati Padia (yati1998)
对于那些有兴趣参与 CSI 或 Kubernetes 存储系统任何部分的设计和开发的人,请加入Kubernetes 存储特别兴趣小组 (SIG)。我们始终欢迎新的贡献者。
我们还定期举行 数据保护工作组会议。欢迎新成员加入我们的讨论。