4. API Server 原生快照能力:snapshot-controller 与 VolumeSnapshot CRD 介绍
在 Kubernetes 生态中,持久化存储的数据保护一直是生产环境的核心诉求。Kubernetes 从 1.12 版本开始引入 Volume Snapshot 功能,经过多个版本的迭代,在 1.20 版本中正式 GA(General Availability)。这一能力使得用户可以通过 Kubernetes 原生 API 对持久卷(PersistentVolume)进行快照操作,而无需依赖特定存储后端的 CLI 或管理界面。
本章将深入剖析 snapshot-controller 与 VolumeSnapshot CRD 的架构设计、核心资源对象以及工作流程,为后续基于快照的容量调优与回退演练奠定理论基础。
4.1 核心架构与组件
Volume Snapshot 功能由三个核心组件构成,它们协同工作,将存储后端的快照能力抽象为 Kubernetes 原生 API。
| 组件 | 部署位置 | 核心职责 |
|---|---|---|
| snapshot-controller | Control Plane(通常作为 Deployment 运行) | 管理 VolumeSnapshot 和 VolumeSnapshotContent 对象的生命周期;处理快照的创建、删除、恢复等操作;与 CSI Driver 交互。 |
| VolumeSnapshot CRD | API Server 注册 | 定义 VolumeSnapshot、VolumeSnapshotContent、VolumeSnapshotClass 三种自定义资源,作为用户与快照系统交互的 API 入口。 |
| CSI Driver(存储插件) | 每个 Node 或作为 StatefulSet | 实现 CSI 接口中的 CreateSnapshot、DeleteSnapshot、ListSnapshots 等方法,执行实际的存储后端快照操作。 |
snapshotter 插件。常见的云厂商 CSI Driver(如 AWS EBS CSI Driver、GCE PD CSI Driver、Azure Disk CSI Driver)均已支持。
下图展示了 snapshot-controller 与各组件之间的交互关系:
4.2 三大 CRD 资源详解
Volume Snapshot 功能引入了三个自定义资源定义(CRD),它们构成了快照操作的数据模型。理解这三个资源的关系是掌握快照能力的关键。
4.2.1 VolumeSnapshot
VolumeSnapshot 是用户直接操作的 API 对象,类似于 PVC(PersistentVolumeClaim)之于 PV。它代表用户发起的一个快照请求。
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: my-app-snapshot-20250320
namespace: production
spec:
volumeSnapshotClassName: csi-aws-ebs-snapshot-class
source:
persistentVolumeClaimName: my-app-pvc
- volumeSnapshotClassName:指定使用的 VolumeSnapshotClass,决定快照的策略和参数。
- source.persistentVolumeClaimName:指定要创建快照的源 PVC。
- source.volumeHandle(可选):直接指定存储后端的卷句柄,用于跨集群场景。
4.2.2 VolumeSnapshotContent
VolumeSnapshotContent 是集群级别的资源,类似于 PV。它代表一个已经创建成功的快照实例,由 snapshot-controller 自动管理。
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
name: snapcontent-abc123
spec:
volumeSnapshotRef:
name: my-app-snapshot-20250320
namespace: production
source:
volumeHandle: vol-0a1b2c3d4e5f67890
volumeSnapshotClassName: csi-aws-ebs-snapshot-class
deletionPolicy: Delete
status:
readyToUse: true
creationTime: 1710921600
restoreSize: 10737418240
- volumeSnapshotRef:指向所属的 VolumeSnapshot 对象。
- source.volumeHandle:存储后端返回的卷标识符。
- deletionPolicy:删除策略,可选
Delete或Retain。 - status.readyToUse:标识快照是否可用。
4.2.3 VolumeSnapshotClass
VolumeSnapshotClass 类似于 StorageClass,定义了快照的配置模板,包括 CSI Driver 信息、快照参数等。
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-aws-ebs-snapshot-class
driver: ebs.csi.aws.com
deletionPolicy: Delete
parameters:
type: gp3
tags: "environment=production,team=platform"
4.3 快照生命周期与状态机
snapshot-controller 维护了 VolumeSnapshot 和 VolumeSnapshotContent 的完整状态机。理解状态转换有助于排查快照创建失败的问题。
| 阶段 | VolumeSnapshot 状态 | VolumeSnapshotContent 状态 | 说明 |
|---|---|---|---|
| 1. 创建 | Pending |
未创建 | 用户提交 VolumeSnapshot,controller 开始处理 |
| 2. 绑定 | Pending |
Creating |
controller 创建 VolumeSnapshotContent,并调用 CSI Driver |
| 3. 快照中 | Pending |
Creating |
CSI Driver 正在执行存储后端快照操作 |
| 4. 就绪 | ReadyToUse |
ReadyToUse |
快照创建成功,可用于恢复或克隆 |
| 5. 删除 | 删除中 | 根据 deletionPolicy 决定 |
删除 VolumeSnapshot 触发级联删除或保留 |
| 6. 失败 | Error |
Error |
快照创建失败,需查看事件日志 |
- 如果 VolumeSnapshot 长时间处于
Pending状态,请检查 CSI Driver 是否正常运行,以及 VolumeSnapshotClass 中的 driver 名称是否正确。 - 删除 VolumeSnapshot 时,如果
deletionPolicy设置为Retain,VolumeSnapshotContent 会保留,需要手动清理。 - 快照恢复时,目标 PVC 的 StorageClass 必须与源卷兼容,否则恢复可能失败。
4.4 快照恢复与克隆
VolumeSnapshot 的核心价值在于数据恢复和快速克隆。通过 VolumeSnapshot,可以创建新的 PVC 来恢复数据。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-app-pvc-restored
namespace: production
spec:
storageClassName: gp3
dataSource:
name: my-app-snapshot-20250320
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
- dataSource:指定数据源为 VolumeSnapshot,Kubernetes 会自动从快照恢复数据。
- 恢复后的 PVC 可以立即挂载到 Pod 中使用,数据与快照创建时刻完全一致。
- 克隆操作与恢复类似,只需指定不同的 PVC 名称即可实现快速克隆。
4.5 生产环境最佳实践
- 合理设置 deletionPolicy:对于重要数据,建议使用
Retain策略,防止误删除导致数据丢失。 - 监控快照状态:通过 Prometheus 监控
kube_volumesnapshot_status_ready_to_use指标,及时发现快照失败。 - 限制快照频率:避免对同一 PVC 频繁创建快照,防止存储后端性能下降。
- 测试恢复流程:定期从快照恢复数据到测试环境,验证快照数据的完整性和可用性。
- 使用命名空间隔离:为不同业务线创建独立的 VolumeSnapshotClass,避免配置冲突。