このページでは、ボリューム スナップショットを使用して Persistent Disk ストレージをバックアップおよび復元する方法について説明します。
概要については、Kubernetes のボリューム スナップショットについての記事をご覧ください。
要件
GKE でボリューム スナップショットを使用するには、次の要件を満たす必要があります。
- スナップショットをサポートする CSI ドライバを使用します。in-tree の Persistent Disk ドライバはスナップショットをサポートしていません。スナップショットを作成して管理するには、基盤となる - PersistentVolumeClaim(PVC)と同じ CSI ドライバを使用する必要があります。- Persistent Disk(PD)ボリューム スナップショットの場合は、Compute Engine Persistent Disk の CSI ドライバを使用します。GKE バージョン 1.18.10-gke.2100 以降、またはバージョン 1.19.3-gke.2100 を実行する新しい Linux クラスタには、Compute Engine Persistent Disk の CSI ドライバがデフォルトでインストールされます。また、既存のクラスタで Compute Engine Persistent Disk の CSI ドライバを有効にすることもできます。 
- スナップショットをサポートするすべての CSI ドライバの一覧については、Kubernetes ドキュメントの Drivers にある Other Features の列をご覧ください。 
 
- コントロール プレーンのバージョン 1.17 以降を使用します。Compute Engine Persistent Disk の CSI ドライバを使用するには、 - VolumeSnapshotで GKE バージョン 1.17.6-gke.4 以降を使用します。
- スナップショットに使用する既存の PersistentVolumeClaimが必要です。スナップショット ソースに使用するPersistentVolumeは、CSI ドライバによって管理される必要があります。CSI ドライバを使用しているかどうかを確認するには、PersistentVolume仕様のcsiセクションでdriver: pd.csi.storage.gke.ioまたはfilestore.csi.storage.gke.ioが指定されているかをチェックします。以降のセクションで説明するように、PersistentVolumeが CSI ドライバによって動的にプロビジョニングされていれば、CSI ドライバによって管理されています。
制限事項
Compute Engine でのディスク スナップショットの作成に関する制限はすべて GKE にも適用されます。
ベスト プラクティス
GKE で Persistent Disk Volume のスナップショットを使用する場合は、Compute Engine のディスク スナップショットのベスト プラクティスに従ってください。
始める前に
作業を始める前に、次のタスクが完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components updateコマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。
ボリューム スナップショットの作成と使用
このドキュメントの例では、次の作業を行う方法について説明します。
- PersistentVolumeClaimと- Deploymentを作成する。
- Deploymentが使用する- PersistentVolumeにファイルを追加する。
- VolumeSnapshotClassを作成してスナップショットを構成する。
- PersistentVolumeのボリューム スナップショットを作成する。
- テストファイルを削除する。
- 作成したスナップショットに PersistentVolumeを復元する。
- 復元が機能していることを確認する。
ボリューム スナップショットを使用するには、次の手順を行う必要があります。
- VolumeSnapshotClassオブジェクトを作成して、スナップショットの CSI ドライバと削除ポリシーを指定します。
- VolumeSnapshotオブジェクトを作成して、既存の- PersistentVolumeClaimのスナップショットをリクエストします。
- PersistentVolumeClaim内の- VolumeSnapshotを参照して、そのスナップショットにボリュームを復元するか、スナップショットを使用して新しいボリュームを作成します。
PersistentVolumeClaim と Deployment を作成する
- PersistentVolumeClaimオブジェクトを作成するには、次のマニフェストを- my-pvc.yamlとして保存します。- Persistent Disk- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: storageClassName: standard-rwo accessModes: - ReadWriteOnce resources: requests: storage: 1Gi- この例では、Compute Engine Persistent Disk の CSI ドライバとともにデフォルトでインストールされた - standard-rwoストレージ クラスを使用します。詳細については、Compute Engine Persistent Disk の CSI ドライバの使用に関する記事をご覧ください。- spec.storageClassNameには、サポートされている CSI ドライバを使用するストレージ クラスを指定できます。
- 次のようにマニフェストを適用します。 - kubectl apply -f my-pvc.yaml
- 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
- 次のようにマニフェストを適用します。 - kubectl apply -f my-deployment.yaml
- Deploymentのステータスを確認します。- kubectl get deployment hello-app- Deploymentの準備が完了するまでに時間がかかることがあります。次のような出力が表示されるまで、上記のコマンドを実行します。- NAME READY UP-TO-DATE AVAILABLE AGE hello-app 1/1 1 1 2m55s
ボリュームにテストファイルを追加する
- Deploymentの- Podsを一覧表示します。- kubectl get pods -l app=hello-app- 出力は次のようになります。 - NAME READY STATUS RESTARTS AGE hello-app-6d7b457c7d-vl4jr 1/1 Running 0 2m56s
- Podにテストファイルを作成します。- kubectl exec POD_NAME \ -- sh -c 'echo "Hello World!" > /usr/share/hello/hello.txt'- POD_NAMEは、- Podの名前に置き換えます。
- ファイルが存在することを確認します。 - kubectl exec POD_NAME \ -- sh -c 'cat /usr/share/hello/hello.txt'- 出力は次のようになります。 - Hello World!
VolumeSnapshotClass オブジェクトを作成する
VolumeSnapshotClass オブジェクトを作成して、ボリューム スナップショットの CSI ドライバと deletionPolicy を指定します。VolumeSnapshot オブジェクトの作成時に VolumeSnapshotClass オブジェクトを参照できます。
- 次のマニフェストを - volumesnapshotclass.yamlとして保存します。- Persistent Disk- バージョン 1.21 以降を実行しているクラスタには、 - v1API バージョンを使用します。- 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 Persistent Disk の 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
- ディスク イメージを作成するには、 - parametersフィールドに次の行を追加します。- parameters: snapshot-type: images image-family: IMAGE_FAMILY- IMAGE_FAMILYは、目的のイメージ ファミリーの名前(- preloaded-dataなど)に置き換えます。
 
