Pod スナップショットを使用して Agent Sandbox 環境を保存して復元する

このドキュメントでは、 GKE Pod スナップショット を使用して、実行中の Agent Sandbox 環境の状態を保存する方法について説明します。

Agent Sandbox は、大規模言語モデル(LLM)によって生成されたコードなど、信頼性の低いコードを実行するための分離された環境を提供することで、セキュリティを強化します。このタイプのコードをクラスタで直接実行すると、信頼できないコードが他のアプリや基盤となるクラスタノード自体にアクセスしたり、干渉する可能性があるため、セキュリティ上のリスクが生じます。

GKE Pod スナップショットを使用すると、サンドボックス環境の状態を保存して復元できます。この機能は、次の理由で役立ちます。

  • 高速起動: 事前ウォーミングされた スナップショットから復元することで、サンドボックスの起動時間を短縮します。
  • 長時間実行エージェント: 実行に時間がかかるサンドボックスを一時停止して 後で再開したり、進行状況を失うことなく別のノードに移動したりできます。
  • ステートフル ワークロード: サンドボックス環境の状態を保存して復元することで、会話 履歴や中間計算など、エージェントのコンテキストを保持します。
  • 再現性: 特定の状態をキャプチャし、それをベースとして使用して、 同じ初期化状態で複数の新しいサンドボックスを開始します。

スナップショットは、次の 2 つの方法でトリガーできます。

  • 手動トリガー: PodSnapshotManualTrigger リソースを作成してスナップショットをトリガーします。
  • ワークロード トリガー: サンドボックス化されたアプリケーション自体が、保存の準備ができたときに通知します。

このドキュメントでは、スナップショットを手動でトリガーする方法について説明します。

始める前に

  1. コンソールの Google Cloud プロジェクト セレクタページで、 Google Cloud プロジェクトを選択または作成します。

    プロジェクトを選択または作成するために必要なロール

    • プロジェクトを選択する: プロジェクトの選択には特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトを選択できます。
    • プロジェクトを作成する: プロジェクトを作成するには、プロジェクト作成者ロール (roles/resourcemanager.projectCreator)が必要です。これには resourcemanager.projects.create 権限が含まれています。ロールを付与する方法を確認する

    プロジェクト セレクタに移動

  2. プロジェクトに対して課金が有効になっていることを確認します Google Cloud

  3. Google Kubernetes Engine、Cloud Storage、Identity and Access Management(IAM)API を有効にします。

    API を有効にするために必要なロール

    API を有効にするには、serviceusage.services.enable 権限が必要です。プロジェクトを作成した場合は、オーナーロール(roles/owner)を通じてこの権限が付与されている可能性があります。それ以外の場合は、Service Usage 管理者ロール(roles/serviceusage.serviceUsageAdmin)を通じてこの権限を取得できます。ロールを付与する方法を確認する

    API を有効にする

  4. コンソール Google Cloud で Cloud Shell をアクティブにします。

    Cloud Shell をアクティブにする

要件

GKE Pod スナップショットには、GKE バージョン 1.35.3-gke.1234000 以降が必要です。Autopilot モードと Standard モードの両方がサポートされています。

Pod スナップショットには GKE Sandboxが必要であるため、環境には特定の制限があります。たとえば、Pod スナップショットは E2 マシンタイプをサポートしていません。そのため、このチュートリアルでは、N2 マシンで構成されるノードプールを作成します。

GPU ベースのマシンタイプの使用に関する情報など、制限事項の完全なリストについては、 制限事項と要件をご覧ください。

環境変数を定義する

このドキュメントで実行するコマンドを簡略化するために、Cloud Shell で環境 変数を設定できます。これらの変数 には、プロジェクト Google Cloud の ID、スナップショットを保存する Cloud Storage バケットの名前、GKE クラスタの ロケーションなどの値が格納されます。

これらの変数を定義すると、値を再入力または置き換えるのではなく、変数名($CLUSTER_NAME など)を参照することで、複数のコマンドで再利用できます。この方法を使用すると、プロセスを簡単に追跡でき、エラーのリスクを軽減できます。

