全部產品
Search
文件中心

Container Service for Kubernetes:為多個雲端硬碟儲存卷建立組快照

更新時間:Jun 25, 2025

雲端硬碟儲存快照可以協助您實現應用資料的備份和恢複。在多雲端硬碟情境下,通過VolumeSnapshot資源為雲端硬碟分別單獨建立快照,難以保證快照時刻一致。通過組快照,您可以統一管理和備份多個雲端硬碟,減少因非同步快照導致的資料不一致風險。

前提條件

  • 已建立ACK託管叢集,且叢集為1.28及以上版本。

  • 叢集預設已安裝CSI組件,確保CSI組件為1.31.4及以上版本。如需升級請參見升級csi-plugin和csi-provisioner

    說明

    如果您叢集中使用Flexvolume組件,由於Flexvolume已廢棄,請在遷移Flexvolume至CSI完成後再使用組快照。您可以在營運管理 > 組件管理,在儲存頁簽下確認儲存群組件類型。

  • 已開通快照,開通快照不收費,建立快照後才開始收費。

計費說明

組快照功能基於ECS快照一致性組實現,使用ECS快照一致性組本身不收費,但會收取組內各個快照的容量費用。更多資訊,請參見快照計費

使用限制

組快照的使用限制與ECS快照一致性組一致,請參見建立快照一致性組

使用說明

您可以通過定義以下自訂資源(CRD),聲明五種與組快照相關的Kubernetes資源類型。

CRD

描述

VolumeGroupSnapshotClass

定義VolumeGroupSnapshot使用的刪除策略等參數。

VolumeGroupSnapshot

聲明一個儲存卷組快照執行個體,指定需要備份的雲端硬碟目標。

VolumeGroupSnapshotContent

記錄實際建立的ECS快照一致性組執行個體資訊。

VolumeSnapshot

聲明單個儲存卷快照執行個體。VolumeGroupSnapshot建立後,將自動為需要備份的雲端硬碟生產時刻一致的一組VolumeSnapshot。

VolumeSnapshotContent

記錄實際建立的單個ECS快照執行個體資訊。

VolumeGroupSnapshotClass、VolumeGroupSnapshot與VolumeGroupSnapshotContent之間的關係類似於StorageClass、PersistentVolumeClaim與PersistentVolume。當VolumeGroupSnapshot資源建立成功後,CSI組件將會建立出對應的ECS快照一致性組,自動在叢集中產生一組VolumeSnapshot及對應的VolumeSnapshotContent。若某個雲端硬碟出現異常,可通過其對應的VolumeSnapshot完成恢複。

使用樣本

1、開啟組快照相關的特性門控

建立組快照前,您需要先開啟EnableVolumeGroupSnapshots特性門控。

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集列表

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,單擊組件管理

  3. 組件管理頁面,找到csi-provisioner組件,單擊對應的配置

  4. csi-provisioner 參數配置頁面,設定FeatureGate參數為EnableVolumeGroupSnapshots=true,然後單擊確認

    若之前已經開啟過其他特性門控,則參數填寫格式為xxxxxx=true,yyyyyy=false,EnableVolumeGroupSnapshots=true

2、建立MySQL樣本應用

  1. 使用以下YAML樣本,建立多副本的有狀態應用mysql.yaml檔案。

    展開查看有狀態應用mysql.yaml檔案

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: mysql
    spec:
      selector:
        matchLabels:
          app: mysql
      serviceName: "mysql"
      replicas: 2
      template:
        metadata:
          labels:
            app: mysql
        spec:
          containers:
          - name: mysql
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/mysql:8.0.30-8.6
            env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-pass
                  key: password
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - name: data
              # MySQL存放資料的位置
              mountPath: /var/lib/mysql
              subPath: mysql
      volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: "alicloud-disk-essd"
          resources:
            requests:
              storage: 20Gi
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: mysql-pass
    type: Opaque
    data:   # 以下為登入MySQL樣本資料庫的使用者名稱和密碼(BASE64編碼形式),也可自訂。
      password: MTIzNDU2   
      username: cm9vdA==  
    
  2. 部署有狀態應用MySQL。

    kubectl apply -f mysql.yaml
  3. 為兩個不同副本分別寫入資料。

    1. 登入mysql-0副本,並串連資料庫。

      kubectl exec -it mysql-0 -- bash  # 登入Pod。
      mysql -uroot -p123456  # 串連資料庫。
    2. 在資料庫中執行以下命令,寫入資料。

      create database test;
      use test;
      create table scores( name VARCHAR(50) NOT NULL, score INT AUTO_INCREMENT PRIMARY KEY );
      insert into scores(name,score) values("Amy",95);
      select * from scores;

      最後一步預期輸出:

      +------+-------+
      | name | score |
      +------+-------+
      | Amy  |    95 |
      +------+-------+
    3. 使用以上方法,為mysql-1副本寫入資料。