- 次のようにマニフェストを適用します。 - kubectl apply -f volumesnapshotclass.yaml
VolumeSnapshot を作成する
VolumeSnapshot オブジェクトは、既存の PersistentVolumeClaim オブジェクトのスナップショットのリクエストです。VolumeSnapshot オブジェクトを作成すると、GKE はオブジェクトを自動的に作成し、VolumeSnapshotContent オブジェクト(PersistentVolume オブジェクトなどのクラスタ内のリソース)とバインドします。
- 次のマニフェストを - volumesnapshot.yamlとして保存します。- apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: my-snapshot spec: volumeSnapshotClassName: my-snapshotclass source: persistentVolumeClaimName: my-pvc
- 次のようにマニフェストを適用します。 - kubectl apply -f volumesnapshot.yaml- Volumeスナップショットを作成すると、GKE によって対応する- VolumeSnapshotContentオブジェクトがクラスタ内に作成されます。このオブジェクトには、- VolumeSnapshotオブジェクトのスナップショットとバインディングが格納されます。- VolumeSnapshotContentsオブジェクトを直接操作することはありません。
- 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
テストファイルを削除する
- 作成したテストファイルを削除します。 - kubectl exec POD_NAME \ -- sh -c 'rm /usr/share/hello/hello.txt'
- ファイルが存在していないことを確認します。 - kubectl exec POD_NAME \ -- sh -c 'cat /usr/share/hello/hello.txt'- 出力は次のようになります。 - cat: /usr/share/hello/hello.txt: No such file or directory
ボリューム スナップショットを復元する
PersistentVolumeClaim の VolumeSnapshot を参照して、既存のボリュームのデータで新しいボリュームをプロビジョニングできます。また、ボリュームをスナップショットでキャプチャした状態に復元することもできます。
PersistentVolumeClaim で VolumeSnapshot を参照するには、PersistentVolumeClaim に dataSource フィールドを追加します。VolumeSnapshotContents がディスク イメージとスナップショットのどちらを参照する場合も、同じプロセスが使用されます。
この例では、新しい PersistentVolumeClaim で作成した VolumeSnapshot を参照して、新しいクレームを使用するように Deployment を更新します。
- 次のようなディスクまたはイメージのスナップショットを使用していることを確認します。 - ディスクのスナップショット: スナップショットの作成の頻度が高く、復元の頻度は低い。
- イメージのスナップショット: スナップショットの作成の頻繁が低く、復元の頻度は高い。また、イメージのスナップショットは、ディスクのスナップショットよりも作成に時間がかかることがあります。
 - 詳細については、スナップショット頻度の上限をご覧ください。スナップショットのタイプを把握していると、問題のトラブルシューティングに役立ちます。 - VolumeSnapshotを調べます。- kubectl describe volumesnapshot SNAPSHOT_NAME- volumeSnapshotClassNameフィールドには、スナップショット クラスを指定します。- kubectl describe volumesnapshotclass SNAPSHOT_CLASS_NAME- snapshot-typeパラメータで- snapshotsまたは- imagesを指定します。指定しない場合のデフォルトは- snapshotsです。- スナップショット クラスが存在しない場合(たとえば、スナップショットが静的に作成された場合)、 - VolumeSnapshotContentsを調べます。- sh kubectl describe volumesnapshotcontents SNAPSHOT_CONTENTS_NAME出力のスナップショット ハンドルの形式を見れば、スナップショットのタイプがわかります。 *- projects/PROJECT_NAME/global/snapshots/SNAPSHOT_NAME: ディスクのスナップショット- projects/PROJECT_NAME/global/images/IMAGE_NAME: イメージのスナップショット
 
