容器服务Kubernetes版ACK(Container Service for Kubernetes)的云盘存储快照特性可以帮助您实现应用数据的备份和恢复。本文介绍ACK的存储快照的基本概念、使用流程,及说明如何动态、静态创建快照。

前提条件

  • ACK发布的Kubernetes 1.18及之上版本默认提供了存储快照的功能,因此使用云盘存储快照时,请确保您创建的ACK集群Kubernetes版本等于或大于1.18。具体操作,请参见创建Kubernetes托管版集群
  • 访问指定地域的ECS控制台,确认已开启云盘快照服务。具体操作,请参见开通快照

背景信息

在阿里云ACK集群中部署有状态服务通常使用云盘数据卷存储数据,虽然云盘本身提供了数据的备份(快照)恢复机制,但是如何将这种机制和Kubernetes服务集成并灵活地提供给应用使用?为了解决这个问题,Kubernetes使用以下两个特性来实现备份恢复能力:
  • 通过VolumeSnapshot资源实现云盘的备份(快照功能)。
  • 通过PVC的DataSource功能实现数据的恢复。

使用说明

为了实现快照相关功能,ACK通过CRD定义了以下3个相关的资源类型。
资源类型名称 描述
VolumeSnapshotContent 存储后端的快照实例,由系统管理员创建维护,无NameSpace。类似PV概念。
VolumeSnapshot 声明一个快照实例,由用户创建维护,属于特定NameSpace。类似PVC概念。
VolumeSnapshotClass 定义一个快照类,描述创建快照使用的参数、Controller。类似StorageClass概念。
存储快照资源的绑定规则如下:
  • 在使用Snapshot资源类型时,和PV、PVC一样,首先您需绑定VolumeSnapshot与VolumeSnapshotContent。
  • 集群会自动为正确配置了VolumeSnapshotClassName字段的VolumeSnapshot资源,创建VolumeSnapshotContent资源。 如果您没有配置或者配置错误的话则无法自动创建VolumeSnapshotContent,您需要手动创建VolumeSnapshotContent,并绑定VolumeSnapshot。
  • VolumeSnapshotContent与VolumeSnapshot绑定是一对一的关系。
注意 删除VolumeSnapshotContent同时,后端的快照也会被删除。

动态创建快照

下图为在ACK使用的云盘上动态创建快照的使用流程图。snapshot
使用流程说明如下。
流程步骤 描述
创建原始应用,创建云盘卷保存数据。
创建VolumeSnapshot,此时集群会自动创建VolumeSnapshotContent和存储端的快照实例。
创建新的应用,并配置PVC引用步骤②中创建的快照对象。
上述的三个步骤实现:
  • 备份:图中的Volume1的数据被备份到Snapshot1
  • 恢复:Snapshot1的数据(也就是Volume1的数据)被恢复成Volume2

