GKE クラスタの永続ストレージをバックアップして復元する

このページでは、Kubernetes ボリューム スナップショットを使用して、GKE クラスタに関連付けられた基盤となる Filestore ストレージをバックアップおよび復元する方法について説明します。

Kubernetes ボリューム スナップショットの作成は、Filestore バックアップの作成と同等です。

詳細については、Kubernetes のボリューム スナップショットについての記事をご覧ください。

要件

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

  • Filestore CSI ドライバをデプロイする必要があります。次の Filestore サービスティアのみがサポートされています。

    • 基本 HDD(GKE バージョン 1.21 以降)
    • 基本 SSD(GKE バージョン 1.21 以降)
    • GKE バージョン 1.27 以降のゾーン(10 TiB~100 TiB)
    • Enterprise(GKE バージョン 1.25 以降)
  • コントロール プレーンのバージョン 1.17 以降を使用します。VolumeSnapshotFilestore CSI ドライバを使用するには、サービスティアに適用される GKE バージョン番号を使用します。

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

制限事項

  • スナップショット ボリュームには、通常のボリュームと同じサイズ制限があります。たとえば、Filestore スナップショットでは、基本 HDD ティアのサイズが 1 TiB 以上である必要があります。

  • Filestore の CSI ドライバは、次の Filestore サービスティアで動的プロビジョニングまたはバックアップ ワークフローをサポートしていません。

    • ゾーン(1 TiB~9.75 TiB)
    • リージョン
  • 一度にバックアップできるシェアは 1 つのインスタンスにつき 1 つのみです。ストレージ プールについては、2 つの異なる Filestore インスタンスからの 2 つの異なる共有から発行されたバックアップ リクエストは同時に実行されます。

  • シングルシェアのバックアップは、シングルシェアのボリュームにのみ復元できます。Filestore の CSI ドライバを使用する場合、新しい Filestore インスタンスにシングルシェアのボリュームのみを復元できます。

    • 新しいインスタンスでは、バックアップと同じサービスティアを使用する必要があります。
    • 新しいインスタンスの最小容量は、バックアップの最小容量と一致している必要があります。
  • ソースまたは既存の Filestore インスタンスに対する Filestore の backup restore オペレーションはサポートされていません。機能制限の一覧については、Filestore のバックアップ機能の制限事項をご覧ください。

  • マルチシェアのバックアップはサポートされていません。

準備

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

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components update を実行して最新のバージョンを取得する。

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

このドキュメントの例では、次の作業を行う方法について説明します。

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

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

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

PersistentVolumeClaimDeployment を作成する

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

    Filestore

     apiVersion: v1
     kind: PersistentVolumeClaim
     metadata:
       name: my-pvc
     spec:
       storageClassName: enterprise-rwx
       accessModes:
       - ReadWriteMany
       resources:
         requests:
           storage: 1Ti
    

    この例では、エンタープライズ階層の Filestore PVC を作成します。詳細については、Filestore CSI ドライバを使用して Filestore インスタンスにアクセスするをご覧ください。

    spec.storageClassName には、サポートされている 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
    

    Deployment の準備が完了するまでに時間がかかることがあります。次のような出力が表示されるまで、上記のコマンドを実行します。

    NAME        READY   UP-TO-DATE   AVAILABLE   AGE
    hello-app   1/1     1            1           2m55s
    

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

  1. DeploymentPods を一覧表示します。

    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 として保存します。

    Filestore

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

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

    • driver フィールドは、スナップショットをプロビジョニングするために CSI ドライバによって使用されます。この例では、filestore.csi.storage.gke.ioFilestore CSI ドライバを使用します。
    • deletionPolicy フィールドは、バインドされた VolumeSnapshot オブジェクトの削除時に、VolumeSnapshotContent オブジェクトとその基盤となるスナップショットを GKE でどのように処理するかを指示します。VolumeSnapshotContent オブジェクトと基盤となるスナップショットを削除するには、Delete を指定します。VolumeSnapshotContent とその基盤となるスナップショットを保持する場合は、Retain を指定します。
  2. 次のようにマニフェストを適用します。

    kubectl apply -f volumesnapshotclass.yaml
    

