容器服務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中返回相同的數據,實現了數據的恢復。