3、為MySQL應用建立組快照

  1. 建立組快照類VolumeGroupSnapshotClass。

    此時叢集中應已預設存在組快照類alibabacloud-disk-group-snapshot,您也可以使用以下group-snapshot-class-demo.yaml樣本,建立自訂群組快照類。

    apiVersion: groupsnapshot.storage.k8s.io/v1alpha1
    kind: VolumeGroupSnapshotClass
    metadata:
      name: group-snapshot-class-demo
    deletionPolicy: Delete
    driver: diskplugin.csi.alibabacloud.com

    deletionPolicy參數取值說明如下:

    • Delete:刪除VolumeGroupSnapshot時,VolumeGroupSnapshotContent以及關聯的組快照也會一起被刪除。

    • Retain:刪除VolumeGroupSnapshot時,VolumeGroupSnapshotContent以及關聯的組快照不會被刪除。

    說明

    當前ECS快照一致性組暫不支援設定到期時間,建立的組快照執行個體需要手動刪除。

  2. 部署建立組快照類VolumeGroupSnapshotClass。

    kubectl apply -f group-snapshot-class-demo.yaml
  3. 使用以下group-snapshot-demo.yaml樣本,為上述MySQL應用建立出的兩個雲端硬碟儲存卷建立組快照。

    apiVersion: groupsnapshot.storage.k8s.io/v1alpha1
    kind: VolumeGroupSnapshot
    metadata:
      name: group-snapshot-demo
      namespace: default
    spec:
      source:
        selector:
          matchLabels:
            app: mysql
      volumeGroupSnapshotClassName:
        group-snapshot-class-demo

    source.selector:labelSelector用於選擇需要備份的PVC的標籤。

    由volumeClaimTemplates建立的PVC會內建與應用一致的標籤。若您通過其他方式建立PVC,可手動打上統一的標籤。

  4. 部署組快照。

    kubectl apply -f group-snapshot-demo.yaml

4、驗證組快照是否建立成功

  1. 查詢已建立的VolumeGroupSnapshot資源,並等待其建立成功。

    kubectl get vgs group-snapshot-demo -w

    預期READYTOUSEfalse變為true

  2. 查詢實際備份的PVC列表,以及為每個PVC自動建立的VolumeSnapshot列表。

    kubectl describe vgs group-snapshot-demo

    預期輸出包含類似以下內容:

    Status:
      Bound Volume Group Snapshot Content Name: groupsnapcontent-adcef6ef-811a-4e9d-ba51-3927caxxxxxx
      Creation Time: 2024-11-27T06:02:56Z
      Pvc Volume Snapshot Ref List:
        Persistent Volume Claim Ref:
          Name: disk-mysql-0
        Volume Snapshot Ref:
          Name: snapshot-1c2c5bcaf47ee2bffcc5b2f52dff65a4aacaaea38032c05d75acd536f7xxxxxx-2024-11-27-6.4.7
        Persistent Volume Claim Ref:
          Name: disk-mysql-1
        Volume Snapshot Ref:
          Name: snapshot-37a2fbf634d68cd2103f261313c2ed781fbd2bd52b5a0d0e0c0ef7c339xxxxxx-2024-11-27-6.4.9

    參數

    說明

    Bound Volume Group Snapshot Content Name

    與該VolumeGroupSnapshot綁定的VolumeGroupSnapshotContent資源。

    Pvc Volume Snapshot Ref List

    PVC關聯的VolumeSnapshot,包含以下參數:

    • Persistent Volume Claim Ref:備份的雲端硬碟儲存卷的PVC名稱。

    • Volume Snapshot Ref:自動建立的與PVC對應VolumeSnapshot資源。

  3. 查詢Volumesnapshot資源。

    kubectl get volumesnapshot \ 

    預期輸出:

    snapshot-1c2c5bcaf47ee2bffcc5b2f52dff65a4aacaaea38032c05d75acd536f7xxxxxx-2024-11-27-6.4.7 \
    snapshot-37a2fbf634d68cd2103f261313c2ed781fbd2bd52b5a0d0e0c0ef7c339xxxxxx-2024-11-27-6.4.9

    預期ReadyToUse均為true

  4. 查詢實際建立的ECS快照一致性組執行個體資訊。

    kubectl describe vgsc groupsnapcontent-adcef6ef-811a-4e9d-ba51-3927caxxxxxx

    預期輸出包含類似以下內容:

      Volume Group Snapshot Handle:  ssg-2zeg72d1qym6vnxxxxxx

    前往ECS管理主控台,在左側導覽列選擇儲存與快照 > 快照,在快照一致性組頁簽下,通過以上輸出的快照一致性組ID搜尋ssg-2zeg72d1qym6vnxxxxxx,預期看到對應的組快照執行個體資訊。

