ボリューム スナップショットの使用

Google Kubernetes Engine(GKE)の Kubernetes ボリューム スナップショット機能は、GKE クラスタ内の永続ボリュームで使用できます。

ボリューム スナップショットを使用すると、特定の時点でのボリュームのコピーを作成できます。このコピーを使用して、ボリュームを以前の状態に戻すことができます。また、新しいボリュームをプロビジョニングすることもできます。

バージョン 1.17 以降では、次のコンポーネントを使用してボリューム スナップショットをプロビジョニングしてアタッチできます。

要件

GKE でボリューム スナップショットを使用するには、次の要件を満たす必要があります。

  • スナップショットをサポートする CSI ドライバを使用する。スナップショットは、ツリー内の永続ディスク ドライバではサポートされません。

  • GKE バージョン 1.17 以降のバージョンのコントロール プレーン(マスター)を使用する。Compute Engine 永続ディスクの CSI ドライバを使用するには、VolumeSnapshot で GKE バージョン 1.17.6-gke.4 以降を使用します。VolumeSnapshot で Filestore CSI ドライバを使用するには、GKE バージョン 1.21 以降を使用します。

  • スナップショットに使用する既存の PersistentVolumeClaim がある。スナップショット ソースに使用する PersistentVolume は、CSI ドライバによって管理される必要があります。CSI ドライバを使用しているかどうかを確認するには、PersistentVolume 仕様の csi セクションで driver: pd.csi.storage.gke.io または filestore.csi.storage.gke.io が指定されているかをチェックします。以降のセクションで説明のとおり、PersistentVolume が CSI ドライバによって動的にプロビジョニングされると、CSI ドライバによって管理されます。

始める前に

作業を始める前に、次のことを確認してください。

次のいずれかの方法で gcloud のデフォルトの設定を指定します。

  • gcloud init。デフォルトの設定全般を確認する場合に使用します。
  • gcloud config。プロジェクト ID、ゾーン、リージョンを個別に設定する場合に使用します。

gcloud init の使用

エラー One of [--zone, --region] must be supplied: Please specify location を受信した場合は、このセクションの内容を実施します。

  1. gcloud init を実行して、次の操作を行います。

    gcloud init

    リモート サーバーで SSH を使用している場合は、--console-only フラグを指定して、コマンドがブラウザを起動しないようにします。

    gcloud init --console-only
  2. 手順に従って gcloud を承認し、Google Cloud アカウントを使用します。
  3. 新しい構成を作成するか、既存の構成を選択します。
  4. Google Cloud プロジェクトを選択します。
  5. ゾーンクラスタの場合はデフォルトの Compute Engine ゾーン、リージョン クラスタまたは Autopilot クラスタの場合はデフォルトの Compute Engine リージョンを選択します。

gcloud config の使用

  • デフォルトのプロジェクト ID を設定します。
    gcloud config set project PROJECT_ID
  • ゾーンクラスタを使用する場合は、デフォルトのコンピューティング ゾーンを設定します。
    gcloud config set compute/zone COMPUTE_ZONE
  • Autopilot クラスタまたはリージョン クラスタを使用する場合は、デフォルトのコンピューティング リージョンを設定します。
    gcloud config set compute/region COMPUTE_REGION
  • gcloud を最新バージョンに更新します。
    gcloud components update

ボリューム スナップショットの作成と使用

このドキュメントの例では、次のことを行う方法を説明します。

  1. PersistentVolumeClaim と Deployment を作成する
  2. Deployment が使用する PersistentVolume にファイルを追加する
  3. VolumeSnapshotClass を作成してスナップショットを構成する
  4. PersistentVolume のボリューム スナップショットを作成する
  5. テストファイルを削除する
  6. 作成したスナップショットに PersistentVolume を復元する。
  7. 復元が機能していることを確認する

ボリューム スナップショットを使用するには、次の手順を行う必要があります。

  1. VolumeSnapshotClass オブジェクトを作成して、スナップショットの CSI ドライバと削除ポリシーを指定します。
  2. VolumeSnapshot オブジェクトを作成して、既存の PersistentVolumeClaim のスナップショットをリクエストします。
  3. PersistentVolumeClaim 内の VolumeSnapshot を参照して、そのスナップショットにボリュームを復元するか、スナップショットを使用して新しいボリュームを作成します。

