すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:複数のクラウドディスクボリュームのグループスナップショットの作成

最終更新日:Mar 27, 2026

Container Service for Kubernetes (ACK) のステートフルアプリケーションが複数のディスクで構成されている場合、各ディスクから個別に VolumeSnapshot を作成すると、各スナップショットがわずかに異なる時点のデータをキャプチャするため、リカバリーポイントに不整合が生じる可能性があります。グループスナップショットは、すべてのスナップショットを同時にトリガーすることでこの問題を解決し、グループ内のすべてのディスクが同じ瞬間にキャプチャされるようにします。これにより、複数のボリュームにまたがるアプリケーションを復元する必要がある場合に、データの不整合のリスクを低減できます。

仕組み

グループスナップショットは、ECS スナップショット整合性グループをベースに構築されています。ACK は、グループスナップショットの管理に使用できる以下の CustomResourceDefinitions (CRD) を提供します。

CRD 類似リソース 目的
VolumeGroupSnapshotClass StorageClass グループスナップショットのドライバーと削除ポリシーを定義します
VolumeGroupSnapshot PersistentVolumeClaim (PVC) ラベルセレクターによって識別されるディスクセットのスナップショットをリクエストします
VolumeGroupSnapshotContent PersistentVolume (PV) リクエストに応じて作成された ECS スナップショット整合性グループを記録します
VolumeSnapshot ボリュームスナップショットのリクエストです。VolumeGroupSnapshot の作成後に各ディスクに対して自動的に作成されます
VolumeSnapshotContent ECS スナップショットに関する情報を記録します

VolumeGroupSnapshot を作成すると、Container Storage Interface (CSI) プラグインが ECS スナップショット整合性グループを作成し、選択された各ディスクに対して VolumeSnapshot と VolumeSnapshotContent を自動的に生成します。ディスクに障害が発生した場合は、対応する VolumeSnapshot から復元します。

課金

スナップショット整合性グループは無料です。グループ内のスナップショットは、ストレージ使用量に基づいて課金されます。詳細については、「スナップショットの課金」をご参照ください。

制限事項

  • グループスナップショットは、ECS スナップショットと同じ制限に従います。詳細については、「使用制限」をご参照ください。

  • ECS スナップショット整合性グループでは、有効期限はサポートされていません。不要になったグループスナップショットは手動で削除してください。

前提条件

開始する前に、以下のものが揃っていることを確認してください。

説明

クラスターが FlexVolume (ACK では非推奨) を使用している場合は、グループスナップショットを作成する前に CSI にアップグレードしてください。詳細については、「FlexVolume から CSI へのアップグレード」をご参照ください。どのボリュームプラグインがインストールされているかを確認するには、ACK コンソールのクラスター詳細ページに移動し、左側のナビゲーションウィンドウで [運用管理] > [アドオン] を選択し、[ストレージ] タブをクリックします。

ステップ 1:機能ゲートの有効化

グループスナップショットを作成する前に、csi-provisioner で EnableVolumeGroupSnapshots 機能ゲートを有効にします。

  1. ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。

  2. [クラスター] ページで、クラスター名をクリックします。左側のナビゲーションウィンドウで、[運用管理] > [アドオン] を選択します。

  3. [アドオン] ページで、csi-provisioner カードを見つけ、右下隅の [設定] をクリックします。

  4. [csi-provisioner パラメーター] ダイアログボックスで、FeatureGate フィールドを EnableVolumeGroupSnapshots=true に設定し、[OK] をクリックします。他の機能ゲートがすでに有効になっている場合は、新しいゲートを追加します:xxxxxx=true,yyyyyy=false,EnableVolumeGroupSnapshots=true

ステップ 2:MySQL StatefulSet のデプロイ

この例では、2 つのレプリカを持つ MySQL StatefulSet を使用します。各レプリカは 20 GiB の ESSD ディスクを PVC としてマウントし、グループとしてスナップショットを作成するための 2 つのディスクを提供します。

  1. 次の内容で mysql.yaml を作成します:<details><summary>mysql.yaml</summary>

    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
              mountPath: /var/lib/mysql   # 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:
      password: MTIzNDU2   # "123456" の Base64 エンコード値
      username: cm9vdA==   # "root" の Base64 エンコード値

    </details>

  2. StatefulSet をデプロイします:

    kubectl apply -f mysql.yaml
  3. 両方の Pod レプリカにテストデータを書き込みます。mysql-0 Pod にログインし、行を挿入します:

    kubectl exec -it mysql-0 -- bash   # Pod 内でシェルを開く
    mysql -uroot -p123456              # MySQL に接続する
    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 |
    +------+-------+

    mysql-1 Pod についても同じ手順を繰り返します。