5、使用快照恢複MySQL中的雲端硬碟儲存卷

您可以手動恢複單個指定的雲端硬碟儲存卷,也可以通過指令碼大量復原組快照中所有的雲端硬碟儲存卷

手動恢複單個指定的雲端硬碟儲存卷

下文樣本以恢複上述MySQL應用中的disk-mysql-0對應的雲端硬碟儲存卷為例,介紹如何恢複指定的雲端硬碟儲存卷。

  1. 使用以下disk-mysql-0-copy.yaml樣本,建立恢複的雲端硬碟儲存卷。CSI將為其建立新的雲端硬碟,且雲端硬碟內資料與disk-mysql-0一致。

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: disk-mysql-0-copy
    spec:
      volumeMode: Filesystem
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 20Gi 
      storageClassName: "alicloud-disk-essd"
      dataSource:
        # disk-mysql-0 PVC對應的VolumeSnapshot資源。
        name: snapshot-1c2c5bcaf47ee2bffcc5b2f52dff65a4aacaaea38032c05d75acd536f7xxxxxx-2024-11-27-6.4.7
        kind: VolumeSnapshot
        apiGroup: snapshot.storage.k8s.io
  2. 建立恢複的雲端硬碟儲存卷。

    kubectl apply -f disk-mysql-0-copy.yaml
  3. 查詢已建立的PVC。

    kubectl get pvc disk-mysql-0-copy

    預期輸出:

    disk-mysql-0-copy   Bound    d-2ze0iwwqg0s6b0xxxxxx             20Gi       RWO            alicloud-disk-essd               <unset>                 69s

    前往ECS管理主控台,在左側導覽列選擇儲存與快照 > Block Storage,在雲端硬碟頁簽下,通過以上輸出的雲端硬碟ID搜尋d-2ze0iwwqg0s6b0xxxxxx,並單擊該ID查詢其詳情,可見其由快照建立。

通過指令碼大量復原組快照中所有的雲端硬碟儲存卷