Cloud Shell で次の環境変数を定義するには、次のコマンドを実行します。

export PROJECT_ID=$(gcloud config get project)
export CLUSTER_NAME="agent-sandbox-cluster"
export GKE_LOCATION="us-central1"
export CLUSTER_VERSION="1.35.3-gke.1234000"
export AGENT_SANDBOX_VERSION="v0.4.6"
export NODE_POOL_NAME="agent-sandbox-node-pool"
export MACHINE_TYPE="n2-standard-2"
export SNAPSHOTS_BUCKET_NAME="agent-sandbox-snapshots-${PROJECT_ID}"
export SNAPSHOT_NAMESPACE="pod-snapshots-ns"
export SNAPSHOT_KSA_NAME="pod-snapshot-sa"
export SNAPSHOT_FOLDER="my-snapshots"
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")

これらの環境変数の説明は次のとおりです。

  • PROJECT_ID: 現在の Google Cloud プロジェクトの ID。この変数を定義すると、GKE クラスタなどのすべてのリソースが正しいプロジェクトに作成されます。
  • CLUSTER_NAME: GKE クラスタの名前(agent-sandbox-cluster など)。
  • GKE_LOCATION: GKE クラスタが作成される Google Cloud リージョン(us-central1 など)。
  • CLUSTER_VERSION: GKE クラスタのバージョン。バージョン 1.35.3-gke.1234000 以降にする必要があります。
  • AGENT_SANDBOX_VERSION: クラスタにデプロイする Agent Sandbox コントローラのバージョン。
  • NODE_POOL_NAME: サンドボックス化されたワークロードを実行するノードプールの名前(agent-sandbox-node-pool など)。
  • MACHINE_TYPE: ノードプール内のノードのマシンタイプ(n2-standard-2 など)。Pod スナップショットは、E2 マシンタイプをサポートしていません。ノードプール内のノードに GPU ベースのマシンタイプを使用する場合は、 制限事項と要件をご覧ください。 さまざまなマシンシリーズとさまざまな オプションの選択の詳細については、マシン ファミリーのリソースと比較 ガイドをご覧ください。
  • SNAPSHOTS_BUCKET_NAME: スナップショットを保存するために作成する Cloud Storage バケットの名前。
  • SNAPSHOT_NAMESPACE: スナップショット ワークロードとサービス アカウントが存在する Kubernetes Namespace。
  • SNAPSHOT_KSA_NAME: ワークロードが認証に使用する Kubernetes サービス アカウントの名前。
  • SNAPSHOT_FOLDER: スナップショットが整理される Cloud Storage バケット内のディレクトリ。
  • PROJECT_NUMBER: IAM 権限バインディングに使用される、プロジェクトの一意の数値識別子。

構成手順の概要

Agent Sandbox 環境の Pod スナップショットを有効にするには、いくつかの構成手順を行う必要があります。これらの手順を理解するには、まずいくつかの重要なコンセプトとスナップショット プロセスを理解すると役立ちます。

主なコンセプト

  • 環境: サンドボックス化されたアプリケーションは、GKE クラスタノードの Kubernetes Pod 内で実行されます。
  • ID: Pod は Kubernetes サービス アカウントに関連付けられ、作成した特別な Namespace で実行されます。Kubernetes サービス アカウントと Namespace は、Pod に リソースへの安全なアクセス Google Cloud を許可するために使用される一意の ID を形成します。
  • 権限: スナップショットを Cloud Storage に保存できるようにするには、 Pod の ID に Cloud Storage バケットへの書き込みを許可する特定の IAM 権限を付与する必要があります。

スナップショット プロセス

  1. トリガー: スナップショットは、手動(外部)またはサンドボックス化されたワークロード自体によって開始されます。このドキュメントでは、PodSnapshotManualTrigger リソースを作成して開始する手動トリガーについて説明します。
  2. キャプチャ: GKE は、Pod のメモリの状態やファイル システムなど、Pod の実行状態をキャプチャします。
  3. アップロード: GKE は、Pod の Kubernetes サービス アカウントに付与された権限を使用して、キャプチャされた状態をスナップショット ファイルとして指定された Cloud Storage バケットにアップロードします。

