为单个云盘存储卷创建快照

云盘存储快照可以帮助您实现应用数据的备份和恢复。本文介绍如何通过VolumeSnapshot资源为云盘存储卷创建快照,以及如何基于快照恢复数据。

前提条件

功能概述

ACK集群中,通常使用云盘存储卷为StatefulSet提供持久化存储。基于云盘本身提供的快照功能,Kubernetes使用以下两个特性来实现云盘存储卷的数据备份和恢复能力。

  • 通过VolumeSnapshot资源实现云盘数据的备份(快照功能)。

  • 通过PVCDataSource功能实现云盘数据的恢复。

计费说明

ACK的存储快照基于ECS快照实现。快照会收取存储费用,具体请参见快照计费

使用说明

为了实现快照相关功能,ACK通过CRD定义了以下3个相关的资源类型。

资源类型名称

描述

VolumeSnapshotContent

存储后端的快照,由集群管理员创建维护,无NameSpace。类似PV概念。

VolumeSnapshot

声明一个快照,由操作人员创建维护,属于特定Namespace。类似PVC概念。

VolumeSnapshotClass

定义一个快照类,描述创建快照使用的参数、Controller。类似StorageClass概念。

绑定规则如下:

  • 使用Snapshot资源类型时,类似PVPVC,首先您需绑定VolumeSnapshotVolumeSnapshotContent。

  • 如果VolumeSnapshot正确配置了VolumeSnapshotClassName字段,集群会自动创建VolumeSnapshotContent。如果没有配置或者配置错误,则无法自动创建,您需要手动创建VolumeSnapshotContent,并绑定VolumeSnapshot。

  • VolumeSnapshotContentVolumeSnapshot绑定是一对一的关系。

重要

删除VolumeSnapshotContent时,后端的快照也会被删除。

动态创建快照

使用流程

ACK使用云盘动态创建快照使用流程如下图所示。snapshot

重要

使用PL0、PL1、PL2、PL3级别的ESSD云盘或ESSD AutoPL云盘时,动态创建的快照默认开启快照极速可用能力

使用流程说明如下:

流程步骤

描述

创建应用并使用云盘存储卷保存数据。

创建关联了VolumeSnapshotClassVolumeSnapshot,此时集群会自动创建VolumeSnapshotContent和存储后端的快照。

创建新的应用,并配置PVC引用步骤②中创建的快照。

上述的三个步骤实现:

  • 备份:Volume1的数据被备份到Snapshot1。

  • 恢复:Snapshot1的数据(也就是Volume1的数据)被恢复成Volume2。

使用示例

  1. 创建VolumeSnapshotClass。

    1. 使用以下YAML内容创建volumesnapshotclass.yaml文件。

      apiVersion: snapshot.storage.k8s.io/v1
      kind: VolumeSnapshotClass
      metadata:
       name: default-snapclass
      driver: diskplugin.csi.alibabacloud.com
      parameters:
        retentionDays: "5"
        forceDelete: "true"
      deletionPolicy: Delete

      参数

      说明

      retentionDays

      指定快照自动回收时间。单位为天。

      forceDelete

      forceDelete配置为"true"时,表示使用强制删除快照功能。

      csi-provisioner组件v1.26.5-92f859a-aliyun版本起,默认使用强制删除且不可修改,此前默认为普通删除。

      • 强制删除:强制删除用户创建的所有已使用和未使用的快照。

      • 普通删除:只删除未使用的快照。不删除已经使用过的快照。

      deletionPolicy

      快照的回收策略。取值范围:

      • Delete:删除VolumeSnapshot时,VolumeSnapshotContent以及关联的快照也会一起被删除。

      • Retain:删除VolumeSnapshot时,VolumeSnapshotContent以及关联的快照不会被删除。

    2. 创建VolumeSnapshotClass。

      kubectl apply -f volumesnapshotclass.yaml
  2. 创建应用并写入数据。

    1. 使用以下YAML内容创建nginx.yaml文件。

      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: nginx
      spec:
        selector:
          matchLabels:
            app: nginx
        serviceName: "nginx"
        replicas: 1
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - name: disk
                mountPath: /data
        volumeClaimTemplates:
        - metadata:
            name: disk
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: "alicloud-disk-topology-alltype"
            resources:
              requests:
                storage: 20Gi 
    2. 创建应用。

      kubectl apply -f nginx.yaml
    3. 查看Pod部署状态。

      kubectl get pod -l app=nginx

      预期返回:

      NAME        READY   STATUS    RESTARTS   AGE
      nginx-0     1/1     Running   0          82s
    4. 向挂载路径写入数据。

      kubectl exec -it nginx-0 -- touch /data/test
      kubectl exec -it nginx-0 -- ls /data

      预期返回:

      lost+found test
  3. 创建VolumeSnapshot。

    重要
    • 如果CSI组件版本不低于v1.22.12-b797ad9-aliyun,则创建快照时,不依赖该是否有Running Pod在使用PVC,可对任意挂载过的云盘创建快照。

    • 如果CSI组件版本低于v1.22.12-b797ad9-aliyun,则创建快照时,需要保证有Running Pod正在使用当前PVC,即保证云盘处于挂载状态。

    1. 使用以下YAML内容创建snapshot-1.yaml文件。

      apiVersion: snapshot.storage.k8s.io/v1
      kind: VolumeSnapshot
      metadata:
        name: new-snapshot-demo
        namespace: default
      spec:
        volumeSnapshotClassName: default-snapclass   # 关联VolumeSnapshotClass
        source:
          persistentVolumeClaimName: disk-nginx-0
    2. 创建VolumeSnapshot。

      kubectl apply -f snapshot-1.yaml
  4. 查看VolumeSnapshotVolumeSnapshotContent。

    说明

    您也可以登录ECS控制台查看VolumeSnapshotContent对应的快照。

    1. 查看VolumeSnapshot。

      kubectl get volumesnapshots

      预期返回:

      NAME                READYTOUSE   SOURCEPVC      SOURCESNAPSHOTCONTENT   RESTORESIZE   SNAPSHOTCLASS       SNAPSHOTCONTENT                                    CREATIONTIME   AGE
      new-snapshot-demo   true         disk-nginx-0                           20Gi          default-snapclass   snapcontent-48b04625-679a-490f-9ef3-f04b2b8e6c57   28s            28s
    2. 查看VolumeSnapshotContent。

      kubectl get VolumeSnapshotContent

      预期返回:

      NAME                                               READYTOUSE   RESTORESIZE   DELETIONPOLICY   DRIVER                            VOLUMESNAPSHOTCLASS   VOLUMESNAPSHOT      VOLUMESNAPSHOTNAMESPACE   AGE
      snapcontent-48b04625-679a-490f-9ef3-f04b2b8e6c57   true         21474836480   Delete           diskplugin.csi.alibabacloud.com   default-snapclass     new-snapshot-demo   default                   49s
  5. 使用VolumeSnapshot创建一个新的应用,以此恢复数据。

    1. 使用以下YAML内容创建nginx-restore文件。

      volumeClaimTemplates中,需设置dataSource.kindVolumeSnapshot,且dataSource.nameVolumeSnapshot名称。

      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: nginx-restore
      spec:
        selector:
          matchLabels:
            app: nginx
        serviceName: "nginx"
        replicas: 1
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - name: disk
                mountPath: /data
        volumeClaimTemplates:
        - metadata:
            name: disk
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: "alicloud-disk-topology-alltype"
            resources:
              requests:
                storage: 20Gi
            dataSource:
              name: new-snapshot-demo
              kind: VolumeSnapshot
              apiGroup: snapshot.storage.k8s.io
    2. 创建应用。

      kubectl apply -f nginx-restore.yaml
    3. 查看挂载路径的数据,确认数据是否已经恢复。

      kubectl exec -it nginx-restore-0 -- ls /data

      返回示例:

      lost+found test

