这篇文章发布已超过一年。较旧的文章可能包含过时的内容。请检查页面上的信息自发布以来是否已变得不正确。
为 Kubernetes 引入卷快照 Alpha 版
Kubernetes v1.12 引入了对卷快照的 alpha 支持。此功能允许创建/删除卷快照,并能够使用 Kubernetes API 从快照原生创建新卷。
什么是快照?
许多存储系统(如 Google Cloud Persistent Disks、Amazon Elastic Block Storage 和许多本地存储系统)都能够创建持久卷的“快照”。快照表示卷的时间点副本。快照可用于配置新卷(预先填充快照数据)或将现有卷恢复到之前的状态(由快照表示)。
为什么要向 Kubernetes 添加快照?
Kubernetes 卷插件系统已经提供了一个强大的抽象,可以自动化块存储和文件存储的配置、附加和挂载。
所有这些功能的基础是 Kubernetes 的工作负载可移植性目标:Kubernetes 旨在在分布式系统应用程序和底层集群之间创建一个抽象层,以便应用程序可以忽略其运行的集群的具体细节,并且应用程序部署不需要“特定于集群”的知识。
Kubernetes 存储 SIG 认为快照操作是许多有状态工作负载的关键功能。例如,数据库管理员可能希望在开始数据库操作之前快照数据库卷。
通过在 Kubernetes API 中提供触发快照操作的标准方法,Kubernetes 用户现在可以处理这样的用例,而无需绕过 Kubernetes API(并手动执行特定于存储系统的操作)。
相反,Kubernetes 用户现在可以放心地将快照操作以集群无关的方式纳入他们的工具和策略中,并且知道它可以在任意 Kubernetes 集群上工作,而不管底层存储是什么。
此外,这些 Kubernetes 快照原语充当基本构建块,可解锁为 Kubernetes 开发高级的企业级存储管理功能的能力:例如数据保护、数据复制和数据迁移。
哪些卷插件支持 Kubernetes 快照?
Kubernetes 支持三种类型的卷插件:内置、Flex 和 CSI。有关详细信息,请参阅Kubernetes 卷插件常见问题解答。
快照仅支持 CSI 驱动程序(不支持内置或 Flex)。要使用 Kubernetes 快照功能,请确保在集群上部署了实现快照的 CSI 驱动程序。
在本博客发布时,以下 CSI 驱动程序支持快照
其他驱动程序的快照支持正在等待中,应该很快可用。阅读“Kubernetes 的容器存储接口 (CSI) 进入 Beta 版”博客文章,了解有关 CSI 以及如何部署 CSI 驱动程序的更多信息。
Kubernetes 快照 API
与管理 Kubernetes 持久卷的 API 类似,Kubernetes 卷快照引入了三个新的 API 对象来管理快照
VolumeSnapshot
- 由 Kubernetes 用户创建,以请求为指定的卷创建快照。它包含有关快照操作的信息,例如拍摄快照的时间戳以及快照是否可以使用。
- 与
PersistentVolumeClaim
对象类似,此对象的创建和删除表示用户希望创建或删除集群资源(快照)。
VolumeSnapshotContent
- 由 CSI 卷驱动程序在成功创建快照后创建。它包含有关快照的信息,包括快照 ID。
- 与
PersistentVolume
对象类似,此对象表示集群上配置的资源(快照)。 - 与
PersistentVolumeClaim
和PersistentVolume
对象类似,一旦创建快照,VolumeSnapshotContent
对象就会绑定到为其创建的 VolumeSnapshot(具有一对一的映射)。
VolumeSnapshotClass
- 由集群管理员创建,用于描述应如何创建快照。包括驱动程序信息、访问快照的密钥等。
重要的是要注意,与核心 Kubernetes 持久卷对象不同,这些快照对象被定义为CustomResourceDefinitions (CRD)。Kubernetes 项目正在放弃在 API 服务器中预定义资源类型,并正在转向 API 服务器独立于 API 对象的模型。这允许 API 服务器被 Kubernetes 以外的项目重用,并且使用者(如 Kubernetes)可以简单地安装他们需要的资源类型作为 CRD。
支持快照的CSI 驱动程序将自动安装所需的 CRD。Kubernetes 最终用户只需要验证是否在其 Kubernetes 集群上部署了支持快照的 CSI 驱动程序。
除了这些新对象之外,PersistentVolumeClaim
对象还添加了一个新的 DataSource 字段
type PersistentVolumeClaimSpec struct {
AccessModes []PersistentVolumeAccessMode
Selector *metav1.LabelSelector
Resources ResourceRequirements
VolumeName string
StorageClassName *string
VolumeMode *PersistentVolumeMode
DataSource *TypedLocalObjectReference
}
这个新的 alpha 字段允许创建新的卷,并使用现有快照中的数据自动预先填充。
Kubernetes 快照要求
在使用 Kubernetes 卷快照之前,您必须
- 确保在 Kubernetes 集群上部署并运行了实现快照的 CSI 驱动程序。
- 通过新的 Kubernetes 功能门启用 Kubernetes 卷快照功能(默认情况下,alpha 功能处于禁用状态)
- 在 API 服务器二进制文件上设置以下标志:
--feature-gates=VolumeSnapshotDataSource=true
- 在 API 服务器二进制文件上设置以下标志:
在创建快照之前,您还需要通过创建 VolumeSnapshotClass
对象并将 snapshotter
字段设置为指向您的 CSI 驱动程序来指定快照的 CSI 驱动程序信息。在下面的 VolumeSnapshotClass
示例中,CSI 驱动程序是 com.example.csi-driver
。每个快照配置器至少需要一个 VolumeSnapshotClass
对象。您还可以通过在类定义中放入注释 snapshot.storage.kubernetes.io/is-default-class: "true"
来为每个单独的 CSI 驱动程序设置默认的 VolumeSnapshotClass
。
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshotClass
metadata:
name: default-snapclass
annotations:
snapshot.storage.kubernetes.io/is-default-class: "true"
snapshotter: com.example.csi-driver
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshotClass
metadata:
name: csi-snapclass
snapshotter: com.example.csi-driver
parameters:
fakeSnapshotOption: foo
csiSnapshotterSecretName: csi-secret
csiSnapshotterSecretNamespace: csi-namespace
您必须根据 CSI 驱动程序的文档设置任何必需的不透明参数。如上面的示例所示,参数 fakeSnapshotOption: foo
和任何引用的密钥将在快照创建和删除期间传递给 CSI 驱动程序。默认的 CSI external-snapshotter 保留参数键 csiSnapshotterSecretName
和 csiSnapshotterSecretNamespace
。如果指定,它会获取密钥并在创建和删除快照时将其传递给 CSI 驱动程序。
最后,在创建快照之前,您必须使用 CSI 驱动程序配置卷,并使用您要快照的某些数据填充它(请参阅有关如何创建和使用 CSI 卷的CSI 博客文章)。
使用 Kubernetes 创建新快照
一旦定义了 VolumeSnapshotClass
对象并且您有一个要快照的卷,您可以通过创建 VolumeSnapshot
对象来创建新快照。
快照的来源指定要从中创建快照的卷。它有两个参数
kind
- 必须是PersistentVolumeClaim
name
- PVC API 对象名称
要快照的卷的命名空间假定与 VolumeSnapshot
对象的命名空间相同。
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshot
metadata:
name: new-snapshot-demo
namespace: demo-namespace
spec:
snapshotClassName: csi-snapclass
source:
name: mypvc
kind: PersistentVolumeClaim
在 VolumeSnapshot
规范中,用户可以指定 VolumeSnapshotClass
,其中包含有关应使用哪个 CSI 驱动程序来创建快照的信息。创建 VolumeSnapshot
对象时,来自 VolumeSnapshotClass
的参数 fakeSnapshotOption: foo
和任何引用的密钥都将通过 CreateSnapshot
调用传递给 CSI 插件 com.example.csi-driver
。
作为响应,CSI 驱动程序会触发卷的快照,然后自动创建一个 VolumeSnapshotContent
对象来表示新的快照,并将新的 VolumeSnapshotContent
对象绑定到 VolumeSnapshot
,使其可以使用。如果 CSI 驱动程序未能创建快照并返回错误,则快照控制器会在 VolumeSnapshot
对象的状态中报告错误,并且不会重试(这与 Kubernetes 中的其他控制器不同,是为了防止在意外时间拍摄快照)。
如果未指定快照类,则外部快照程序将尝试查找并为快照设置默认快照类。默认快照类中由 snapshotter
指定的 CSI 驱动程序
必须与 PVC 存储类中由 provisioner
指定的 CSI 驱动程序
匹配。
请注意,Kubernetes 快照的 alpha 版本不提供任何一致性保证。在进行快照以保证数据一致性之前,您必须准备好您的应用程序(暂停应用程序、冻结文件系统等)。
您可以通过运行 kubectl describe volumesnapshot
来验证 VolumeSnapshot
对象是否已创建并与 VolumeSnapshotContent
绑定。
Status
下的Ready
应该设置为 true,以表明此卷快照已准备好使用。Creation Time
字段表示快照实际创建(切割)的时间。Restore Size
字段表示从快照还原卷时所需的最小卷大小。spec
中的Snapshot Content Name
字段指向为此快照创建的VolumeSnapshotContent
对象。
使用 Kubernetes 导入现有快照
您始终可以通过手动创建一个 VolumeSnapshotContent
对象来表示现有快照,从而将现有快照导入 Kubernetes。 由于 VolumeSnapshotContent
是非命名空间 API 对象,因此只有系统管理员才有权限创建它。 创建 VolumeSnapshotContent
对象后,用户可以创建一个指向 VolumeSnapshotContent
对象的 VolumeSnapshot
对象。 external-snapshotter 控制器将在验证快照存在并且 VolumeSnapshot
和 VolumeSnapshotContent
对象之间的绑定正确后,将快照标记为就绪。绑定后,快照即可在 Kubernetes 中使用。
应使用以下字段创建 VolumeSnapshotContent
对象以表示预先配置的快照
csiVolumeSnapshotSource
- 快照识别信息。snapshotHandle
- 快照的名称/标识符。此字段是必需的。driver
- 用于处理此卷的 CSI 驱动程序。此字段是必需的。它必须与快照控制器中的快照器名称匹配。creationTime
和restoreSize
- 这些字段对于预先配置的卷不是必需的。 external-snapshotter 控制器将在创建后自动更新它们。
volumeSnapshotRef
- 指向此对象应绑定到的VolumeSnapshot
对象的指针。name
和namespace
- 它指定内容绑定到的VolumeSnapshot
对象的名称和命名空间。UID
- 这些字段对于预先配置的卷不是必需的。external-snapshotter 控制器将在绑定后自动更新该字段。 如果用户指定 UID 字段,则必须确保它与绑定快照的 UID 匹配。 如果指定的 UID 与绑定快照的 UID 不匹配,则该内容被视为孤立对象,控制器将删除它及其关联的快照。
snapshotClassName
- 此字段是可选的。 external-snapshotter 控制器将在绑定后自动更新该字段。
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshotContent
metadata:
name: static-snapshot-content
spec:
csiVolumeSnapshotSource:
driver: com.example.csi-driver
snapshotHandle: snapshotcontent-example-id
volumeSnapshotRef:
kind: VolumeSnapshot
name: static-snapshot-demo
namespace: demo-namespace
应该创建一个 VolumeSnapshot
对象以允许用户使用快照
snapshotClassName
- 卷快照类的名称。此字段是可选的。如果设置,则快照类中的快照器字段必须与快照控制器的快照器名称匹配。如果未设置,则快照控制器将尝试查找默认快照类。snapshotContentName
- 卷快照内容的名称。 此字段对于预先配置的卷是必需的。
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshot
metadata:
name: static-snapshot-demo
namespace: demo-namespace
spec:
snapshotClassName: csi-snapclass
snapshotContentName: static-snapshot-content
创建这些对象后,快照控制器会将它们绑定在一起,并将字段 Ready(在 Status
下)设置为 True,以表明快照已准备好使用。
使用 Kubernetes 从快照配置新卷
要配置一个预先填充了来自快照对象的数据的新卷,请在 PersistentVolumeClaim
中使用新的 dataSource 字段。它有三个参数
- name - 表示要用作源的快照的
VolumeSnapshot
对象的名称 - kind - 必须为
VolumeSnapshot
- apiGroup - 必须为
snapshot.storage.k8s.io
源 VolumeSnapshot
对象的命名空间假定与 PersistentVolumeClaim
对象的命名空间相同。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-restore
Namespace: demo-namespace
spec:
storageClassName: csi-storageclass
dataSource:
name: new-snapshot-demo
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
创建 PersistentVolumeClaim
对象后,它将触发新卷的配置,该新卷预先填充了来自指定快照的数据。
作为存储供应商,我如何为我的 CSI 驱动程序添加快照支持?
要实现快照功能,CSI 驱动程序必须添加对其他控制器功能 CREATE_DELETE_SNAPSHOT
和 LIST_SNAPSHOTS
的支持,并实现其他控制器 RPC:CreateSnapshot
、DeleteSnapshot
和 ListSnapshots
。 有关详细信息,请参阅 CSI 规范。
尽管 Kubernetes 在 CSI 卷驱动程序的打包和部署方面尽可能限制性最小,但它提供了一种建议机制,用于在 Kubernetes 上部署任意容器化的 CSI 驱动程序,以简化容器化 CSI 兼容卷驱动程序的部署。
作为此建议部署过程的一部分,Kubernetes 团队提供了许多 sidecar(辅助)容器,包括一个新的 external-snapshotter sidecar 容器。
external-snapshotter 监视 Kubernetes API 服务器上的 VolumeSnapshot
和 VolumeSnapshotContent
对象,并针对 CSI 端点触发 CreateSnapshot 和 DeleteSnapshot 操作。 CSI external-provisioner sidecar 容器也已更新,以支持使用新的 dataSource
PVC 字段从快照还原卷。
为了支持快照功能,建议存储供应商除了 external provisioner 和 external attacher 之外,还应在其状态集中部署 external-snapshotter sidecar 容器及其 CSI 驱动程序,如下面的图所示。
在此示例部署 yaml 文件中,两个 sidecar 容器,external provisioner 和 external snapshotter 以及 CSI 驱动程序与状态集 pod 中的 hostpath CSI 插件一起部署。 Hostpath CSI 插件是一个示例插件,不适用于生产环境。
alpha 版本的限制是什么?
Kubernetes 快照的 alpha 实现具有以下限制
- 不支持将现有卷恢复到快照表示的较早状态(alpha 版本仅支持从快照配置新卷)。
- 不支持从快照对现有 PersistentVolumeClaim 进行“就地还原”:即,从快照配置新卷,但更新现有 PersistentVolumeClaim 以指向新卷,并有效地使 PVC 看起来恢复到较早的状态(alpha 版本仅支持使用通过新的 PV/PVC 从快照配置的新卷)。
- 除了存储系统提供的任何保证之外,没有快照一致性保证(例如,崩溃一致性)。
下一步是什么?
根据反馈和采用情况,Kubernetes 团队计划在 1.13 或 1.14 版本中将 CSI 快照实现推向 beta 版本。
如何了解更多信息?
在此处查看有关快照功能的其他文档:http://k8s.io/docs/concepts/storage/volume-snapshots 和 https://kubernetes-csi.github.io/docs/
如何参与其中?
与所有 Kubernetes 项目一样,该项目是来自不同背景的许多贡献者共同努力的结果。
除了致力于快照功能的贡献者之外
- Xing Yang (xing-yang)
- Jing Xu (jingxu97)
- Huamin Chen (rootfs)
- Tomas Smetana (tsmetana)
- Shiwei Xu (wackxu)
我们非常感谢 Kubernetes Storage SIG 和 CSI 社区的所有贡献者,他们帮助审查了该项目的设计和实施,包括但不限于以下人员
- Saad Ali (saadali)
- Tim Hockin (thockin)
- Jan Šafránek (jsafrane)
- Luis Pabon (lpabon)
- Jordan Liggitt (liggitt)
- David Zhu (davidz627)
- Garth Bushell (garthy)
- Ardalan Kangarlou (kangarlou)
- Seungcheol Ko (sngchlko)
- Michelle Au (msau42)
- Humble Devassy Chirammal (humblec)
- Vladimir Vivien (vladimirvivien)
- John Griffith (j-griffith)
- Bradley Childs (childsb)
- Ben Swartzlander (bswartz)
如果您有兴趣参与 CSI 或 Kubernetes 存储系统的任何部分的设计和开发,请加入 Kubernetes 存储特别兴趣小组 (SIG)。我们正在快速发展,并且始终欢迎新的贡献者。