GKE が Kubernetes サービス アカウントと IAM ロールを使用して Google Cloud リソースにアクセスする方法の詳細については、 GKE ワークロードから API に対する認証を行う Google Cloud をご覧ください

Agent Sandbox 環境の Pod スナップショットを有効にするには、次の構成を行います。まず、Workload Identity Federation for GKE と Pod スナップショット機能を有効にして GKE クラスタを作成し、クラスタ環境を準備します。次に、スナップショットが安全に保存され、サンドボックスに必要な権限が付与されるように、Cloud Storage と IAM ポリシーを構成します。最後に、サンドボックスの保存場所とポリシーを指定するスナップショット リソースを作成します。

次の表に、実行する必要がある構成手順の概要を示します。各手順については、以降のセクションで説明します。

トピック タスク
クラスタの設定 1. GKE クラスタを作成し、Pod スナップショット機能と Workload Identity Federation for GKE 機能を有効にします。
2.Agent Sandbox をデプロイします。
ストレージと権限を構成する 1. Cloud Storage バケットとマネージド フォルダを作成します。
2.カスタム IAM ロールを作成します。
3.Kubernetes Namespace と Kubernetes サービス アカウント(KSA)を作成します。
4.IAM ロールを Kubernetes サービス アカウントにバインドします。
5.スナップショット コントローラに権限を付与します。
スナップショット リソースを構成する 1. PodSnapshotStorageConfigを作成する
2. PodSnapshotPolicyを作成する
3. 作成するSandboxTemplate

クラスタの設定

サンドボックス化されたアプリは GKE クラスタノードの Pod 内で実行されるため、クラスタ環境を設定する必要があります。このセクションでは、GKE クラスタを作成し、Agent Sandbox コントローラをデプロイする方法について説明します。

要件を満たす新しい GKE クラスタを作成する

Pod スナップショットを有効にして、新しい GKE クラスタを作成します。完全な機能互換性を確保するには、クラスタ バージョン 1.35.3-gke.1234000 以降を指定します。

Autopilot

必要な機能を備えた Autopilot クラスタを作成します。

gcloud container clusters create-auto ${CLUSTER_NAME} \
   --cluster-version=${CLUSTER_VERSION} \
   --enable-pod-snapshots \
   --location=${GKE_LOCATION}

Standard

必要な機能を備えた Standard クラスタを作成します。

gcloud container clusters create ${CLUSTER_NAME} \
   --cluster-version=${CLUSTER_VERSION} \
   --enable-pod-snapshots \
   --machine-type=${MACHINE_TYPE} \
   --workload-pool=${PROJECT_ID}.svc.id.goog \
   --workload-metadata=GKE_METADATA \
   --num-nodes=1 \
   --location=${GKE_LOCATION}

GKE Sandbox を有効にしてノードプールを作成します。 GKE Sandbox は、オープンソースの gVisor プロジェクトに基づくコンテナ セキュリティ機能で、実行中のアプリケーションとホスト オペレーティング システムの間に追加の分離レイヤを提供します。

gcloud container node-pools create ${NODE_POOL_NAME} \
   --cluster ${CLUSTER_NAME} \
   --num-nodes=1 \
   --location=${GKE_LOCATION} \
   --project=${PROJECT_ID} \
   --machine-type=${MACHINE_TYPE} \
   --sandbox type=gvisor

認証情報を取得する

kubectl CLI がクラスタに接続できるように、クラスタの認証情報を取得します。

gcloud container clusters get-credentials ${CLUSTER_NAME} \
    --location=${GKE_LOCATION}

Agent Sandbox コントローラをクラスタにデプロイする

公式リリース マニフェストをクラスタに適用することで、Agent Sandbox コントローラとその必須コンポーネントをデプロイできます。これらのマニフェストは、クラスタに Agent Sandbox コントローラをデプロイして実行するために必要なすべてのコンポーネントをダウンロードするように Kubernetes に指示する構成ファイルです。