- 次のマニフェストを - pvc-restore.yamlとして保存します。- Persistent Disk- 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
- 次のようにマニフェストを適用します。 - kubectl apply -f pvc-restore.yaml
- 新しい - PersistentVolumeClaimを使用するように- my-deployment.yamlファイルを更新します。- ... volumes: - name: my-volume persistentVolumeClaim: claimName: pvc-restore
- 更新されたマニフェストを適用します。 - 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 は、GKE が作成した新しい Pod の名前に置き換えます。
出力は次のようになります。
   Hello World!
既存のスナップショットをインポートする
現在のクラスタの外部で作成された既存のボリューム スナップショットを使用して、VolumeSnapshotContents オブジェクトを手動でプロビジョニングできます。たとえば、別のクラスタに作成された別のGoogle Cloud リソースのスナップショットで GKE のボリュームを更新できます。
- スナップショットの名前を探します。 - Google Cloud コンソール- 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
- 次の - 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
- 次のようにマニフェストを適用します。 - kubectl apply -f restored-snapshot.yaml
- 次の - VolumeSnapshotContentマニフェストを- restored-snapshot-content.yamlとして保存します。- snapshotHandleフィールドは、プロジェクト ID とスナップショット名に置き換えます。双方向のバインディングを有効にするには、- volumeSnapshotRef.nameと- volumeSnapshotRef.namespaceの両方が、以前に作成した- VolumeSnapshotを参照している必要があります。- apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotContent metadata: name: restored-snapshot-content spec: deletionPolicy: Retain driver: pd.csi.storage.gke.io source: snapshotHandle: projects/PROJECT_ID/global/snapshots/SNAPSHOT_NAME volumeSnapshotRef: kind: VolumeSnapshot name: restored-snapshot namespace: default
- 次のようにマニフェストを適用します。 - kubectl apply -f restored-snapshot-content.yaml
- 次の - 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: standard-rwo accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
- 次のようにマニフェストを適用します。 - kubectl apply -f restored-pvc.yaml
- 次の - 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
- 次のようにマニフェストを適用します。 - kubectl apply -f restored-pod.yaml
- ファイルが復元されたことを確認します。 - kubectl exec restored-pod -- sh -c 'cat /demo/data/hello.txt'
クリーンアップ
このページで使用したリソースについて、 Google Cloud アカウントに課金されないようにするには、次の手順で操作します。
- VolumeSnapshotを削除します。- kubectl delete volumesnapshot my-snapshot
- VolumeSnapshotClassを削除します。- kubectl delete volumesnapshotclass my-snapshotclass
- Deploymentを削除します。- kubectl delete deployments hello-app
- PersistentVolumeClaimオブジェクトを削除します。- kubectl delete pvc my-pvc pvc-restore
次のステップ
- Kubernetes ボリューム スナップショットのドキュメントを読む。
- ボリュームの拡張について学習する。
- CSI ドライバを手動でインストールする方法を学習する。
- GKE のブロック ストレージ(Persistent Disk)について学習する。