VolumeSnapshot の作成

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

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

    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
    

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

  3. GKE が VolumeSnapshotContents オブジェクトを作成したことを確認します。

    kubectl get volumesnapshotcontents
    

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

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

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

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
    

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

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

    Filestore

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-restore
    spec:
      dataSource:
        name: my-snapshot
        kind: VolumeSnapshot
        apiGroup: snapshot.storage.k8s.io
      storageClassName: enterprise-rwx
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 1Ti
    
  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
    

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

  1. 更新された 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 は、GKE が作成した新しい Pod の名前に置き換えます。

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

   Hello World!

既存のスナップショットをインポートする

現在のクラスタの外部で作成された既存のボリューム スナップショットを使用して、VolumeSnapshotContents オブジェクトを手動でプロビジョニングできます。たとえば、別のクラスタに作成された別の Google Cloud リソースのスナップショットを GKE のボリュームに入力できます。

  1. スナップショットの名前を探します。

    Google Cloud コンソール

    https://console.cloud.google.com/compute/snapshots に移動します。

    Google Cloud CLI

    次のコマンドを実行します。

    gcloud compute snapshots list
    

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

    NAME                                           DISK_SIZE_GB  SRC_DISK                                                     STATUS
    snapshot-5e6af474-cbcc-49ed-b53f-32262959a0a0  1             us-central1-b/disks/pvc-69f80fca-bb06-4519-9e7d-b26f45c1f4aa READY
    
  2. 次の VolumeSnapshot マニフェストを restored-snapshot.yaml として保存します。

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

    kubectl apply -f restored-snapshot.yaml
    
  4. 次の VolumeSnapshotContent マニフェストを restored-snapshot-content.yaml として保存します。snapshotHandle フィールドは、プロジェクト ID とスナップショット名に置き換えます。双方向のバインディングを有効にするには、volumeSnapshotRef.namevolumeSnapshotRef.namespace の両方が、以前に作成した VolumeSnapshot を参照している必要があります。

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshotContent
    metadata:
      name: restored-snapshot-content
    spec:
      deletionPolicy: Retain
      driver: filestore.csi.storage.gke.io
      source:
        snapshotHandle: projects/PROJECT_ID/global/snapshots/SNAPSHOT_NAME
      volumeSnapshotRef:
        kind: VolumeSnapshot
        name: restored-snapshot
        namespace: default
    
  5. 次のようにマニフェストを適用します。

    kubectl apply -f restored-snapshot-content.yaml
    
  6. 次の PersistentVolumeClaim マニフェストを restored-pvc.yaml として保存します。Kubernetes ストレージ コントローラは、restored-snapshot という名前の VolumeSnapshot を探し、データソースとして PersistentVolume を見つけるか、動的に作成しようとします。その後、Pod でこの PVC を使用して、復元されたデータにアクセスできます。

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

    kubectl apply -f restored-pvc.yaml
    
  8. 次の Pod マニフェストを restored-pod.yaml として保存し、PersistentVolumeClaim を参照します。CSI ドライバが PersistentVolume をプロビジョニングし、スナップショットで更新します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: restored-pod
    spec:
      containers:
      - name: busybox
        image: busybox
        args:
        - sleep
        - "3600"
        volumeMounts:
        - name: source-data
          mountPath: /demo/data
      volumes:
      - name: source-data
        persistentVolumeClaim:
          claimName: restored-pvc
          readOnly: false
    
  9. 次のようにマニフェストを適用します。

    kubectl apply -f restored-pod.yaml
    
  10. ファイルが復元されたことを確認します。

    kubectl exec restored-pod -- sh -c 'cat /demo/data/hello.txt'
    

クリーンアップ

このページで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、次の手順を行います。

  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
    

次のステップ