ステップ 3:グループスナップショットの作成

VolumeGroupSnapshotClass の作成

クラスターには、alibabacloud-disk-group-snapshot という名前のデフォルトの VolumeGroupSnapshotClass がすでに利用可能です。カスタムクラスを使用するには、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 フィールドは、VolumeGroupSnapshot を削除したときに、基盤となる ECS スナップショット整合性グループがどうなるかを制御します:

動作
Delete VolumeGroupSnapshotContent と ECS スナップショット整合性グループを削除します
Retain VolumeGroupSnapshotContent と ECS スナップショット整合性グループを保持します

クラスを適用します:

kubectl apply -f group-snapshot-class-demo.yaml

VolumeGroupSnapshot の作成

MySQL アプリケーションにマウントされた両方の PVC のスナップショットを作成するために、group-snapshot-demo.yaml を作成します:

apiVersion: groupsnapshot.storage.k8s.io/v1alpha1
kind: VolumeGroupSnapshot
metadata:
  name: group-snapshot-demo
  namespace: default
spec:
  source:
    selector:
      matchLabels:
        app: mysql           # このラベルを持つすべての PVC を選択します
  volumeGroupSnapshotClassName: group-snapshot-class-demo

source.selector フィールドは、ラベルセレクターを使用してバックアップする PVC を識別します。StatefulSet の volumeClaimTemplates から作成された PVC には、StatefulSet の Pod ラベルが自動的に付与されます。PVC を手動で作成した場合は、このステップを実行する前に対応するラベルを追加してください。

VolumeGroupSnapshot を適用します:

kubectl apply -f group-snapshot-demo.yaml

ステップ 4:グループスナップショットの確認

  1. VolumeGroupSnapshot を監視し、READYTOUSEfalse から true に変わるまで待ちます:

    kubectl get vgs group-snapshot-demo -w
  2. スナップショットの詳細を調べて、どの PVC がどの VolumeSnapshot にマッピングされているかを確認します:

    フィールド 説明
    Bound Volume Group Snapshot Content Name この VolumeGroupSnapshot にバインドされた VolumeGroupSnapshotContent
    Persistent Volume Claim Ref バックアップされた PVC の名前
    Volume Snapshot Ref その 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
  3. 両方の VolumeSnapshot が準備完了であることを確認します:

    kubectl get volumesnapshot

    両方のスナップショットで READYTOUSE: true が表示されるはずです。

  4. ECS スナップショット整合性グループ ID を取得します:

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

    期待される出力 (省略):

    Volume Group Snapshot Handle: ssg-2zeg72d1qym6vnxxxxxx

    ECS コンソールでスナップショット整合性グループを表示するには、ECS コンソールに移動し、左側のナビゲーションウィンドウで [ストレージとスナップショット] > [スナップショット] を選択し、[スナップショット整合性グループ] タブをクリックして、ssg-2zeg72d1qym6vnxxxxxx を検索します。

ステップ 5:スナップショットからのディスクボリュームの復元

2 つの復元オプションが利用可能です。1 つのボリュームを手動で復元するか、スクリプトを使用してすべてのボリュームを一度にバッチで復元します。

オプション 1:単一ボリュームの復元

次の例では、disk-mysql-0 Pod にアタッチされたディスクボリュームを復元します。

disk-mysql-0-copy.yaml を作成します。dataSource フィールドは、指定された VolumeSnapshot から新しいディスクをプロビジョニングするように CSI に指示します:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: disk-mysql-0-copy
spec:
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: "alicloud-disk-essd"
  dataSource:
    name: snapshot-1c2c5bcaf47ee2bffcc5b2f52dff65a4aacaaea38032c05d75acd536f7xxxxxx-2024-11-27-6.4.7  # [1]
    kind: VolumeSnapshot                                                                                  # [2]
    apiGroup: snapshot.storage.k8s.io                                                                    # [3]
  • [1] disk-mysql-0 をバックアップする VolumeSnapshot の名前 (上記の kubectl describe vgs の出力から)。

  • [2] リソースの種類 — スナップショットから復元する場合は常に VolumeSnapshot です。

  • [3] CSI スナップショットリソースの API グループ。