GKE クラスタに Agent Sandbox をデプロイするには、次のコマンドを実行します。

# Apply the main manifest for the controller and its Custom Resource Definitions (CRDs)
kubectl apply \
-f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/manifest.yaml \
-f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/extensions.yaml

コントローラを確認する

マニフェストを適用したら、agent-sandbox-system Namespace で Agent Sandbox コントローラ Pod が正しく実行されていることを確認します。前の手順でマニフェストを適用すると、agent-sandbox-system Namespace が自動的に作成されます。

kubectl get pods -n agent-sandbox-system

Pod の STATUS 列に「Running」、READY 列に「1/1」が表示されるまで待ちます。Pod が正常に実行されている場合、出力は次のようになります。

NAME                         READY   STATUS    RESTARTS   AGE
agent-sandbox-controller-0      1/1     Running   0          44d

Agent Sandbox コントローラが実行されると、クラスタに作成した Sandbox リソースのサンドボックス環境を自動的に作成して管理できます。

ストレージと権限を構成する

このセクションでは、Pod スナップショットに必要なストレージと権限を構成する方法について説明します。Cloud Storage バケットとマネージド フォルダを作成して、スナップショット データを保存します。次に、サンドボックスとスナップショット コントローラに、そのストレージにアクセスするために必要な権限を付与します。

Cloud Storage バケットを作成する

スナップショットを保存するバケットを作成します。スナップショット プロセスを高速かつ費用対効果の高いものにするため、次の設定でバケットを作成することをおすすめします。

  • 階層型 Namespace を有効にする: 階層型 Namespace 機能では、バケットがフラット Namespace ではなくファイル システム階層に整理されます。この構成により、読み取りと書き込みのスループットが向上し、スナップショットの保存と復元が高速化されます。
  • 削除(復元可能)を無効にする: 削除(復元可能)機能は、削除されたファイルを一定期間保持することでデータを保護します。ただし、スナップショット プロセスでは、アップロード中に多くの一時ファイルが作成および削除されます。これらの一時ファイルを保存するための不要な料金が発生しないように、削除(復元可能)を無効にすることをおすすめします。

これらの設定でバケットを作成するには、次のコマンドを実行します。

gcloud storage buckets create "gs://${SNAPSHOTS_BUCKET_NAME}" \
    --uniform-bucket-level-access \
    --enable-hierarchical-namespace \
    --soft-delete-duration=0d \
    --location="${GKE_LOCATION}"

マネージド フォルダを作成する

マネージド フォルダを作成して、バケット内のスナップショットを整理します。マネージド フォルダを使用すると、バケット全体ではなく、特定のフォルダに IAM 権限を適用できます。このフォルダレベルのアクセスにより、サンドボックスは独自のスナップショットにのみアクセスでき、それらのスナップショットはバケット内の他のデータから分離されます。

マネージド フォルダを作成するには、次のコマンドを実行します。

gcloud storage managed-folders create "gs://${SNAPSHOTS_BUCKET_NAME}/${SNAPSHOT_FOLDER}/"

サービス アカウントと IAM ロールを構成する

