68·存储高级

卷快照

kubernetesstoragesnapshotbackup

卷快照

学习目标

  1. 理解 VolumeSnapshot 的工作原理
  2. 掌握快照的创建、恢复和删除
  3. 了解快照在备份和灾难恢复中的应用

核心概念

快照是什么

Volume Snapshot (卷快照):
┌─────────────────────────────────────────┐
│           PV(持久卷)                   │
│  ┌─────────────────────────────────┐    │
│  │ 数据 A │ 数据 B │ 数据 C │      │    │
│  └─────────────────────────────────┘    │
│                    │                     │
│                    │ 创建快照            │
│                    ▼                     │
│  ┌─────────────────────────────────┐    │
│  │      VolumeSnapshot             │    │
│  │ 数据 A │ 数据 B │ 数据 C │ (只读)│    │
│  └─────────────────────────────────┘    │
│                                          │
│  快照是某一时刻的数据副本               │
│  可用于恢复数据或创建新卷               │
└─────────────────────────────────────────┘

快照相关资源

资源关系:

VolumeSnapshotClass (快照类)
    │
    ▼
VolumeSnapshot (快照请求)
    │
    ▼
VolumeSnapshotContent (快照内容,自动创建)
    │
    ▼
底层存储快照 (如 AWS EBS Snapshot)

恢复流程:
VolumeSnapshot ──恢复──→ PVC ──挂载──→ Pod

VolumeSnapshotClass

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: csi-snapclass
driver: ebs.csi.aws.com        # CSI Driver
deletionPolicy: Delete          # 删除快照时的行为
parameters:
  encrypted: "true"
deletionPolicy说明
Delete删除 VolumeSnapshot 时同时删除底层快照
Retain删除 VolumeSnapshot 时保留底层快照

创建快照

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: my-snapshot
spec:
  volumeSnapshotClassName: csi-snapclass
  source:
    persistentVolumeClaimName: my-pvc  # 源 PVC
创建过程:
1. 用户创建 VolumeSnapshot
2. CSI Driver 调用云 API 创建快照
3. 自动创建 VolumeSnapshotContent
4. 快照状态变为 ReadyToUse

查看快照

# 查看快照列表
kubectl get volumesnapshot

# 查看快照详情
kubectl describe volumesnapshot my-snapshot

# 查看快照内容(自动创建)
kubectl get volumesnapshotcontent
快照状态:
- Ready: false → 正在创建
- Ready: true  → 创建完成,可用于恢复

从快照恢复

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: restored-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: <your-sc>
  resources:
    requests:
      storage: 10Gi              # 必须 >= 快照大小
  dataSource:
    name: my-snapshot             # 引用快照
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
恢复流程:

VolumeSnapshot (my-snapshot)
         │
         │ dataSource
         ▼
PVC (restored-pvc) ──新建──→ PV (包含快照数据)
         │
         │ 挂载
         ▼
Pod ──读取──→ 恢复的数据

快照备份流程

定时备份方案:

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   CronJob    │     │  Volume      │     │   云存储     │
│  定时触发    │────►│  Snapshot    │────►│  快照存储    │
└──────────────┘     └──────────────┘     └──────────────┘
                                                │
                                                │ 灾难恢复
                                                ▼
                     ┌──────────────┐     ┌──────────────┐
                     │   新 PVC     │◄────│   快照       │
                     │  恢复数据    │     │  选择快照    │
                     └──────────────┘     └──────────────┘

快照与备份的区别

方面VolumeSnapshot备份工具 (Velero 等)
粒度单个 PVC整个命名空间/集群
速度快(增量)较慢
跨集群不支持支持
资源仅存储包含 K8s 资源定义
适用快速恢复灾难恢复、迁移

跨区域快照

# 将快照复制到其他区域
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: cross-region-snapshot
spec:
  volumeSnapshotClassName: csi-snapclass
  source:
    volumeSnapshotContentName: source-snapshot-content
# AWS 示例:复制快照到其他区域
aws ec2 copy-snapshot \
  --source-region us-east-1 \
  --source-snapshot-id snap-xxxx \
  --destination-region us-west-2

实践练习

练习 1:安装 Snapshot CRD

# 安装 Snapshot Controller(如果未安装)
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml

# 验证安装
kubectl get crd | grep snapshot

练习 2:创建和恢复快照

# 1. 创建快照
kubectl apply -f - <<EOF
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: test-snapshot
spec:
  volumeSnapshotClassName: csi-snapclass
  source:
    persistentVolumeClaimName: my-pvc
EOF

# 2. 等待快照就绪
kubectl get volumesnapshot test-snapshot -w

# 3. 从快照恢复
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: restored-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: <your-sc>
  resources:
    requests:
      storage: 10Gi
  dataSource:
    name: test-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
EOF

练习 3:验证恢复数据

# 创建 Pod 使用恢复的 PVC
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: restore-test
spec:
  containers:
    - name: app
      image: busybox
      command: ["sh", "-c", "ls -la /data && sleep 3600"]
      volumeMounts:
        - mountPath: /data
          name: restored
  volumes:
    - name: restored
      persistentVolumeClaim:
        claimName: restored-pvc
EOF

# 验证数据
kubectl exec restore-test -- ls /data

常见误解

1. 快照不是完整副本

大多数云存储的快照是增量的
只有变化的数据块会被存储
这使得快照创建和存储成本更低

2. 快照需要 CSI Driver 支持

不是所有 CSI Driver 都支持快照
需要检查 Driver 文档确认支持
hostPath 和 NFS 通常不支持原生快照

小结

要点说明
VolumeSnapshotPVC 的时间点数据副本
VolumeSnapshotClass定义快照的创建方式
恢复通过 PVC dataSource 引用快照
适用场景快速备份、数据恢复、测试环境
限制依赖 CSI Driver,不跨集群

练习编辑器

bash
Loading...

继续学习

完成本课后,建议继续学习下一课「数据持久化」 以巩固所学知识。