Container ServiceKubernetes版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中返回相同的資料,實現了資料的恢複。