GKE がスナップショットを安全に保存できるようにするには、サンドボックス化されたワークロードを実行する Pod で使用される Kubernetes サービス アカウントに、バケットへの書き込み権限が必要です。この権限を付与するには、 Google CloudPod で使用される Kubernetes サービス アカウントに IAM ロールをバインドします。 このセクションでは、カスタム IAM ロールを作成し、Kubernetes サービス アカウントを作成して、必要な権限を構成する方法について説明します。

  1. スナップショット データの書き込みに必要な権限を含む podSnapshotGcsReadWriter という名前のカスタム IAM ロールを作成します。

    gcloud iam roles create podSnapshotGcsReadWriter \
        --project="${PROJECT_ID}" \
        --permissions="storage.objects.get,storage.objects.create,storage.objects.delete,storage.folders.create"
    

    ロールが正常に作成されると、出力は次のようになります。

    Created role [podSnapshotGcsReadWriter].
    etag: BwZJUfjNbew=
    includedPermissions:
    - storage.folders.create
    - storage.objects.create
    - storage.objects.delete
    - storage.objects.get
    name: projects/${PROJECT_ID}/roles/podSnapshotGcsReadWriter
    stage: ALPHA
    title: podSnapshotGcsReadWriter
    
  2. サンドボックスとそのサービス アカウントが存在する Namespace を作成します。

    kubectl create namespace "${SNAPSHOT_NAMESPACE}"
    
  3. 作成した Namespace に Kubernetes サービス アカウントを作成します。Kubernetes サービス アカウントと Namespace は、サンドボックスに リソースへの安全なアクセスを許可するために使用される Google Cloud 一意の ID を形成します。

    kubectl create serviceaccount "${SNAPSHOT_KSA_NAME}" \
        --namespace "${SNAPSHOT_NAMESPACE}"
    
  4. Namespace 内のすべてのサービス アカウントに roles/storage.bucketViewer ロールを付与します。このロールを使用すると、アカウントはバケットのメタデータを表示できますが、データ自体を読み書きすることはできません。

    gcloud storage buckets add-iam-policy-binding "gs://${SNAPSHOTS_BUCKET_NAME}" \
        --member="principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/namespace/${SNAPSHOT_NAMESPACE}" \
        --role="roles/storage.bucketViewer"
    
  5. サンドボックスの Kubernetes サービス アカウントにカスタム podSnapshotGcsReadWriter ロールを付与します。このバインディングにより、この特定のアカウントのみがマネージド フォルダにデータを書き込むことができます。

    gcloud storage buckets add-iam-policy-binding "gs://${SNAPSHOTS_BUCKET_NAME}" \
        --member="principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${SNAPSHOT_NAMESPACE}/sa/${SNAPSHOT_KSA_NAME}" \
        --role="projects/${PROJECT_ID}/roles/podSnapshotGcsReadWriter"
    
  6. Kubernetes サービス アカウントに roles/storage.objectUser ロールを付与します。このロールは、Pod スナップショット エージェントがマネージド フォルダでオペレーションを実行するために必要です。

    gcloud storage buckets add-iam-policy-binding "gs://${SNAPSHOTS_BUCKET_NAME}" \
        --member="principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${SNAPSHOT_NAMESPACE}/sa/${SNAPSHOT_KSA_NAME}" \
        --role="roles/storage.objectUser"
    

スナップショット コントローラに権限を付与する

GKE システムのスナップショット コントローラに objectUser ロールを付与します。この権限により、コントローラは、PodSnapshot リソースを削除したときにスナップショット オブジェクトを削除するなど、スナップショットのライフサイクルを管理できます。

gcloud storage buckets add-iam-policy-binding "gs://${SNAPSHOTS_BUCKET_NAME}" \
    --member="serviceAccount:service-${PROJECT_NUMBER}@container-engine-robot.iam.gserviceaccount.com" \
    --role="roles/storage.objectUser"

スナップショット リソースを構成する

このセクションでは、Agent Sandbox ワークロードのスナップショット リソースを構成する方法について説明します。

スナップショット ストレージとルールを定義する

GKE がスナップショットを保存する場所と、スナップショット プロセスを管理するルールを指定するには、次の 2 つのカスタム リソースを作成します。

  • PodSnapshotStorageConfig: このリソースは、GKE がスナップショット ファイルを保存する Cloud Storage バケットとフォルダの場所を指定します。
  • PodSnapshotPolicy: このリソースは、Kubernetes ラベルに基づいて、スナップショットの対象となる Pod を定義します。また、スナップショットが手動か、サンドボックス ワークロードによって開始されるかなど、トリガー ルールも指定します。

両方のリソースを 1 つの手順で適用するには、Cloud Shell で次のコマンドを実行します。この方法を使用すると、環境変数が正しく挿入されます。