本文示例将通过创建Nginx应用并恢复应用的数据,说明如何使用存储快照功能。操作步骤如下。

  1. 创建VolumeSnapshotClass快照类。
    1. 使用以下YAML内容创建volumesnapshotclass.yaml文件。
      apiVersion: snapshot.storage.k8s.io/v1beta1
      kind: VolumeSnapshotClass
      metadata:
        name: default-snapclass
      driver: diskplugin.csi.alibabacloud.com
      parameters:
         snapshotType: "xxx"
         instantAccessRetentionDays: "1"
      deletionPolicy: Delete
      参数 描述
      deletionPolicy
      • 当值为Delete的时候,说明删除VolumeSnapshot时,VolumeSnapshotContent以及关联的快照也会被一起删除。
      • 当值为Retain的时候,说明删除VolumeSnapshot时,VolumeSnapshotContent以及关联的快照不会被删除。
      parameters.snapshotType 指定为InstantAcces的时候,动态创建出来的是极速快照,只针对于ESSD云盘。更多信息,请参见开启或关闭快照极速可用功能

      默认值为normal,表示创建普通快照。

      parameters.instantAccessRetentionDays 与参数parameters.snapshotType共同使用,指定了创建极速快照保留天数,过了该天数后,极速快照将会转换成普通快照。
    2. 执行以下命令创建VolumeSnapshotClass快照类。
      kubectl apply -f volumesnapshotclass.yaml
  2. 创建原始应用并写入数据。
    1. 使用以下YAML内容创建nginx.yaml文件。
      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: web
      spec:
        selector:
          matchLabels:
            app: nginx
        serviceName: "nginx"
        replicas: 1
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: nginx
              volumeMounts:
              - name: disk-ssd
                mountPath: /data
        volumeClaimTemplates:
        - metadata:
            name: disk-ssd
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: "alicloud-disk-ssd"
            resources:
              requests:
                storage: 20Gi
    2. 执行以下命令创建应用Nginx。
      kubectl apply -f nginx.yaml
    3. 执行以下命令往Pod(web-0)中写入数据。
      kubectl exec -it web-0 touch /data/test
      kubectl exec -it web-0 ls /data
      输出:
      lost+found test
  3. 创建VolumeSnapshot。
    1. 使用以下YAML内容创建snapshot.yaml文件。
      apiVersion: snapshot.storage.k8s.io/v1beta1
      kind: VolumeSnapshot
      metadata:
        name: new-snapshot-demo
      spec:
        volumeSnapshotClassName: default-snapclass
        source:
          persistentVolumeClaimName: disk-ssd-web-0
    2. 执行以下命令创建VolumeSnapshot。
      kubectl apply -f snapshot.yaml
    3. 执行以下命令查看是否创建VolumeSnapshot和VolumeSnapshotContent。您也可以登录ECS控制台查看快照实例。
      查看VolumeSnapshot命令:
      kubectl get volumesnapshots.snapshot.storage.k8s.io
      输出:
      NAME                                            AGE
      new-snapshot-demo                                36m
      查看VolumeSnapshotContent命令:
      kubectl get VolumeSnapshotContent
      输出:
      NAME                                            AGE
      snapshotcontent-222222                           36m
  4. 恢复数据。
    1. 使用以下YAML内容创建nginx-restore文件。
      apiVersion: v1
      kind: Service
      metadata:
        name: nginx
        labels:
          app: nginx
      spec:
        ports:
        - port: 80
          name: web
        clusterIP: None
        selector:
          app: nginx
      ---
      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: web-restore
      spec:
        selector:
          matchLabels:
            app: nginx
        serviceName: "nginx"
        replicas: 1
        template:
          metadata:
            labels:
              app: nginx
          spec:
            hostNetwork: true
            containers:
            - name: nginx
              image: nginx
              command: ["sh", "-c"]
              args: ["sleep 10000"]
              volumeMounts:
              - name: disk-ssd
                mountPath: /data
        volumeClaimTemplates:
        - metadata:
            name: disk-ssd
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: alicloud-disk-ssd
            resources:
              requests:
                storage: 20Gi
            dataSource:
              name: new-snapshot-demo
              kind: VolumeSnapshot
              apiGroup: snapshot.storage.k8s.io
      说明volumeClaimTemplates中,需设置dataSource的类型为VolumeSnapshot,且VolumeSnapshot的名字为步骤3中创建的new-snapshot-demo。
    2. 执行以下命令恢复数据。
      kubectl apply -f nginx-restore.yaml
  5. 执行以下命令查看Pod(web-restore-0)数据。
    kubectl exec -it web-restore-0 ls /data
    输出:
    lost+found test
    可见在不同的Pod中返回相同数据,实现了数据的恢复。

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

将已有ECS快照导入至ACK集群中的操作步骤如下。

  1. 使用以下YAML内容创建VolumeSnapshotContent。
    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 填写在ECS页面上的已生成的快照ID。
    volumeSnapshotRef 填写要创建的VolumeSnapshot的信息:
    • name:将要创建的VolumeSnapshot的名称。
    • namespace:将要创建的VolumeSnapshot所在的命名空间。
  2. 使用以下YAML内容创建VolumeSnapshot。
    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshot
    metadata:
      name: new-snapshot-demo
    spec:
      source:
        volumeSnapshotContentName: new-snapshot-content-test
    参数 描述
    metadata.name VolumeSnapshot的名称,需要和上述VolumeSnapshotContent中指定的相同。
    spec.source.volumeSnapshotContentName 是当前VolumeSnapshot绑定的VolumeSnapshotContent的名称,需与上述创建的VolumeSnapshotContent的名称一致。
  3. 恢复数据。
    1. 使用以下YAML内容创建nginx-restore文件。
      apiVersion: v1
      kind: Service
      metadata:
        name: nginx
        labels:
          app: nginx
      spec:
        ports:
        - port: 80
          name: web
        clusterIP: None
        selector:
          app: nginx
      ---
      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: web-restore
      spec:
        selector:
          matchLabels:
            app: nginx
        serviceName: "nginx"
        replicas: 1
        template:
          metadata:
            labels:
              app: nginx
          spec:
            hostNetwork: true
            containers:
            - name: nginx
              image: nginx
              command: ["sh", "-c"]
              args: ["sleep 10000"]
              volumeMounts:
              - name: disk-ssd
                mountPath: /data
        volumeClaimTemplates:
        - metadata:
            name: disk-ssd
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: alicloud-disk-ssd
            resources:
              requests:
                storage: 20Gi
            dataSource:
              name: new-snapshot-demo
              kind: VolumeSnapshot
              apiGroup: snapshot.storage.k8s.io
      说明volumeClaimTemplates中,需设置dataSource的类型为VolumeSnapshot,且VolumeSnapshot的名字为步骤2中创建的new-snapshot-demo。
    2. 执行以下命令恢复数据。
      kubectl apply -f nginx-restore.yaml
  4. 执行以下命令查看Pod(web-restore-0)数据。
    kubectl exec -it web-restore-0 ls /data
    输出:
    lost+found test
    可见在不同的Pod中返回相同数据,实现了数据的恢复。