PersistentVolumeClaim と Deployment を作成する

  1. PersistentVolumeClaim オブジェクトを作成するには、次のマニフェストを my-pvc.yaml として保存します。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: my-pvc
    spec:
      storageClassName: standard-rwo
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    

    spec.storageClassName には、サポートされている CSI ドライバを使用するストレージ クラスを指定できます。この例では、Compute Engine 永続ディスクの CSI ドライバとともにデフォルトでインストールされた standard-rwo ストレージ クラスを使用します。詳細については、Compute Engine 永続ディスクの CSI ドライバの使用をご覧ください。

  2. 次のようにマニフェストを適用します。

    kubectl apply -f my-pvc.yaml
    
  3. Deployment を作成するには、次のマニフェストを my-deployment.yaml として保存します。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-app
    spec:
      selector:
        matchLabels:
          app: hello-app
      template:
        metadata:
          labels:
            app: hello-app
        spec:
          containers:
          - name: hello-app
            image: google/cloud-sdk:slim
            args: [ "sleep", "3600" ]
            volumeMounts:
            - name: sdk-volume
              mountPath: /usr/share/hello/
          volumes:
          - name: sdk-volume
            persistentVolumeClaim:
              claimName: my-pvc
    
  4. 次のようにマニフェストを適用します。

    kubectl apply -f my-deployment.yaml
    
  5. Deployment のステータスを確認します。

    kubectl get deployment hello-app
    

ボリュームにテストファイルを追加する

  1. Deployment 内の Pod を一覧表示します。

    kubectl get pods -l app=hello-app
    

    出力は次のようになります。

    NAME                         READY   STATUS    RESTARTS   AGE
    hello-app-6d7b457c7d-vl4jr   1/1     Running   0          2m56s
    
  2. Pod にテストファイルを作成します。

    kubectl exec POD_NAME -- sh -c 'echo "Hello World!" > /usr/share/hello/hello.txt'
    

    POD_NAME は、Pod の名前で置き換えます。

  3. ファイルが存在することを確認します。

    kubectl exec POD_NAME -- sh -c 'cat /usr/share/hello/hello.txt'
    

    出力は次のようになります。

    Hello World!
    

VolumeSnapshotClass オブジェクトを作成する

VolumeSnapshotClass オブジェクトを作成して、ボリューム スナップショットの CSI ドライバと deletionPolicy を指定します。VolumeSnapshot オブジェクトの作成時に VolumeSnapshotClass オブジェクトを参照できます。

  1. 次のマニフェストを volumesnapshotclass.yaml として保存します。クラスタの GKE のバージョンに応じて、API バージョン v1beta1 または v1 を使用できます。

    v1beta1

    バージョン 1.21 以前を実行しているクラスタには、v1beta1 API バージョンを使用します。

    apiVersion: snapshot.storage.k8s.io/v1beta1
    kind: VolumeSnapshotClass
    metadata:
      name: my-snapshotclass
    driver: pd.csi.storage.gke.io
    deletionPolicy: Delete
    

    v1

    バージョン 1.21 以降を実行しているクラスタには、v1 API バージョンを使用します。

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshotClass
    metadata:
      name: my-snapshotclass
    driver: pd.csi.storage.gke.io
    deletionPolicy: Delete
    

    この例では次のようになります。

    • driver フィールドは、スナップショットのプロビジョニングに使用する CSI ドライバです。pd.csi.storage.gke.io は、Compute Engine 永続ディスクの CSI ドライバを使用します。

    • deletionPolicy フィールドは、バインドされた VolumeSnapshot オブジェクトの削除時に、VolumeSnapshotContent オブジェクトとその基盤となるスナップショットを GKE でどのように処理するかを指示します。VolumeSnapshotContent オブジェクトと基盤となるスナップショットを削除するには、Delete を指定します。VolumeSnapshotContent と基盤となるスナップショットを保持する場合は、Retain を指定します。

    カスタム ストレージ ロケーションを使用するには、storage-locations パラメータをスナップショット クラスに追加します(クラスタ バージョン 1.21 以降が必要です)。

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshotClass
    metadata:
      name: my-snapshotclass
    parameters:
      storage-locations: us-east2
    driver: pd.csi.storage.gke.io
    deletionPolicy: Delete
    
  2. 次のようにマニフェストを適用します。

    kubectl apply -f volumesnapshotclass.yaml
    

VolumeSnapshot を作成する