kubectl apply -f - <<EOF
apiVersion: podsnapshot.gke.io/v1
kind: PodSnapshotStorageConfig
metadata:
  name: cpu-pssc-gcs
spec:
  snapshotStorageConfig:
    gcs:
      bucket: "${SNAPSHOTS_BUCKET_NAME}"
      path: "${SNAPSHOT_FOLDER}"
EOF

sleep 5

kubectl apply -f - <<EOF
apiVersion: podsnapshot.gke.io/v1
kind: PodSnapshotPolicy
metadata:
  name: cpu-psp
  namespace: ${SNAPSHOT_NAMESPACE}
spec:
  storageConfigName: cpu-pssc-gcs
  selector:
    matchLabels:
      app: agent-sandbox-workload
  triggerConfig:
    type: manual
    postCheckpoint: resume
EOF

構成を確認する

スナップショット ストレージの構成とポリシーを適用したら、リソースを使用できることを確認します。このセクションでは、これらのカスタム リソースのステータスを確認する方法について説明します。

  1. PodSnapshotStorageConfig リソースのステータスを確認します。

    kubectl get podsnapshotstorageconfigs.podsnapshot.gke.io cpu-pssc-gcs \
      --namespace "${SNAPSHOT_NAMESPACE}" -o yaml
    

    出力には、type: Readystatus: "True" の条件が含まれている必要があります。

    status:
      conditions:
      - lastTransitionTime: "2025-10-31T18:18:02Z"
        message: Valid PodSnapshotStorageConfig
        reason: StorageConfigValid
        status: "True"
        type: Ready
    
  2. PodSnapshotPolicy リソースのステータスを確認します。

    kubectl get podsnapshotpolicies.podsnapshot.gke.io cpu-psp \
      --namespace "${SNAPSHOT_NAMESPACE}" -o yaml
    

    出力には、type: Readystatus: "True" の条件が含まれている必要があります。また、参照されている PodSnapshotStorageConfig が見つかったことも示されているはずです。

    status:
      conditions:
      - lastTransitionTime: "2025-10-31T18:19:47Z"
        message: The referenced PodSnapshotStorageConfig "cpu-pssc-gcs" was found
        reason: StorageConfigValid
        status: "True"
        type: Ready
    

サンドボックス テンプレートを作成する

ストレージ ポリシーと権限が設定されたら、SandboxTemplate リソースと SandboxClaim リソースを作成します。スナップショット プロセスが機能するには、このドキュメントで作成した Kubernetes サービス アカウントでサンドボックスを実行する必要があります。また、サンドボックスには、PodSnapshotPolicy で指定したラベルが必要です。

この例では、ログにインクリメント カウンタを出力する Python アプリを使用します。このカウンタを使用すると、状態が正常に保存され、後で復元されることを確認できます。

Autopilot

Pod スナップショットは、E2 マシンタイプをサポートしていません。Autopilot では、GKE は Pod スナップショットをサポートしていないマシンタイプをデフォルトで使用する場合があります。ワークロードが互換性のあるハードウェアで実行されるようにするには、 互換性のあるマシン ファミリーを優先するために カスタムの ComputeClass を使用する必要があります。

  1. 次のマニフェストを 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
    
  2. 次のようにマニフェストを適用します。

    kubectl apply -f non-e2-class.yaml
    
  3. SandboxTemplate リソースと SandboxClaim リソースを作成するには、次のマニフェストを適用します。SandboxTemplate は、cloud.google.com/compute-class: non-e2-class ノードセレクタを使用して作成した ComputeClass を参照します。

    kubectl apply -f - <<EOF
    ---
    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxTemplate
    metadata:
      name: python-runtime-template
      namespace: ${SNAPSHOT_NAMESPACE}
    spec:
      podTemplate:
        metadata:
          labels:
            app: agent-sandbox-workload
        spec:
          serviceAccountName: ${SNAPSHOT_KSA_NAME}
          runtimeClassName: gvisor
          nodeSelector:
            cloud.google.com/compute-class: non-e2-class
          containers:
          - name: my-container
            image: python:3.10-slim
            command: ["python3", "-c"]
            args:
              - |
                import time
                i = 0
                while True:
                  print(f"Count: {i}", flush=True)
                  i += 1
                  time.sleep(1)
    ---
    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxClaim
    metadata:
      name: python-sandbox-example
      namespace: ${SNAPSHOT_NAMESPACE}
      labels:
        app: agent-sandbox-workload
    spec:
      sandboxTemplateRef:
        name: python-runtime-template
    EOF
    