下文樣本使用組快照批量重建雲端硬碟PVC,由上述MySQL應用掛載。

  1. 將MySQL應用副本數縮至0。

    kubectl scale sts mysql --replicas=0
  2. 刪除已有的兩個雲端硬碟儲存卷。

    kubectl delete pvc data-mysql-0 data-mysql-1
  3. 使用以下generate_pvc.sh指令碼,產生部署系列資料來源為快照的PVC YAML檔案。

    1. 使用以下generate_pvc.sh指令碼,需提前安裝jq命令列工具。

      展開查看如何安裝jq

      • CentOS

        yum install jq 
      • Ubuntu

        apt-get install jq

      展開查看generate_pvc.sh指令碼

      #!/bin/bash
      
      # 輸入參數。
      NAMESPACE=$1
      VGS_NAME=$2
      STORAGE_CLASS_NAME=$3
      CAPACITY=$4
      KUBECONFIG_PATH=$5
      OUTPUT_FILE=$6
      
      # 擷取 VolumeGroupSnapshot 的詳細資料。
      VGS_INFO=$(kubectl --kubeconfig=${KUBECONFIG_PATH} -n ${NAMESPACE} get vgs ${VGS_NAME} -o json)
      
      # 檢查 .status.pvcVolumeSnapshotRefList 是否存在。
      if ! echo ${VGS_INFO} | jq -e '.status.pvcVolumeSnapshotRefList' &>/dev/null; then
        echo "Error: .status.pvcVolumeSnapshotRefList not found in VolumeGroupSnapshot."
        exit 1
      fi
      
      # 解析 .status.pvcVolumeSnapshotRefList。
      PVCS=($(echo ${VGS_INFO} | jq -r '.status.pvcVolumeSnapshotRefList[].persistentVolumeClaimRef.name'))
      SNAPSHOTS=($(echo ${VGS_INFO} | jq -r '.status.pvcVolumeSnapshotRefList[].volumeSnapshotRef.name'))
      
      # 清空輸出檔案。
      > ${OUTPUT_FILE}
      
      # 產生 N 個 PVC 的 YAML 檔案。
      for i in "${!PVCS[@]}"; do
        PVC_NAME=${PVCS[$i]}
        SNAPSHOT_NAME=${SNAPSHOTS[$i]}
      
        cat <<EOF >> ${OUTPUT_FILE}
      ---
      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: ${PVC_NAME}
      spec:
        volumeMode: Filesystem
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: ${CAPACITY}
        storageClassName: "${STORAGE_CLASS_NAME}"
        dataSource:
          name: ${SNAPSHOT_NAME}
          kind: VolumeSnapshot
          apiGroup: snapshot.storage.k8s.io
      EOF
      done
      
      echo "PVC YAML files have been written to ${OUTPUT_FILE}"

      generate_pvc.sh指令碼中輸入參數的變數說明如下:

      入參

      說明

      樣本值

      1

      VolumeGroupSnapshot資源所在命名空間。

      default

      2

      VolumeGroupSnapshot資源名稱。

      group-snapshot-demo

      3

      儲存類名稱。

      alicloud-disk-essd

      4

      雲端硬碟的容量。

      20Gi

      5

      KubeConfig檔案位置。

      .kube/config (預設位置)

      6

      產生的PVC YAML檔案存放的位置。

      ./output.yaml

    2. 產生資料來源為快照的PVC YAML檔案。

      bash generate_pvc.sh default group-snapshot-demo alicloud-disk-essd 20Gi .kube/config ./output.yaml

      產生的output.yaml樣本如下,可根據實際情況調整,然後在叢集中部署。

      ---
      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: disk-mysql-0
      spec:
        volumeMode: Filesystem
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 20Gi
        storageClassName: "alicloud-disk-essd"
        dataSource:
          name: snapshot-1c2c5bcaf47ee2bffcc5b2f52dff65a4aacaaea38032c05d75acd536f7adb850-2024-11-27-6.4.7
          kind: VolumeSnapshot
          apiGroup: snapshot.storage.k8s.io
      ---
      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: disk-mysql-1
      spec:
        volumeMode: Filesystem
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 20Gi
        storageClassName: "alicloud-disk-essd"
        dataSource:
          name: snapshot-37a2fbf634d68cd2103f261313c2ed781fbd2bd52b5a0d0e0c0ef7c3396fea1c-2024-11-27-6.4.9
          kind: VolumeSnapshot
          apiGroup: snapshot.storage.k8s.io
    3. 在叢集中部署產生的output.yaml檔案,批量重建雲端硬碟PVC。

      kubectl apply -f output.yaml
  4. 恢複MySQL應用的副本數。

    kubectl scale sts mysql --replicas=2
  5. 應用重新啟動後,確認資料已經恢複。

    kubectl exec -it mysql-0 -- bash   # 登入Pod。
    mysql -uroot -p123456              # 在Pod中繼續執行。
    use test;                          # 在資料庫中執行。
    select * from scores;

    最後一步預期輸出:

    +------+-------+
    | name | score |
    +------+-------+
    | Amy  |    95 |
    +------+-------+

相關文檔

如需為單個雲端硬碟建立快照,請參見為單個雲端硬碟儲存卷建立快照