Google Kubernetes Engine(GKE)Pod スナップショットは、実行中の Pod のスナップショットを復元することで、ワークロードの起動レイテンシを改善します。Pod スナップショットは、メモリやルート ファイル システムの変更など、Pod の状態全体を保存します。新しいレプリカが作成されると、Pod は新しい状態から初期化されるのではなく、スナップショットから復元されます。Pod は、スナップショットが取得された時点から実行を再開します。
このドキュメントでは、ワークロードで GKE Pod スナップショットを有効にして構成する方法について説明します。
Pod スナップショットの仕組みの詳細については、Pod スナップショットについてをご覧ください。
始める前に
作業を始める前に、次のタスクが完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API を有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。gcloud CLI をインストール済みの場合は、
gcloud components updateコマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。
Pod スナップショットを有効にする
Pod スナップショットを有効にするには、Pod スナップショット機能を有効にしてクラスタを作成または更新します。Standard クラスタの場合は、GKE Sandbox で実行するノードプールを作成または更新する必要があります。Autopilot クラスタでは、GKE Sandbox がデフォルトでサポートされています。
クラスタで Pod スナップショットを有効にするには、使用する GKE のオペレーション モードに応じて、次のいずれかの手順を行います。
Autopilot
新しいクラスタで Pod スナップショットを有効にするには、次のコマンドを実行します。
gcloud container clusters create-auto CLUSTER_NAME \ --enable-pod-snapshots \ --location=CONTROL_PLANE_LOCATION \ --cluster-version=CLUSTER_VERSION次のように置き換えます。
CLUSTER_NAME: クラスタの名前。CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。CLUSTER_VERSION: 新しいクラスタのバージョン。1.35.3-gke.1234000 以降にする必要があります。
既存のクラスタで Pod スナップショットを有効にするには、次の操作を行います。
クラスタをバージョン 1.35.3-gke.1234000 以降にアップグレードします。
gcloud container clusters upgrade CLUSTER_NAME \ --cluster-version=CLUSTER_VERSION \ --location=CONTROL_PLANE_LOCATION次のように置き換えます。
CLUSTER_NAME: クラスタの名前。CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。CLUSTER_VERSION: 新しいクラスタのバージョン。1.35.3-gke.1234000 以降にする必要があります。
クラスタで Pod スナップショットを有効にします。
gcloud container clusters update CLUSTER_NAME \ --enable-pod-snapshots \ --location=CONTROL_PLANE_LOCATION
Pod スナップショットは、E2 マシンタイプをサポートしていません。Autopilot では、GKE はデフォルトで E2 ノードを使用する場合があります。ワークロードが互換性のあるハードウェアで実行されるようにするには、カスタム ComputeClass を使用して、互換性のあるマシン ファミリーを優先する必要があります。
カスタム ComputeClass を作成して使用する手順は次のとおりです。
次のマニフェストを
non-e2-class.yamlとして保存します。apiVersion: cloud.google.com/v1 kind: ComputeClass metadata: name: non-e2-class spec: priorities: - machineFamily: n2 - machineFamily: c3 activeMigration: optimizeRulePriority: false whenUnsatisfiable: DoNotScaleUp次のようにマニフェストを適用します。
kubectl apply -f non-e2-class.yamlPod 仕様で、
cloud.google.com/compute-classノードセレクタを使用して ComputeClass を参照します。spec: nodeSelector: cloud.google.com/compute-class: non-e2-class ...
Standard
新しいクラスタで Pod スナップショットを有効にするには、次のコマンドを実行します。
gcloud container clusters create CLUSTER_NAME \ --enable-pod-snapshots \ --cluster-version=CLUSTER_VERSION \ --workload-pool=PROJECT_ID.svc.id.goog \ --workload-metadata=GKE_METADATA \ --location=CONTROL_PLANE_LOCATION次のように置き換えます。
CLUSTER_NAME: クラスタの名前。CLUSTER_VERSION: 新しいクラスタのバージョン。1.35.3-gke.1234000 以降にする必要があります。PROJECT_ID: プロジェクト ID。CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。
既存のクラスタで Pod スナップショットを有効にするには、次の操作を行います。
クラスタをバージョン 1.35.3-gke.1234000 以降にアップグレードします。
gcloud container clusters upgrade CLUSTER_NAME \ --node-pool=NODEPOOL_NAME \ --cluster-version=CLUSTER_VERSION \ --location=CONTROL_PLANE_LOCATION次のように置き換えます。
CLUSTER_NAME: クラスタの名前。NODEPOOL_VERSION: ノードプールの名前。CLUSTER_VERSION: 新しいクラスタを更新するバージョン。1.35.3-gke.1234000 以降にする必要があります。CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。
クラスタで Pod スナップショットを有効にします。
gcloud beta container clusters update CLUSTER_NAME \ --enable-pod-snapshots \ --location=CONTROL_PLANE_LOCATION次のように置き換えます。
PROJECT_ID: プロジェクト ID。CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。
Standard クラスタの GKE Sandbox で Pod を実行するには、gVisor を有効にしてノードプールを作成または更新します。ノードプールを更新するには、--sandbox type=gvisor フラグを使用します。gVisor を有効にしてノードプールを作成するには、次のコマンドを実行します。
gcloud container node-pools create NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--node-version=NODE_VERSION \
--machine-type=MACHINE_TYPE \
--location=CONTROL_PLANE_LOCATION \
--image-type=cos_containerd \
--sandbox type=gvisor
次の変数を置き換えます。
NODE_POOL_NAME: 新しいノードプールの名前。NODE_VERSION: ノードプールに使用するバージョン。MACHINE_TYPE: ノードに使用するマシンのタイプ。CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。
gVisor の使用方法については、GKE Sandbox を使用してワークロードを分離するをご覧ください。
スナップショットを保存する
Pod スナップショットは Cloud Storage バケットに保存されます。このバケットには、メモリと(必要に応じて)GPU の状態が含まれます。Pod スナップショットには、Pod のサービス アカウントを有効にして使用し、Cloud Storage に対する認証を行うために Workload Identity Federation for GKE が必要です。
Pod スナップショットには、バケットに対する次の構成が必要です。
- 階層型名前空間: 読み取りと書き込みの秒間クエリ数を増やすには、有効にする必要があります。階層型名前空間では、均一なバケットレベルのアクセスも有効にする必要があります。
- 削除(復元可能): Pod スナップショットは並列複合アップロードを使用するため、削除(復元可能)などのデータ保護機能を無効にする必要があります。有効のままにしておくと、一時オブジェクトの削除によりストレージの請求額が大幅に増加する可能性があります。
- ロケーション: スナップショットが異なるリージョン間で転送されるとパフォーマンスに影響する可能性があるため、Cloud Storage バケットのロケーションは GKE クラスタと同じにする必要があります。
Cloud Storage バケットを作成する
バケットと必要な権限を作成する手順は次のとおりです。
Cloud Storage バケットを作成します。次のコマンドは、必要な構成でバケットを作成します。
gcloud storage buckets create "gs://BUCKET_NAME" \ --uniform-bucket-level-access \ --enable-hierarchical-namespace \ --soft-delete-duration=0d \ --location="LOCATION"次のように置き換えます。
BUCKET_NAME: バケットの名前。LOCATION: バケットのロケーション。
バケットの作成オプションの完全なリストについては、
buckets createオプションをご覧ください。
Cloud Storage バケットにアクセスする権限をワークロードに付与する
デフォルトでは、GKE には Cloud Storage にアクセスする権限がありません。スナップショット ファイルの読み取りと書き込みを行うには、ワークロード Pod で使用される Kubernetes ServiceAccount(KSA)に IAM 権限を付与する必要があります。個々の権限を付与する代わりに、有効期間の短いトークンを付与することもできます。
kubectlコマンドを使用してクラスタと通信できるように、認証情報を取得します。gcloud container clusters get-credentials "CLUSTER_NAME"Pod ごとに、次の操作を行います。
各 Pod の KSA を作成します。
kubectl create serviceaccount "KSA_NAME" \ --namespace "NAMESPACE"次のように置き換えます。
KSA_NAME: KSA の名前。NAMESPACE: Pod の名前空間。
バケットにアクセスする権限を KSA に付与します。
gcloud storage buckets add-iam-policy-binding "gs://BUCKET_NAME" \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME" \ --role="roles/storage.bucketViewer"gcloud storage buckets add-iam-policy-binding "gs://BUCKET_NAME" \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME" \ --role="roles/storage.objectUser"次のように置き換えます。
PROJECT_NUMBER: プロジェクトの番号。PROJECT_ID: プロジェクト ID。
有効期間の短いトークンを使用してマルチテナンシーを有効にする
個々の KSA に権限を付与する代わりに、有効期間が短く、スコープが制限されたトークンを使用してマルチテナンシーを有効にできます。このアプローチは、手動の IAM バインディングに関連する伝播遅延を回避するうえで役立ちます。各 KSA に権限を付与する代わりに、スナップショット ストレージ バケットに対する roles/storage.admin ロールを GKE ノード サービス アカウントに 1 回だけ付与します。ノード サービス アカウントは、特定のパスに対してオンデマンドで有効期間の短いトークンを作成します。
Pod スナップショットでトークンを有効にするには、GKE バージョン 1.35.3-gke.1234000 以降が必要です。
マルチテナンシーを有効にするには、次の操作を行います。
ノード サービス アカウントにバケットへのアクセス権を付与するには、次のコマンドを実行します。
gcloud storage buckets add-iam-policy-binding "gs://BUCKET_NAME" \ --member="serviceAccount:service-PROJECT_NUMBER@gcp-sa-gkenode.iam.gserviceaccount.com" \ --role="roles/storage.admin"スナップショットのストレージを構成する場合は、
tokenSourceフィールドの値をfederatedP4SAに設定します。
Cloud Storage バケットにアクセスする権限をコントローラに付与する
Pod スナップショット コントローラが Cloud Storage バケット内のスナップショットを削除できるようにするには、GKE サービス エージェントにストレージ オブジェクト ユーザー権限を付与する必要があります。
roles/storage.objectUserロールを付与します。gcloud projects add-iam-policy-binding "PROJECT_ID" \ --member="serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com" \ --role="roles/storage.objectUser" \ --condition="expression=resource.name.startsWith(\"projects/_/buckets/BUCKET_NAME\"),title=restrict_to_bucket,description=Restricts access to one bucket only"次のように置き換えます。
PROJECT_NUMBER: プロジェクトの番号。PROJECT_ID: プロジェクト ID。BUCKET_NAME: バケットの名前。
(省略可)Cloud Storage バケットのマネージド フォルダを作成する
フォルダを作成すると、スナップショットの権限を、相互に信頼できない Pod から分離できます。これは、マルチテナントのユースケースで役立ちます。マネージド フォルダを設定する手順は次のとおりです。
Pod スナップショットに必要な権限のみを含むカスタム IAM ロールを作成します。
gcloud iam roles create podSnapshotGcsReadWriter \ --project="PROJECT_ID" \ --permissions="storage.objects.get,storage.objects.create,storage.objects.delete,storage.folders.create"ターゲット名前空間内のすべての KSA に
roles/storage.bucketViewerロールを付与します。このロールを使用すると、KSA はバケット メタデータを読み取りますが、バケット内のオブジェクトに対する読み取り権限や書き込み権限は付与されません。gcloud storage buckets add-iam-policy-binding "gs://BUCKET_NAME" \ --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/namespace/NAMESPACE" \ --role="roles/storage.bucketViewer"次のように置き換えます。
PROJECT_NUMBER: プロジェクトの番号。PROJECT_ID: プロジェクト ID。
Pod スナップショットを保存する必要がある KSA ごとに、次の操作を行います。
KSA のマネージド フォルダを作成します。
gcloud storage managed-folders create "gs://BUCKET_NAME/FOLDER_PATH/"FOLDER_PATHは、マネージド フォルダのパス(my-app-snapshotsなど)に置き換えます。マネージド フォルダに対するカスタム
podSnapshotGcsReadWriterロールを KSA に付与します。gcloud storage managed-folders add-iam-policy-binding "gs://BUCKET_NAME/FOLDER_PATH/" \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME" \ --role="projects/PROJECT_ID/roles/podSnapshotGcsReadWriter"KSA_NAMEは、KSA の名前に置き換えます。
スナップショットのストレージを構成する
スナップショット ファイルの保存場所を指定するには、PodSnapshotStorageConfig リソースを作成します。
次の例では、Cloud Storage バケット BUCKET_NAME 内の
FOLDER_PATH/パスに Pod スナップショットを保存するように GKE を構成します。次のマニフェストをexample-pod-snapshot-storage-configとして保存します。apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotStorageConfig metadata: name: example-pod-snapshot-storage-config spec: snapshotStorageConfig: gcs: bucket: "BUCKET_NAME" path: "FOLDER_PATH" tokenSource: "TOKEN_SOURCE"次のように置き換えます。
BUCKET_NAME: Cloud Storage バケットの名前。FOLDER_PATH: Cloud Storage マネージド フォルダのパス。TOKEN_SOURCE: アクセス用の ID プロバイダ。マルチテナンシーにはpodKSA(デフォルト)またはfederatedP4SAを使用します。
次のようにマニフェストを適用します。
kubectl apply -f example-pod-snapshot-storage-config.yaml
スナップショット ポリシーを作成する
Pod のスナップショットを有効にするには、Pod のラベルに一致するセレクタを含む PodSnapshotPolicy リソースを作成します。
次の例では、
app: my-appラベルが付いた Pod に適用され、example-pod-snapshot-storage-configストレージ構成を使用するポリシーを作成します。次のマニフェストをexample-pod-snapshot-policy.yamlとして保存します。apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotPolicy metadata: name: example-pod-snapshot-policy namespace: NAMESPACE spec: storageConfigName: example-pod-snapshot-storage-config selector: matchLabels: app: my-app triggerConfig: type: TRIGGER_TYPE postCheckpoint: resumeTRIGGER_TYPEは、トリガーのタイプに置き換えます。指定できる値は、ワークロード ベースのトリガーの場合はworkload、オンデマンド スナップショットの場合はmanualです。構成可能なすべてのフィールドの完全なリストについては、PodSnapshotPolicy CustomResourceDefinition(CRD)ドキュメントをご覧ください。
次のようにマニフェストを適用します。
kubectl apply -f example-pod-snapshot-policy.yaml --namespace NAMESPACE
追加の Pod スナップショット ポリシーを構成する
PodSnapshotPolicy で、次のような追加のポリシーを構成できます。
自動クリーンアップ: 古い Pod スナップショット リソースを自動的にクリーンアップするには、
spec.retentionConfigフィールドを使用して保持ポリシーを構成します。lastAccessTimeoutフィールド(7dなど)を使用して期間を指定できます。この期間が経過すると、スナップショットは削除されます。スナップショットを整理する: スナップショットを論理的にグループ化して、類似した環境で異なるコンテキストで取得されたスナップショットを区別できます。たとえば、ベース Pod がすべてのユーザーで同じになる可能性があるマルチテナント シナリオでは、ユーザーまたはグループごとにスナップショットを分離できます。スナップショットを分離するには、
snapshotGroupingRulesフィールドを使用して、ポリシーでグループ化ラベルを指定します。
次の例は、PodSnapshotPolicy で保持設定とグループ化設定の両方を構成する方法を示しています。これらの設定は個別に設定できます。
# ... other fields omitted
spec:
retentionConfig:
lastAccessTimeout: 7d
snapshotGroupingRules:
groupByLabelValue:
labels: ["tenant", "environment"]
groupRetentionPolicy:
maxSnapshotCountPerGroup: 5
構成可能なすべてのフィールドの完全なリストについては、PodSnapshotPolicy CRD ドキュメントをご覧ください。
スナップショットのサイズを最適化する
Pod スナップショットがトリガーされると、gVisor は次のものを含むすべてのコンテナの状態全体をキャプチャします。
- アプリケーションの状態(メモリやレジスタなど)
- ルート ファイル システムと
tmpfs(emptyDirボリュームを含む)への変更 - カーネルの状態(開いているファイル記述子、スレッド、ソケットなど)
スナップショットのサイズは、こうした要因によって決まります。スナップショットが大きいほど、保存と復元に時間がかかります。パフォーマンスを最適化するには、スナップショットをトリガーする前に、Pod がスナップショットから復元された後に不要になるアプリケーションの状態やファイルをクリーンアップする必要があります。
スナップショット サイズの最適化は、大規模言語モデル(LLM)などのワークロードで特に重要です。LLM サーバーは、モデルの重みを GPU に読み込む前に、ローカル ストレージ(rootfs または tmpfs)にダウンロードすることがよくあります。スナップショットが生成されると、GPU の状態とモデルの重みファイルの両方が保存されます。このシナリオでは、モデルが 100 GB の場合、結果のスナップショットは約 200 GB(100 GB のモデルファイルと、GPU の状態を表す 100 GB)になります。モデルの重みが GPU に読み込まれた後、ファイル システム上のファイルが、アプリケーションの実行に必要ではなくなることがよくあります。スナップショットをトリガーする前にこれらのモデルファイルを削除すると、スナップショットのサイズを半分に減らし、レイテンシを大幅に削減してアプリケーションを復元できます。
スナップショットをトリガーする
アプリケーションの準備が整ったときにワークロード内からスナップショットをトリガーすることも、特定の Pod のオンデマンド スナップショットを手動でトリガーすることもできます。
ワークロードからスナップショットをトリガーする
アプリケーション コード内からスナップショットをトリガーするには、スナップショットの準備ができたときにシグナルを送信するようにアプリケーションを構成します。準備完了を通知するには、/proc/gvisor/checkpoint ファイルに 1 を書き込みます(例: echo 1 > /proc/gvisor/checkpoint.)。書き込みオペレーションは、スナップショット プロセスを非同期で開始し、すぐに戻ります。同じファイル記述子から読み取ると、スナップショットと復元が完了し、ワークロードの再開の準備が整うまで、読み取りプロセスがブロックされます。
実際の使用方法はアプリケーションによって異なりますが、次の例は Python アプリケーションのスナップショット トリガーを示しています。このワークロードの例からスナップショットをトリガーするには、次の操作を行います。
次のマニフェストを
my-app.yamlとして保存します。apiVersion: v1 kind: Pod metadata: name: my-app namespace: NAMESPACE labels: app: my-app spec: serviceAccountName: KSA_NAME runtimeClassName: gvisor containers: - name: my-container image: python:3.10-slim command: ["python3", "-c"] args: - | import time def trigger_snapshot(): try: with open("/proc/gvisor/checkpoint", "r+") as f: f.write("1") res = f.read().rstrip() print(f"GKE Pod Snapshot: {res}") except FileNotFoundError: print("GKE Pod Snapshot file does not exist -- Pod Snapshots is disabled") return except OSError as e: return e i = 0 while True: print(f"Count: {i}", flush=True) if (i == 20): #simulate the application being ready to snapshot at 20th count trigger_snapshot() i += 1 time.sleep(1) resources: limits: cpu: "500m" memory: "512Mi" requests: cpu: "250m" memory: "256Mi"アプリケーションをデプロイします。
kubectl apply -f my-app.yaml
スナップショットを手動でトリガーする
特定の Pod のオンデマンド スナップショットを手動でトリガーするには、PodSnapshotManualTrigger リソースを作成します。
次の例では、
my-podという名前の Pod のスナップショットをトリガーします。次のマニフェストをexample-manual-trigger.yamlとして保存します。apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotManualTrigger metadata: name: example-manual-trigger namespace: NAMESPACE spec: targetPod: my-pod次のようにマニフェストを適用します。
kubectl apply -f example-manual-trigger.yaml --namespace NAMESPACE
スナップショットが正常にトリガーされたかどうかを確認するには、PodSnapshotManualTrigger リソースの status フィールドを確認します。
kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io example-manual-trigger -n NAMESPACE -o yaml
status フィールドは、スナップショットのトリガーが成功したか失敗したかを示します。
スナップショットを確認する
スナップショットが作成されたことを確認するには、GKEPodSnapshotting イベントのアクティビティの履歴を確認します。
kubectl get events -o \
custom-columns=NAME:involvedObject.name,CREATIONTIME:.metadata.creationTimestamp,REASON:.reason,MESSAGE:.message \
--namespace NAMESPACE \
--field-selector involvedObject.name=POD_NAME,reason=GKEPodSnapshotting
POD_NAME は、Pod の名前に置き換えます(例: my-app、my-pod)。
出力は次のようになります。
NAME CREATIONTIME REASON MESSAGE
default/5b449f9c7c-bd7pc 2025-11-05T16:25:11Z GKEPodSnapshotting Successfully checkpointed the pod to PodSnapshot
スナップショットを管理する
Pod スナップショットを作成すると、その時点の Pod の状態を保存するために PodSnapshot CRD リソースが作成されます。このリソースの status フィールドは、スナップショット オペレーションが成功したかどうか、スナップショットが復元に使用できるかどうかを示します。
Namespace 内のすべての PodSnapshot リソースを表示するには、次のコマンドを実行します。
kubectl get podsnapshots.podsnapshot.gke.io --namespace NAMESPACE
出力は次のようになります。
NAME STATUS POLICY AGE
de334898-1e7a-4cdb-9f2e-7cc2181c29e4 AllSnapshotsAvailable example-policy 47h
スナップショットからワークロードを復元する
最新のスナップショットからワークロードを復元するには、スナップショットの取得後に既存の Pod を削除し、Pod を再デプロイします。また、同じ仕様で新しい Pod をデプロイすることもできます。GKE は、一致するスナップショットから Pod を自動的に復元します。
次の手順は、Pod を削除して再デプロイすることで、一致するスナップショットから Pod を復元する方法を示しています。
Pod を削除します。
kubectl delete -f POD_NAME.yamlPOD_NAMEは、Pod の名前に置き換えます(例:my-app)。Pod を再適用します。
kubectl apply -f POD_NAME.yamlログを表示して、スナップショットの復元を確認します。
kubectl logs my-app --namespace NAMESPACE出力は、アプリケーションの構成方法によって異なります。アプリケーション例では、復元オペレーションが発生すると、ログに
GKE Pod Snapshot: restoreが表示されます。
特定のスナップショットから復元する
デフォルトでは、GKE は Pod に一致する最新の PodSnapshot リソースからワークロードを復元します。スナップショットが作成されると、GKE は PodSnapshot リソースの一意の名前(UUID)を自動的に生成します。この名前は kubectl get podsnapshots.gke.io --namespace NAMESPACE を実行して確認できます。
古い PodSnapshot リソースまたは特定の PodSnapshot リソースからワークロードを復元するには、ワークロード Pod 仕様に podsnapshot.gke.io/ps-name アノテーションを追加し、ワークロードの復元に使用する PodSnapshot リソースの名前を指定します。
apiVersion: v1
kind: Pod
metadata:
name: my-app
namespace: NAMESPACE
labels:
app: my-app
annotations:
podsnapshot.gke.io/ps-name: "POD_SNAPSHOT_NAME"
spec:
serviceAccountName: KSA_NAME
runtimeClassName: gvisor
containers:
...
POD_SNAPSHOT_NAME は、復元するスナップショットの名前に置き換えます。スナップショット名を取得するには、kubectl get podsnapshots.gke.io --namespace NAMESPACE コマンドを実行します。
GKE が復元に指定されたスナップショットを使用するには、PodSnapshot リソースのステータス条件が Ready であり、Pod と同じ Namespace に存在する必要があります。PodSnapshot が Ready でない場合や、Pod と同じ Namespace に存在しない場合、ワークロードはスナップショットから復元するのではなく、コールド スタートを実行します。
スナップショットを無効にする
PodSnapshotPolicy CRD を削除すると、Pod のスナップショット作成と復元ができなくなります。実行中の Pod は、リソースの削除の影響を受けません。ただし、Pod の保存中または復元中にポリシーを削除すると、Pod が失敗状態になることがあります。
ポリシーで管理される新しい Pod のスナップショット作成と復元を無効にするには、次のコマンドを実行して PodSnapshotPolicy を削除します。
kubectl delete podsnapshotpolicies.podsnapshot.gke.io SNAPSHOT_POLICY --namespace=NAMESPACE
SNAPSHOT_POLICY は、削除する PodSnapshotPolicy の名前に置き換えます(例: example-pod-snapshot-policy)。
特定の PodSnapshot リソースを削除して、Pod が特定のスナップショットから復元されないようにすることもできます。PodSnapshot リソースを削除すると、Cloud Storage に保存されているファイルも削除されます。
特定のスナップショットが将来の復元に使用されないようにするには、次のコマンドを実行して PodSnapshot オブジェクトを削除します。
kubectl delete podsnapshots.podsnapshot.gke.io POD_SNAPSHOT_NAME --namespace=NAMESPACE
POD_SNAPSHOT_NAME は、削除するスナップショットの名前(example-podsnapshot など)に置き換えます。
トラブルシューティング
次のセクションでは、Pod スナップショットに関する一般的な問題のトラブルシューティングに役立つ情報について説明します。
PVC を使用したチェックポイント後の変更のリスク
Pod が Persistent Volume Claim(PVC)を使用している場合、「チェックポイントと再開」ワークフローで重大なリスクが発生します。(postCheckpoint: resume フィールドを使用して)チェックポイントの直後に再開するようにワークロードを構成すると、アプリケーションはアクティブな状態を維持し、チェックポイント後に PVC を変更できます。
- 正常なシャットダウンの問題: チェックポイントと再開のサイクルの後、Pod を削除すると、Kubernetes はコンテナのメインプロセスに
SIGTERMシグナルを送信して、正常なシャットダウン シーケンスを開始します。多くのアプリケーションは、正常なシャットダウン ロジックを実装しています。このロジックでは、クリーンアップ ルーチンがトリガーされ、PVC 上の一時ファイルが削除または更新されることがあります。 - 復元の失敗: Pod スナップショットの取得後に PVC でこれらの変更が発生した場合、復元手順ではチェックポイントの正確な瞬間に存在した PVC の状態が想定されるため、復元の失敗やデータ不整合が発生する可能性があります。
- 推奨される緩和策: ワークロードに PVC が必要な場合は、チェックポイント後にワークロードを再開しないでください。
PodSnapshotPolicyで構成postCheckpoint: stopを使用します。この構成により、チェックポイント フェーズの完了後に補助書き込みや状態変更を実行する機会がプロセスに与えられないようにします。
ConfigMap のマウントとディレクトリのマスキング
構成データをコンテナに統合する場合、マウント方法がスナップショットの整合性に影響する可能性があります。
標準のボリューム マウントを使用して ConfigMap がマウントされている場合、Kubernetes はターゲット ディレクトリ全体を外部マウントとして扱います。スナップショットの作成時に外部マウントはスキップされるため、ディレクトリ全体がスナップショットから除外されます。
次の例では、ディレクトリ全体が外部マウントであるため、/etc/my-app/ ディレクトリの変更はスナップショットにキャプチャされません。
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
config.json: |
{
"mode": "local"
}
---
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
runtimeClassName: gvisor
containers:
- name: my-app-container
image: my-app-image
volumeMounts:
- mountPath: /etc/my-app
name: config-volume
volumes:
- name: config-volume
configMap:
name: my-config
この問題を解決するには、subPath を使用します。subPath は、特定の構成ファイルのみが外部マウントとして扱われるようにするために役立ちます。この構成は正確なファイルをターゲットにしているため、親ディレクトリ内の残りのファイルと構造はコンテナのローカル ファイル システムの一部として残り、チェックポイント プロセス中に適切にキャプチャされます。
次の例は、subPath を使用した volumeMounts 構成を示しています。
volumeMounts:
- mountPath: /etc/my-app/config.json
name: config-volume
subPath: config.json
暗黙的な匿名ボリューム
特定のコンテナ イメージでは、メタデータ内でボリュームが定義されています(Dockerfile の VOLUME 手順を使用)。Pod 仕様でボリュームが定義されていない場合でも、Kubernetes はベースイメージでボリュームとして定義されているパスに対して匿名ボリュームを自動的に作成します。たとえば、alpine/git イメージは /git を暗黙的なボリュームとして定義します。
これらの匿名ボリュームは外部マウントとして扱われ、PVC と同様にチェックポイントは作成されません。ベースイメージを確認し、重要なデータがこのような暗黙的なボリュームに保存されていないことを確認することをおすすめします。
次のステップ
- Pod スナップショットのコンセプトの詳細を確認する。
- Pod スナップショットのカスタム リソース定義(CRD)を参照する。