静态创建快照(使用已有ECS快照)

如果您已在ECS控制台基于云盘创建了快照,可参考以下步骤将ECS快照导入至ACK集群中。

  1. 基于已有ECS快照创建VolumeSnapshotContent。

    1. 使用以下YAML内容创建snapshot-content.yaml文件。

      apiVersion: snapshot.storage.k8s.io/v1
      kind: VolumeSnapshotContent
      metadata:
        name: new-snapshot-content-test
      spec:
        deletionPolicy: Retain
        driver: diskplugin.csi.alibabacloud.com
        source:
          snapshotHandle: <YOUR-SNAPSHOTID>
        volumeSnapshotRef:
          name: new-snapshot-demo
          namespace: default

      参数

      描述

      snapshotHandle

      已有快照的ID。您可以在ECS控制台快照页面获取快照ID。

      volumeSnapshotRef

      填写要创建的VolumeSnapshot的信息。

      • name:将要创建的VolumeSnapshot的名称。

      • namespace:将要创建的VolumeSnapshot所在的命名空间。

    2. 创建VolumeSnapshotContent。

      kubectl apply -f snapshot-content.yaml
  2. 创建VolumeSnapshot,并绑定VolumeSnapshotContent。

    1. 使用以下YAML内容创建snapshot-2.yaml文件。

      apiVersion: snapshot.storage.k8s.io/v1
      kind: VolumeSnapshot
      metadata:
        name: new-snapshot-demo
        namespace: default
      spec:
        source:
          volumeSnapshotContentName: new-snapshot-content-test

      参数

      描述

      metadata.name

      VolumeSnapshot名称,需要和VolumeSnapshotContentvolumeSnapshotRef.name的配置一致。

      volumeSnapshotContentName

      要绑定的VolumeSnapshotContent的名称。

    2. 创建VolumeSnapshot。

      kubectl apply -f snapshot-2.yaml
  3. 使用VolumeSnapshot创建一个新的应用,以此恢复数据。

    1. 使用以下YAML内容创建nginx-restore文件。

      volumeClaimTemplates中,需设置dataSource.kindVolumeSnapshot,且dataSource.nameVolumeSnapshot名称。

      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: nginx-restore
      spec:
        selector:
          matchLabels:
            app: nginx
        serviceName: "nginx"
        replicas: 1
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - name: disk
                mountPath: /data
        volumeClaimTemplates:
        - metadata:
            name: disk
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: "alicloud-disk-topology-alltype"
            resources:
              requests:
                storage: 20Gi
            dataSource:
              name: new-snapshot-demo
              kind: VolumeSnapshot
              apiGroup: snapshot.storage.k8s.io
    2. 创建应用。

      kubectl apply -f nginx-restore.yaml
    3. 查看挂载路径的数据,确认数据是否已经恢复。

      kubectl exec -it nginx-restore-0 -- ls /data

      返回示例:

      lost+found test