Standard

SandboxTemplate リソースと SandboxClaim リソースを作成するには、次のマニフェストを適用します。

kubectl apply -f - <<EOF
---
apiVersion: extensions.agents.x-k8s.io/v1alpha1
kind: SandboxTemplate
metadata:
  name: python-runtime-template
  namespace: ${SNAPSHOT_NAMESPACE}
spec:
  podTemplate:
    metadata:
      labels:
        app: agent-sandbox-workload
    spec:
      serviceAccountName: ${SNAPSHOT_KSA_NAME}
      runtimeClassName: gvisor
      containers:
      - name: my-container
        image: python:3.10-slim
        command: ["python3", "-c"]
        args:
          - |
            import time
            i = 0
            while True:
              print(f"Count: {i}", flush=True)
              i += 1
              time.sleep(1)
---
apiVersion: extensions.agents.x-k8s.io/v1alpha1
kind: SandboxClaim
metadata:
  name: python-sandbox-example
  namespace: ${SNAPSHOT_NAMESPACE}
  labels:
    app: agent-sandbox-workload
spec:
  sandboxTemplateRef:
    name: python-runtime-template
EOF

これで、サンドボックスが正しい ID で実行され、スナップショットを作成する準備ができました。

スナップショットの作成

このセクションでは、実行中のサンドボックスのスナップショットを手動でトリガーする方法について説明します。サンドボックス Pod をターゲットとするトリガー リソースを作成し、スナップショット プロセスが正常に完了したことを確認します。

  1. 初期カウンタログを確認する: スナップショットをトリガーする前に、実行中のサンドボックスのログを表示して、現在のカウンタ値を確認します。ログを表示すると、復元後に比較するベースラインが確立されます。

    kubectl logs python-sandbox-example --namespace "${SNAPSHOT_NAMESPACE}" --tail=5
    

    出力には、カウンタの最後の数行が表示されます。例:

    Count: 15
    Count: 16
    Count: 17
    

    出力された最後の数個の「Count」の値に注意してください。

  2. PodSnapshotManualTrigger リソースを作成する: スナップショットを開始します。

    kubectl apply -f - <<EOF
    apiVersion: podsnapshot.gke.io/v1
    kind: PodSnapshotManualTrigger
    metadata:
      name: cpu-snapshot-trigger
      namespace: ${SNAPSHOT_NAMESPACE}
    spec:
      targetPod: python-sandbox-example
    EOF
    
  3. 手動トリガーが成功したことを確認する:

    kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io \
      --namespace "${SNAPSHOT_NAMESPACE}"
    

    出力にはステータス Complete が表示され、GKE がターゲット Pod のスナップショットを正常にトリガーしたことを示します。

    NAME                   TARGET POD               STATUS     AGE
    cpu-snapshot-trigger   python-sandbox-example   Complete   XXs
    
  4. トリガーを記述してキャプチャされた状態の詳細を表示 します。

    kubectl describe podsnapshotmanualtriggers.podsnapshot.gke.io cpu-snapshot-trigger \
      --namespace "${SNAPSHOT_NAMESPACE}"
    

    出力には、バケットに保存されているスナップショット ファイルの一意の名前を含む Snapshot Created セクションが含まれています。

    Status:
      Conditions:
        Last Transition Time:  2026-01-30T19:11:04Z
        Message:               checkpoint completed successfully
        Reason:                Complete
        Status:                True
        Type:                  Triggered
      Observed Generation:     1
      Snapshot Created:
        Name:  <UNIQUE_SNAPSHOT_NAME>
    

スナップショットから復元する

