Google Kubernetes Engine(GKE)ワークロードの起動レイテンシを短縮するには、実行中の Pod のスナップショットを取得し、そこから新しい Pod を復元します。このドキュメントでは、Pod スナップショット ポリシーを作成し、ワークロードから、または手動でスナップショットをトリガーする方法について説明します。Pod スナップショットの仕組みの詳細については、GKE Pod スナップショットについてをご覧ください。
プラットフォーム管理者、オペレーター、アプリケーション デベロッパーは、このドキュメントを使用してスナップショット ポリシーを構成し、スナップショットをトリガーできます。 Google Cloudのコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE ユーザーのロールとタスクをご覧ください。
始める前に
作業を始める前に、次のタスクが完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API を有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化します。gcloud CLI をインストール済みの場合は、
gcloud components updateコマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。
- 前提条件を満たし、クラスタで Pod スナップショットを有効にします。クラスタとストレージの準備の詳細については、Pod スナップショットの準備をご覧ください。
スナップショット ポリシーを作成する
Pod のスナップショットを有効にするには、Pod のラベルに一致するセレクタを含む PodSnapshotPolicy カスタム リソースを作成します。
次のマニフェストを
example-pod-snapshot-policy.yamlとして保存します。この例では、app: my-appラベルが付いた Pod に適用されるポリシーを作成します。このポリシーでは、Pod スナップショットの準備で作成したexample-pod-snapshot-storage-configPodSnapshotStorageConfig カスタム リソースを使用して、スナップショットの保存場所を定義します。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: resume次のように置き換えます。
NAMESPACE: Pod の名前空間。Pod スナップショットの準備で Cloud Storage へのアクセス権を付与した名前空間と同じ名前空間を使用します。TRIGGER_TYPE: トリガーのタイプ。サポートされている値は、ワークロードベースのトリガーの場合はworkload、オンデマンド スナップショットの場合はmanualです。
この例では、
postCheckpoint: resume設定により、GKE がスナップショットを取得した後も Pod が実行され続けます。構成可能なフィールドの完全なリストについては、PodSnapshotPolicy の仕様をご覧ください。
次のようにマニフェストを適用します。
kubectl apply -f example-pod-snapshot-policy.yaml
Pod スナップショット ポリシーの追加設定を構成する
PodSnapshotPolicy カスタム リソースは、必須のセレクタ、ストレージ構成、トリガーに加えて、オプションの設定もサポートしています。これらの追加設定では、各スナップショットがキャプチャする内容、GKE がスナップショットを保持する期間、GKE が復元用にスナップショットをグループ化する方法を制御します。
スナップショット スコープ: スナップショットでキャプチャする Pod 状態の部分を指定するには、
spec.snapshotScopeフィールドを構成します。サポートされている値はwhole-pod(デフォルト)とrootfs-onlyです。whole-podスコープは、アプリケーションの状態、メモリ、ファイル システムなど、Pod 全体をキャプチャします。rootfs-onlyスコープは、コンテナのルート ファイル システムのみをキャプチャします。rootfs-onlyスコープには、GKE バージョン 1.35.3-gke.1031000 以降が必要です。自動クリーンアップ: 古い PodSnapshot カスタム リソースを自動的にクリーンアップするには、
spec.retentionConfigフィールドを使用して保持ポリシーを構成します。lastAccessTimeoutフィールドを使用して期間を指定できます(例:7d)。この期間が経過すると、GKE はスナップショットを削除します。スナップショットのグループ化: 類似した環境で異なるコンテキストで取得されたスナップショットを分離するには、
spec.snapshotGroupingRulesフィールドにグループ化ラベルを指定します。たとえば、ベース Pod がすべてのユーザーで同じであるマルチテナント シナリオでは、ユーザーまたはグループごとにスナップショットを分離できます。復元中、GKE は同じラベルグループからのみスナップショットを選択します。このグループ化が復元中の互換性マッチングに与える影響については、グループ化ルールのマッチングをご覧ください。
スナップショットのスコープ、保持、グループ化の設定は個別に構成できます。次の例は、PodSnapshotPolicy カスタム リソースの 3 つの設定をすべて示しています。
# Multiple lines are omitted here
spec:
snapshotScope: rootfs-only
retentionConfig:
lastAccessTimeout: 7d
snapshotGroupingRules:
groupByLabelValue:
labels: ["tenant", "environment"]
groupRetentionPolicy:
maxSnapshotCountPerGroup: 5
構成可能なフィールドの完全なリストについては、PodSnapshotPolicy の仕様をご覧ください。
スナップショットのサイズを最適化する
スナップショットが大きいほど、保存と復元に時間がかかります。スナップショットをトリガーする前に、GKE がスナップショットから Pod を復元した後にアプリケーションで不要になる一時ファイルやアプリケーションの状態を削除して、サイズを縮小します。
デフォルトの whole-pod スナップショット スコープでは、GKE Sandbox は次のものを含むすべてのコンテナの状態全体をキャプチャします。
- アプリケーションの状態(メモリやレジスタなど)
- ルート ファイル システムと
tmpfsマウント(emptyDirボリュームを含む)への変更 - カーネルの状態(開いているファイル記述子、スレッド、ソケットなど)
スナップショット サイズの最適化は、大規模言語モデル(LLM)などのワークロードで特に重要です。LLM サーバーは、モデルの重みを GPU に読み込む前に、ローカル ストレージ(rootfs または tmpfs)にダウンロードすることがよくあります。スナップショットを生成すると、GKE Sandbox は GPU の状態とモデルの重みファイルの両方を保存します。このシナリオでは、モデルが 100 GB の場合、結果のスナップショットは約 200 GB(100 GB のモデルファイルと、GPU の状態を表す 100 GB)になります。アプリケーションがモデルの重みを GPU に読み込んだ後、ファイル システム上のファイルが、アプリケーションの実行に必要ではなくなることがよくあります。スナップショットをトリガーする前にこれらのモデルファイルを削除すると、スナップショットのサイズを半分に減らし、レイテンシを大幅に削減してアプリケーションを復元できます。
スナップショットをトリガーする
次のいずれかの方法でスナップショットをトリガーします。
ワークロード トリガー: 初期化の完了後など、スナップショットの準備ができたことを通知するようにアプリケーションを変更できる場合は、この方法を使用します。この方法は、水平方向にスケーリングするワークロードの起動レイテンシを改善するのに最適です。ワークロード トリガーは、ワークロード サイクルで 1 回だけ実行されます。
手動トリガー: アプリケーションを変更して readiness を通知できない場合や、特定の Pod のオンデマンド スナップショットが必要な場合は、この方法を使用します。手動トリガーは、必要に応じて何度でも作成できます。
ワークロードからスナップショットをトリガーする
アプリケーション コード内からスナップショットをトリガーするには、スナップショットの準備ができたときにシグナルを送信するようにアプリケーションを構成します。準備完了を通知するには、echo 1 > /proc/gvisor/checkpoint コマンドを実行するなどして、値 1 を /proc/gvisor/checkpoint ファイルに書き込みます。書き込みオペレーションは、スナップショット プロセスを非同期で開始し、すぐに戻ります。同じファイル記述子から読み取ると、スナップショットまたは復元オペレーションが完了し、ワークロードの再開の準備が整うまで、読み取りプロセスがブロックされます。
ワークロードからスナップショットをトリガーする前に、スナップショット ポリシーで Pod が選択されていることを確認します。そのポリシーの triggerConfig.type フィールドの値は workload に設定する必要があります。
実際の使用方法はアプリケーションによって異なりますが、次の例は Python アプリケーションのスナップショット トリガーを示しています。このワークロードの例からスナップショットをトリガーするには、次の操作を行います。
次のマニフェストを
my-app.yamlとして保存します。この例では、app: my-appラベルはサンプルのスナップショット ポリシーのセレクタと一致し、runtimeClassName: gvisor設定は GKE Sandbox で Pod を実行します。apiVersion: v1 kind: Pod metadata: name: my-app namespace: NAMESPACE labels: app: my-app spec: serviceAccountName: SERVICEACCOUNT_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 i = 0 while True: print(f"Count: {i}", flush=True) if (i == 20): # Simulate readiness at the 20th count trigger_snapshot() i += 1 time.sleep(1) resources: limits: cpu: "500m" memory: "512Mi" requests: cpu: "250m" memory: "256Mi"次のように置き換えます。
NAMESPACE: Pod の名前空間。SERVICEACCOUNT_NAME: Pod スナップショットの準備で Cloud Storage へのアクセス権を付与した ServiceAccount オブジェクトの名前。
アプリケーションをデプロイします。
kubectl apply -f my-app.yamlアプリケーションが起動し、準備完了のシグナルを送信すると、GKE Sandbox がスナップショットを取得します。スナップショットが成功したことを確認するには、スナップショットを確認するをご覧ください。
スナップショットを手動でトリガーする
スナップショットを手動でトリガーする前に、ターゲット Pod が実行されていること、スナップショット ポリシーが Pod を選択していることを確認します。そのポリシーの triggerConfig.type フィールドの値は manual に設定する必要があります。
特定の Pod のオンデマンド スナップショットを手動でトリガーするには、次の手順で PodSnapshotManualTrigger カスタム リソースを作成します。
次のマニフェストを
example-manual-trigger.yamlとして保存します。この例では、my-podという名前の Pod のスナップショットをトリガーします。apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotManualTrigger metadata: name: example-manual-trigger namespace: NAMESPACE spec: targetPod: my-podNAMESPACEは、Pod の Namespace に置き換えます。次のようにマニフェストを適用します。
kubectl apply -f example-manual-trigger.yamlスナップショットが正常にトリガーされたことを確認するには、PodSnapshotManualTrigger カスタム リソースの
statusセクションを確認します。kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io \ example-manual-trigger \ --namespace NAMESPACE -o yamlNAMESPACEは、Pod の Namespace に置き換えます。トリガーが成功すると、
status.conditionsフィールドにチェックポイントが完了したことが表示され、status.snapshotCreatedフィールドに作成された PodSnapshot カスタム リソースの名前が表示されます。
スナップショットを確認する
GKE がスナップショットを作成したことを確認するには、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
次のように置き換えます。
NAMESPACE: Pod の名前空間。POD_NAME: Pod の名前。
出力は次のようになります。
NAME CREATIONTIME REASON MESSAGE
default/5b449f9c7c-bd7pc 2025-11-05T16:25:11Z GKEPodSnapshotting Successfully checkpointed the pod to PodSnapshot
MESSAGE 列に Successfully checkpointed the pod to PodSnapshot が表示されます。これは、GKE が Pod の状態を PodSnapshot カスタム リソースに保存したことを確認するものです。PodSnapshot カスタム リソースを表示して管理するには、スナップショットを管理するをご覧ください。