VolumeSnapshot オブジェクトは、既存の PersistentVolumeClaim オブジェクトのスナップショットのリクエストです。VolumeSnapshot オブジェクトを作成すると、GKE はオブジェクトを自動的に作成し、VolumeSnapshotContent オブジェクト(PersistentVolume オブジェクトなどのクラスタ内のリソース)とバインドします。

  1. 次のマニフェストを volumesnapshot.yaml として保存します。API バージョン v1beta1 または v1 を使用できます。

    v1beta1

    バージョン 1.21 以前を実行しているクラスタには、v1beta1 API バージョンを使用します。

    apiVersion: snapshot.storage.k8s.io/v1beta1
    kind: VolumeSnapshot
    metadata:
      name: my-snapshot
    spec:
      volumeSnapshotClassName: my-snapshotclass
      source:
        persistentVolumeClaimName: my-pvc
    

    v1

    バージョン 1.21 以降を実行しているクラスタには、v1 API バージョンを使用します。

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshot
    metadata:
      name: my-snapshot
    spec:
      volumeSnapshotClassName: my-snapshotclass
      source:
        persistentVolumeClaimName: my-pvc
    
  2. 次のようにマニフェストを適用します。

    kubectl apply -f volumesnapshot.yaml
    

    ボリューム スナップショットを作成すると、GKE がクラスタに対応する VolumeSnapshotContent オブジェクトを作成します。このオブジェクトには、VolumeSnapshot オブジェクトのスナップショットとバインディングが格納されます。VolumeSnapshotContents オブジェクトを直接操作することはありません。

  3. GKE が VolumeSnapshotContents オブジェクトを作成したことを確認するには、次のコマンドを実行します。

    kubectl get volumesnapshotcontents
    

    出力は次のようになります。

    NAME                                               AGE
    snapcontent-cee5fb1f-5427-11ea-a53c-42010a1000da   55s
    

ボリューム スナップ ショットのコンテンツが作成されると、VolumeSnapshotClass で指定した CSI ドライバによって、対応するストレージ システムにスナップショットが作成されます。GKE がストレージ システムにスナップショットを作成し、クラスタ上のボリューム スナップショット オブジェクトにバインドすると、スナップショットが使用できるようになります。ステータスを確認するには、次のコマンドを実行します。

kubectl get volumesnapshot \
  -o custom-columns='NAME:.metadata.name,READY:.status.readyToUse'

使用する準備ができている場合、出力は次のようになります。

NAME               READY
my-snapshot        true

テストファイルを削除する

  1. 作成したテストファイルを削除します。

    kubectl exec POD_NAME -- sh -c 'rm /usr/share/hello/hello.txt'
    
  2. ファイルが存在していないことを確認します。

    kubectl exec POD_NAME -- sh -c 'cat /usr/share/hello/hello.txt'
    

    出力は次のようになります。

    cat: /usr/share/hello/hello.txt: No such file or directory
    

ボリューム スナップショットを復元する

PersistentVolumeClaimVolumeSnapshot を参照して、既存のボリュームのデータで新しいボリュームをプロビジョニングできます。また、ボリュームをスナップショットでキャプチャした状態に復元することもできます。

PersistentVolumeClaimVolumeSnapshot を参照するには、PersistentVolumeClaimdataSource フィールドを追加します。

この例では、新しい PersistentVolumeClaim で作成した VolumeSnapshot を参照して、新しいクレームを使用するように Deployment を更新します。

  1. 次のマニフェストを pvc-restore.yaml として保存します。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-restore
    spec:
      dataSource:
        name: my-snapshot
        kind: VolumeSnapshot
        apiGroup: snapshot.storage.k8s.io
      storageClassName: standard-rwo
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    
  2. 次のようにマニフェストを適用します。

    kubectl apply -f pvc-restore.yaml
    
  3. 新しい PersistentVolumeClaim を使用するように my-deployment.yaml を更新します。

    ...
    volumes:
    - name: my-volume
      persistentVolumeClaim:
        claimName: pvc-restore
    
  4. 更新されたマニフェストを適用します。

    kubectl apply -f my-deployment.yaml
    

スナップショットが正常に復元されたことを確認する

スナップショットが正常に復元されたことを確認するには、更新された Deployment 用に GKE が作成した新しい Pod の名前を取得します。

kubectl get pods -l app=hello-app

テストファイルが存在することを確認します。

kubectl exec NEW_POD_NAME -- sh -c 'cat /usr/share/hello/hello.txt'

NEW_POD_NAME は、作成した新しい Pod GKE の名前に置き換えます。

出力は次のようになります。

Hello World!

クリーンアップ

  1. VolumeSnapshot を削除します。

    kubectl delete volumesnapshot my-snapshot
    
  2. VolumeSnapshotClass を削除します。

    kubectl delete volumesnapshotclass my-snapshotclass
    
  3. Deployment を削除します。

    kubectl delete deployments hello-app
    
  4. PersistentVolumeClaim オブジェクトを削除します。

    kubectl delete pvc my-pvc pvc-restore
    

次のステップ