スナップショットをキャプチャしたら、サンドボックス環境を復元して、保存された状態から実行を再開できます。サンドボックスを復元するには、元の SandboxTemplate を参照する新しい SandboxClaim を作成します。Pod スナップショット コントローラは、一致する最新のスナップショットを自動的に識別して復元します。

  1. 新しい SandboxClaim を作成してサンドボックスを復元します。

    kubectl apply -f - <<EOF
    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxClaim
    metadata:
      name: python-sandbox-from-snapshot
      namespace: ${SNAPSHOT_NAMESPACE}
      labels:
        app: agent-sandbox-workload
    spec:
      sandboxTemplateRef:
        name: python-runtime-template
    EOF
    
  2. ログを表示して、復元が行われたことを確認します。カウンタは、スナップショットが作成された時点から続行されます。

    kubectl logs python-sandbox-from-snapshot --namespace "${SNAPSHOT_NAMESPACE}"
    

    出力には、カウンタが再開されたことが示されます。例:

    Count: 18
    Count: 19
    Count: 20
    Count: 21
    

リソースのクリーンアップ

このドキュメントで使用したリソースについて、 Google Cloud アカウントに課金されないようにするには、次の手順で作成したリソースを削除します。

  1. サンドボックスの要求を削除して、実行中の Pod を停止し、Agent Sandbox コントローラがコンテナを正常に終了できるようにします。

    kubectl delete sandboxclaims --all --namespace "${SNAPSHOT_NAMESPACE}"
    
  2. サンドボックスの作成とスナップショットの開始に使用したサンドボックス テンプレートと手動トリガーを削除します。

    # Delete the blueprints
    kubectl delete sandboxtemplates --all --namespace "${SNAPSHOT_NAMESPACE}"
    
    # Delete the snapshot initiation objects
    kubectl delete podsnapshotmanualtriggers --all --namespace "${SNAPSHOT_NAMESPACE}"
    
  3. Namespace 内でスナップショットの対象となる Pod を定義するスナップショット ポリシーを削除します。

    kubectl delete podsnapshotpolicy cpu-psp --namespace "${SNAPSHOT_NAMESPACE}"
    
  4. スナップショット ストレージ構成を削除します。これは、スナップショット ストレージ バックエンドのグローバル定義です。このリソースはクラスタ スコープであるため、Namespace フラグは使用しないでください。

    kubectl delete podsnapshotstorageconfig cpu-pssc-gcs
    
  5. Autopilot 用に作成した場合は、ComputeClass を削除します。

    kubectl delete computeclass non-e2-class
    
  6. Kubernetes Namespace を削除して、Kubernetes サービス アカウントと残りの Namespace メタデータを自動的に削除します。

    kubectl delete namespace "${SNAPSHOT_NAMESPACE}"
    
  7. GKE クラスタを削除して、基盤となるインフラストラクチャとチュートリアルに関連付けられているすべてのノードを削除します。

    gcloud container clusters delete "${CLUSTER_NAME}" --location="${GKE_LOCATION}" --quiet
    
  8. ストレージを完全にリセットする場合は、再帰的な削除コマンドを使用して Cloud Storage バケットを削除します(省略可)。正しく構成されたバケットを今後のテストで再利用する場合は、この手順をスキップできます。

    gcloud storage rm --recursive "gs://${SNAPSHOTS_BUCKET_NAME:?Error: SNAPSHOTS_BUCKET_NAME is not set. Please re-define the environment variables you defined earlier.}"
    
  9. プロジェクトを完全にクリーンな状態に戻す場合は、カスタム IAM ロールを削除します(省略可)。IAM ロールはクラスタを削除した後も保持されるため、個別に削除する必要があります。

    gcloud iam roles delete podSnapshotGcsReadWriter --project="${PROJECT_ID}"
    

次のステップ

  • GKE Pod スナップショットの詳細を確認する
  • Agent Sandbox オープンソース プロジェクトの詳細については、 GitHubをご覧ください。
  • Agent Sandbox で AI コードの実行を 分離する方法を確認する