PVC を適用します:

kubectl apply -f disk-mysql-0-copy.yaml

PVC がバインドされていることを確認します:

kubectl get pvc disk-mysql-0-copy

期待される出力:

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

ディスクがスナップショットから作成されたことを確認するには、ECS コンソールに移動し、左側のナビゲーションウィンドウで [ストレージとスナップショット] > [ブロックストレージ] を選択し、[クラウドディスク] タブをクリックして、d-2ze0iwwqg0s6b0xxxxxx を検索します。ディスク詳細ページを開くと、スナップショットから作成されたことがわかります。

オプション 2:すべてのボリュームを一度にバッチで復元

generate_pvc.sh スクリプトを使用して、VolumeGroupSnapshot から PVC マニフェストを自動的に生成し、一度にすべて適用します。

  1. jq コマンドラインツールをインストールします:

    • CentOS: yum install jq

    • Ubuntu: apt-get install jq

  2. MySQL StatefulSet のレプリカ数を 0 にスケールダウンして、復元前にすべての書き込みを停止します:

    kubectl scale sts mysql --replicas=0
  3. 既存の PVC を削除します:

    kubectl delete pvc data-mysql-0 data-mysql-1
  4. 次の内容で generate_pvc.sh を作成します:<details><summary>generate_pvc.sh</summary>

    パラメーター 説明
    1 VolumeGroupSnapshot の名前空間 default
    2 VolumeGroupSnapshot の名前 group-snapshot-demo
    3 復元された PVC の StorageClass 名 alicloud-disk-essd
    4 ディスク容量 20Gi
    5 kubeconfig ファイルへのパス .kube/config
    6 生成された PVC YAML の出力パス ./output.yaml
    #!/bin/bash
    
    # 入力パラメーター
    NAMESPACE=$1           # VolumeGroupSnapshot の名前空間
    VGS_NAME=$2            # VolumeGroupSnapshot の名前
    STORAGE_CLASS_NAME=$3  # 復元された PVC の StorageClass
    CAPACITY=$4            # ディスク容量 (例:20Gi)
    KUBECONFIG_PATH=$5     # kubeconfig ファイルへのパス
    OUTPUT_FILE=$6         # 生成された YAML の出力パス
    
    # VolumeGroupSnapshot の詳細を取得
    VGS_INFO=$(kubectl --kubeconfig=${KUBECONFIG_PATH} -n ${NAMESPACE} get vgs ${VGS_NAME} -o json)
    
    # PVC とスナップショットのマッピングが存在することを確認
    if ! echo ${VGS_INFO} | jq -e '.status.pvcVolumeSnapshotRefList' &>/dev/null; then
      echo "エラー: .status.pvcVolumeSnapshotRefList が VolumeGroupSnapshot に見つかりません。"
      exit 1
    fi
    
    # PVC 名とそれに対応するスナップショット名を取得
    PVCS=($(echo ${VGS_INFO} | jq -r '.status.pvcVolumeSnapshotRefList[].persistentVolumeClaimRef.name'))
    SNAPSHOTS=($(echo ${VGS_INFO} | jq -r '.status.pvcVolumeSnapshotRefList[].volumeSnapshotRef.name'))
    
    # 出力ファイルをクリア
    > ${OUTPUT_FILE}
    
    # ディスクごとに 1 つの PVC マニフェストを生成
    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 ファイルが ${OUTPUT_FILE} に書き込まれました"

    </details> このスクリプトは、6 つの位置パラメーターを受け取ります:

  5. スクリプトを実行して PVC マニフェストを生成します:

    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

    必要に応じて output.yaml を編集し、適用します:

    kubectl apply -f output.yaml
  6. StatefulSet のレプリカ数を 2 に戻します:

    kubectl scale sts mysql --replicas=2
  7. Pod が再起動した後、データが復元されたことを確認します:

    kubectl exec -it mysql-0 -- bash   # Pod 内でシェルを開く
    mysql -uroot -p123456              # MySQL に接続する
    use test;
    select * from scores;

    期待される出力:

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

次のステップ