容器服务Kubernetes版ACK(Container Service for Kubernetes)的云盘存储快照特性可以帮助您实现应用数据的备份和恢复。本文介绍ACK的存储快照的基本概念、使用流程,并说明如何动态、静态创建快照。
前提条件
已创建ACK集群,且集群版本为1.18及以上版本。具体操作,请参见创建Kubernetes托管版集群。
背景信息
在阿里云ACK集群中部署有状态服务通常使用云盘数据卷存储数据,虽然云盘本身提供了数据的备份(快照)恢复机制,但是如何将这种机制和Kubernetes服务集成并灵活地提供给应用使用?为了解决这个问题,Kubernetes使用以下两个特性来实现备份恢复能力:
通过VolumeSnapshot资源实现云盘的备份(快照功能)。
通过PVC的DataSource功能实现数据的恢复。
计费说明
云盘快照基于阿里云ECS快照实现,关于ECS云盘快照的计费信息,请参见快照计费。
自2023年10月12日11:00起,阿里云ECS快照升级新版不再收取快照极速可用存储费和快照极速可用次数费,更多信息,请参见快照极速可用能力。
使用说明
为了实现快照相关功能,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使用云盘动态创建快照使用流程如下图所示。
使用PL0、PL1、PL2、PL3级别的ESSD云盘或ESSD AutoPL云盘时,动态创建的快照默认开启快照极速可用功能。
使用流程说明如下。
流程步骤 | 描述 |
① | 创建原始应用,创建云盘卷保存数据。 |
② | 创建VolumeSnapshot,此时集群会自动创建VolumeSnapshotContent和存储端的快照实例。 |
③ | 创建新的应用,并配置PVC引用步骤②中创建的快照对象。 |
上述的三个步骤实现:
备份:图中的Volume1的数据被备份到Snapshot1。
恢复:Snapshot1的数据(也就是Volume1的数据)被恢复成Volume2。
本文示例将通过创建MySQL应用并恢复应用的数据,说明如何使用存储快照功能。操作步骤如下。
创建VolumeSnapshotClass快照类。
使用以下YAML内容创建volumesnapshotclass.yaml文件。
apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotClass metadata: name: default-snapclass driver: diskplugin.csi.alibabacloud.com parameters: retentionDays: "5" deletionPolicy: Delete
参数
说明
deletionPolicy
当值为Delete时,说明删除VolumeSnapshot时,VolumeSnapshotContent以及关联的快照也会一起被删除。
当值为Retain时,说明删除VolumeSnapshot时,VolumeSnapshotContent以及关联的快照不会被删除。
parameters.retentionDays
指定快照自动回收时间。
parameters.forceDelete
当指定forceDelete为"true"时,表示使用强制删除快照功能。自csi-provisioner组件v1.26.5-92f859a-aliyun版本起,默认使用强制删除且不可修改,此前默认为普通删除。
强制删除:强制删除用户创建的所有已使用和未使用的快照。
普通删除:只能删除未使用的快照。已经使用过的快照,不能使用普通删除。
执行以下命令创建VolumeSnapshotClass快照类。
kubectl apply -f volumesnapshotclass.yaml
创建原始应用并写入数据。
使用以下YAML内容创建mysql.yaml文件。
apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql spec: selector: matchLabels: app: mysql serviceName: "mysql" replicas: 1 template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:5.7 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password imagePullPolicy: IfNotPresent volumeMounts: - name: disk mountPath: /data volumeClaimTemplates: - metadata: name: disk spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "alicloud-disk-topology-alltype" resources: requests: storage: 20Gi --- apiVersion: v1 kind: Secret metadata: name: mysql-pass type: Opaque data: username: dGVz**** password: dGVzdDEt****
执行以下命令创建应用MySQL。
kubectl apply -f mysql.yaml
执行以下命令往Pod(mysql-0)中写入数据。
kubectl exec -it mysql-0 -- touch /data/test kubectl exec -it mysql-0 -- ls /data
输出:
lost+found test
创建VolumeSnapshot。
说明若您集群使用的CSI版本不低于v1.22.12-b797ad9-aliyun,创建快照时, 不依赖该PVC是否有Running Pod存在,可对任意挂载过的云盘创建快照。关于CSI版本更多信息,请参见csi-provisioner。
若您集群使用的CSI版本低于v1.22.12-b797ad9-aliyun,创建快照时,则需要保证有Pod正在使用当前PVC,即保证云盘处于挂载状态。
使用以下YAML内容创建snapshot.yaml文件。
apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: new-snapshot-demo namespace: default spec: volumeSnapshotClassName: default-snapclass source: persistentVolumeClaimName: disk-mysql-0
执行以下命令创建VolumeSnapshot。
kubectl apply -f snapshot.yaml
执行以下命令查看是否创建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
恢复数据。
使用以下YAML内容创建mysql-restore文件。
apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql-restore spec: selector: matchLabels: app: mysql serviceName: "mysql" replicas: 1 template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:5.7 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password 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
说明在volumeClaimTemplates中,需设置dataSource的类型为VolumeSnapshot,且VolumeSnapshot的名字为步骤3中创建的new-snapshot-demo。
执行以下命令恢复数据。
kubectl apply -f mysql-restore.yaml
执行以下命令查看Pod(mysql-restore-0)数据。
kubectl exec -it mysql-restore-0 -- ls /data
输出:
lost+found test
可见在不同的Pod中返回相同的数据,实现了数据的恢复。
静态创建快照(使用ECS上已有快照)
将已有ECS快照导入至ACK集群中的操作步骤如下。
使用以下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所在的命名空间。
使用以下YAML内容创建VolumeSnapshot。
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的名称,需要和上述VolumeSnapshotContent中指定的相同。
spec.source.volumeSnapshotContentName
当前VolumeSnapshot绑定的VolumeSnapshotContent的名称,需与上述创建的VolumeSnapshotContent的名称一致。
恢复数据。
使用以下YAML内容创建mysql-restore文件。
apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql-restore spec: selector: matchLabels: app: mysql serviceName: "mysql" replicas: 1 template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:5.7 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password 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
说明在volumeClaimTemplates中,需设置dataSource的类型为VolumeSnapshot,且VolumeSnapshot的名字为步骤2中创建的new-snapshot-demo。
执行以下命令恢复数据。
kubectl apply -f mysql-restore.yaml
执行以下命令查看Pod(mysql-restore-0)数据。
kubectl exec -it mysql-restore-0 -- ls /data
输出:
lost+found test
可见在不同的Pod中返回相同的数据,实现了数据的恢复。