Agent Sandbox in GKE-Umgebungen mit Pod-Snapshots speichern und wiederherstellen

In diesem Dokument erfahren Sie, wie Sie mit GKE-Pod-Snapshots den Status einer laufenden Agent Sandbox in einer GKE-Umgebung speichern.

Die Agent Sandbox in der GKE verbessert die Sicherheit, indem sie eine isolierte Umgebung für die Ausführung von nicht vertrauenswürdigem Code bereitstellt, z. B. Code, der von Large Language Models (LLMs) generiert wurde. Die Ausführung dieser Art von Code direkt in einem Cluster birgt Sicherheitsrisiken, da nicht vertrauenswürdiger Code möglicherweise auf andere Anwendungen oder den zugrunde liegenden Clusterknoten selbst zugreifen oder diese beeinträchtigen könnte.

Mit GKE-Pod-Snapshots können Sie den Status von Sandbox-Umgebungen speichern und wiederherstellen. Diese Funktion ist aus folgenden Gründen nützlich:

  • Schneller Start: Reduzieren Sie die Startzeit der Sandbox, indem Sie sie aus einem vorab initialisierten Snapshot wiederherstellen.
  • Lang andauernde Agenten: Sie können eine Sandbox, die lange ausgeführt wird, pausieren und später fortsetzen oder auf einen anderen Knoten verschieben, ohne den Fortschritt zu verlieren.
  • Zustandsorientierte Arbeitslasten: Der Kontext eines KI-Agenten, z. B. der Unterhaltungsverlauf oder Zwischenberechnungen, wird beibehalten, indem der Status der Sandbox-Umgebung gespeichert und wiederhergestellt wird.
  • Reproduzierbarkeit: Erfassen Sie einen bestimmten Zustand und verwenden Sie ihn als Grundlage, um mehrere neue Sandboxes mit demselben initialisierten Zustand zu starten.

Ein Snapshot kann auf zwei Arten ausgelöst werden:

  • Manueller Trigger: Sie erstellen eine PodSnapshotManualTrigger-Ressource, um den Snapshot auszulösen.
  • Arbeitslast-Trigger: Die Sandbox-Anwendung selbst signalisiert, wenn sie gespeichert werden kann.

In diesem Dokument wird beschrieben, wie Sie einen Snapshot manuell auslösen.

Hinweis

  1. Wählen Sie in der Google Cloud Console auf der Seite für die Projektauswahl ein Projekt von Google Cloud aus oder erstellen Sie eines.

    Erforderliche Rollen zum Auswählen oder Erstellen eines Projekts

    • Projekt auswählen: Für die Auswahl eines Projekts ist keine bestimmte IAM-Rolle erforderlich. Sie können jedes Projekt auswählen, für das Ihnen eine Rolle zugewiesen wurde.
    • Projekt erstellen: Zum Erstellen eines Projekts benötigen Sie die Rolle „Project Creator“ (roles/resourcemanager.projectCreator), die die Berechtigung resourcemanager.projects.create enthält. Informationen zum Zuweisen von Rollen

    Zur Projektauswahl

  2. Prüfen Sie, ob die Abrechnung für Ihr Google Cloud -Projekt aktiviert ist.

  3. Aktivieren Sie die Google Kubernetes Engine, Cloud Storage und Identity and Access Management (IAM) APIs, falls sie noch nicht aktiviert sind.

    Erforderliche Rollen zum Aktivieren von APIs

    Zum Aktivieren von APIs benötigen Sie die Berechtigung serviceusage.services.enable. Wenn Sie das Projekt erstellt haben, haben Sie diese Berechtigung wahrscheinlich bereits über die Inhaberrolle (roles/owner). Andernfalls können Sie diese Berechtigung über die Rolle „Service Usage-Administrator“ (roles/serviceusage.serviceUsageAdmin) erhalten. Informationen zum Zuweisen von Rollen

    APIs aktivieren

  4. Aktivieren Sie Cloud Shell in der Google Cloud Console.

    Cloud Shell aktivieren

Voraussetzungen

Für GKE-Pod-Snapshots ist die GKE-Version 1.35.3-gke.1234000 oder höher erforderlich. Sowohl der Autopilot- als auch der Standardmodus werden unterstützt.

Pod-Snapshots erfordern gVisor und funktionieren nicht mit MicroVM-Sandboxes.

Da für Pod-Snapshots GKE Sandbox erforderlich ist, gelten für Ihre Umgebung bestimmte Einschränkungen. Pod-Snapshots unterstützen beispielsweise keine E2-Maschinentypen. In dieser Anleitung wird daher ein Knotenpool mit N2-Maschinen erstellt.

Eine vollständige Liste der Einschränkungen, einschließlich Informationen zur Verwendung von GPU-basierten Maschinentypen, finden Sie unter Einschränkungen und Anforderungen.

Umgebungsvariablen definieren

Um die Befehle zu vereinfachen, die Sie in diesem Dokument ausführen, können Sie Umgebungsvariablen in Cloud Shell festlegen. In diesen Variablen werden Werte wie die ID Ihres Google Cloud -Projekts, der Name des Cloud Storage-Bucket, in dem Ihre Snapshots gespeichert werden, und der Standort Ihres GKE-Cluster gespeichert.

Nachdem Sie diese Variablen definiert haben, können Sie sie in mehreren Befehlen wiederverwenden, indem Sie auf den Variablennamen verweisen (z. B. $CLUSTER_NAME), anstatt die Werte jedes Mal neu einzugeben oder zu ersetzen. Dieser Ansatz erleichtert die Nachvollziehbarkeit des Prozesses und reduziert das Fehlerrisiko.

Führen Sie die folgenden Befehle aus, um die folgenden nützlichen Umgebungsvariablen in Cloud Shell zu definieren:

export PROJECT_ID=$(gcloud config get project)
export CLUSTER_NAME="agent-sandbox-cluster"
export GKE_LOCATION="us-central1"
export ZONE="us-central1-a"
export AGENT_SANDBOX_VERSION="v1.0.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)")

Hier ist eine Erklärung dieser Umgebungsvariablen:

  • PROJECT_ID: die ID Ihres aktuellen Projekts in Google Cloud . In den Befehlen in diesem Dokument wird diese ID verwendet, um Ressourcen zu benennen und IAM-Berechtigungen zu gewähren.
  • CLUSTER_NAME: der Name Ihres GKE-Cluster (z. B. agent-sandbox-cluster).
  • GKE_LOCATION: Die Google Cloud Region für Ihren Cloud Storage-Bucket (z. B. us-central1). Wenn Sie einen Autopilot-Cluster erstellen, verwendet der Cluster ebenfalls diese Region.
  • ZONE: die Zone für Ihren GKE-Cluster. Wenn Sie einen Standardcluster erstellen, legen Sie hier eine Zone in der Region GKE_LOCATION fest (z. B. us-central1-a). Um die Kosten zu senken, wird in diesem Dokument ein zonaler Standardcluster erstellt.
  • AGENT_SANDBOX_VERSION: Die Version des Open-Source-Agent Sandbox-Controllers, die installiert werden soll. In diesem Dokument wird die Version 1.0.6 verwendet.
  • NODE_POOL_NAME: der Name des Knotenpools, in dem die in einer Sandbox ausgeführten Arbeitslasten ausgeführt werden (z. B. agent-sandbox-node-pool).
  • MACHINE_TYPE: der Maschinentyp der Knoten im Knotenpool (z. B. n2-standard-2). Pod-Snapshots unterstützen keine E2-Maschinentypen. Wenn Sie GPU-basierte Maschinentypen für die Knoten in Ihrem Knotenpool verwenden möchten, lesen Sie die Informationen unter Einschränkungen und Anforderungen. Weitere Informationen zu den verschiedenen Maschinenreihen und zur Auswahl zwischen den verschiedenen Optionen finden Sie im Leitfaden zu Ressourcen und Vergleichen für Maschinenfamilien.
  • SNAPSHOTS_BUCKET_NAME: der Name des Cloud Storage-Bucket, den Sie zum Speichern von Snapshots erstellen.
  • SNAPSHOT_NAMESPACE: der Kubernetes-Namespace, in dem sich Ihre Snapshot-Arbeitslast und Ihr Dienstkonto befinden.
  • SNAPSHOT_KSA_NAME: der Name des Kubernetes-Dienstkontos, das Ihre Arbeitslast zur Authentifizierung verwendet.
  • SNAPSHOT_FOLDER: das Verzeichnis in Ihrem Cloud Storage-Bucket, in dem Snapshots organisiert werden.
  • PROJECT_NUMBER: die eindeutige numerische Kennung für Ihr Projekt, die für IAM-Berechtigungsbindungen verwendet wird.

Übersicht über die Konfigurationsschritte

Wenn Sie Pod-Snapshots der Agent Sandbox in GKE-Umgebungen aktivieren möchten, müssen Sie einige Konfigurationsschritte ausführen. Um diese Schritte zu verstehen, ist es hilfreich, zuerst einige wichtige Konzepte und dann den Snapshot-Prozess zu verstehen:

Wichtige Konzepte

  • Umgebung: Eine Sandbox-Anwendung wird in einem Kubernetes-Pod auf einem GKE-Clusterknoten ausgeführt.
  • Identität: Der Pod ist mit einem Kubernetes-Dienstkonto verknüpft und wird in einem speziellen Namespace ausgeführt, den Sie erstellen. Das Kubernetes-Dienstkonto und der Namespace bilden zusammen eine eindeutige Identität, mit der dem Pod sicherer Zugriff auf Google Cloud -Ressourcen gewährt wird.
  • Berechtigungen: Damit Snapshots in Cloud Storage gespeichert werden können, müssen der Identität des Pods bestimmte IAM-Berechtigungen gewährt werden, die es ihr ermöglichen, in einen Cloud Storage-Bucket zu schreiben.

Snapshot-Prozess

  1. Trigger: Ein Snapshot wird entweder manuell (extern) oder von der Sandbox-Arbeitslast selbst initiiert. In diesem Dokument wird ein manueller Trigger veranschaulicht, den Sie durch Erstellen einer PodSnapshotManualTrigger-Ressource initiieren.
  2. Erfassen: GKE erfasst den Ausführungsstatus des Pods, z. B. den Status des Arbeitsspeichers und des Dateisystems des Pods.
  3. Hochladen: GKE lädt den erfassten Status mithilfe der Berechtigungen, die dem Kubernetes-Dienstkonto des Pods gewährt wurden, als Snapshot-Dateien in den angegebenen Cloud Storage-Bucket hoch.

Weitere Informationen dazu, wie GKE Kubernetes-Dienstkonten und IAM-Rollen für den Zugriff auf Google Cloud -Ressourcen verwendet, finden Sie unter Über GKE-Arbeitslasten beiGoogle Cloud APIs authentifizieren.

Führen Sie die folgende Konfiguration aus, um Pod-Snapshots der Agent Sandbox in GKE-Umgebungen zu aktivieren. Zuerst bereiten Sie eine Clusterumgebung vor, indem Sie einen GKE-Cluster mit aktivierter Workload Identity-Föderation für GKE und aktivierten Pod-Snapshot-Features erstellen. Als Nächstes konfigurieren Sie Cloud Storage- und IAM-Richtlinien, damit Ihre Snapshots sicher gespeichert werden und Ihre Sandbox die erforderlichen Berechtigungen hat. Schließlich erstellen Sie die Snapshot-Ressourcen, die den Speicherort und die Richtlinien für Ihre Sandbox angeben.

In der folgenden Tabelle sind die Konfigurationsschritte zusammengefasst, die Sie ausführen müssen. Jeder Schritt wird in den folgenden Abschnitten erläutert:

Thema Aufgabe
Cluster einrichten 1. Erstellen Sie einen GKE-Cluster und aktivieren Sie die Funktionen „Pod-Snapshots“ und „Workload Identity Federation for GKE“.
2. Agent Sandbox bereitstellen
Speicher und Berechtigungen konfigurieren 1. Erstellen Sie den Cloud Storage-Bucket und den verwalteten Ordner.
2. Erstellen Sie die benutzerdefinierte IAM-Rolle.
3. Erstellen Sie den Kubernetes-Namespace und das Kubernetes-Dienstkonto (KSA).
4. Binden Sie die IAM-Rolle an das Kubernetes-Dienstkonto.
5. Dem Snapshot-Controller Berechtigungen gewähren.
Snapshot-Ressourcen konfigurieren 1. PodSnapshotStorageConfig-Ressource erstellen
2. PodSnapshotPolicy-Ressource erstellen
3. SandboxTemplate-, SandboxWarmPool- und SandboxClaim-Ressourcen erstellen

Clustereinrichtung

Eine Sandbox-Anwendung wird in einem Pod auf einem GKE-Clusterknoten ausgeführt. Sie müssen also eine Clusterumgebung einrichten. In diesem Abschnitt erfahren Sie, wie Sie einen GKE-Cluster erstellen und den Agent Sandbox-Controller bereitstellen.

Neuen GKE-Cluster erstellen, der die Anforderungen erfüllt

Erstellen Sie einen neuen GKE-Cluster mit aktivierten Pod-Snapshots. Für Pod-Snapshots ist die GKE-Version 1.35.3-gke.1234000 oder höher erforderlich. Mit den folgenden Befehlen wird der Cluster in der Release-Version „Schnell“ registriert, deren Standardversion diese Anforderung erfüllt:

Autopilot

Erstellen Sie einen Autopilot-Cluster mit den erforderlichen Features:

gcloud container clusters create-auto ${CLUSTER_NAME} \
   --release-channel=rapid \
   --enable-pod-snapshots \
   --location=${GKE_LOCATION}

Standard

Erstellen Sie einen Standardcluster mit den erforderlichen Features. Mit dem folgenden Befehl wird ein zonaler Cluster erstellt, dessen Steuerungsebene und Knoten in einer Zone ausgeführt werden. So lassen sich Kosten sparen:

gcloud container clusters create ${CLUSTER_NAME} \
   --release-channel=rapid \
   --enable-pod-snapshots \
   --machine-type=${MACHINE_TYPE} \
   --workload-pool=${PROJECT_ID}.svc.id.goog \
   --workload-metadata=GKE_METADATA \
   --num-nodes=1 \
   --location=${ZONE}

Erstellen Sie einen Knotenpool mit aktivierter GKE Sandbox. GKE Sandbox ist eine Containersicherheitsfunktion, die auf dem Open-Source-Projekt gVisor basiert. Sie bietet eine zusätzliche Isolierungsebene zwischen laufenden Anwendungen und dem Hostbetriebssystem:

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

Anmeldedaten abrufen

Rufen Sie die Anmeldedaten des Clusters ab, damit die kubectl-Befehlszeile eine Verbindung zum Cluster herstellen kann:

Autopilot

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

Standard

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

Agent Sandbox Controller in Ihrem Cluster bereitstellen

Sie können den Agent Sandbox-Controller und die erforderlichen Komponenten bereitstellen, indem Sie das offizielle Release-Manifest auf Ihren Cluster anwenden. Dieses Manifest ist eine Konfigurationsdatei, die Kubernetes anweist, alle erforderlichen Komponenten herunterzuladen, die zum Bereitstellen und Ausführen des Agent Sandbox-Controllers in Ihrem Cluster erforderlich sind.

Führen Sie den folgenden Befehl aus, um die Agent Sandbox in Ihrem GKE-Cluster bereitzustellen:

# Apply the release manifest for the controller and its CustomResourceDefinitions
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/sandbox-with-extensions.yaml

Weitere Informationen zur Installation der Agent Sandbox finden Sie unter Agent Sandbox in GKE installieren.

Controller prüfen

Prüfen Sie nach dem Anwenden des Manifests, ob der Agent Sandbox-Controller-Pod im Namespace agent-sandbox-system ordnungsgemäß ausgeführt wird. Das Manifest hat den Namespace agent-sandbox-system automatisch erstellt, als Sie es im vorherigen Schritt angewendet haben.

kubectl get pods -n agent-sandbox-system

Warten Sie, bis für den Pod in der Spalte STATUS „Running“ und in der Spalte READY „1/1“ angezeigt wird. Wenn der Pod ordnungsgemäß ausgeführt wird, sieht die Ausgabe in etwa so aus:

NAME                                        READY   STATUS    RESTARTS   AGE
agent-sandbox-controller-7d5c9b8f6d-x2k9p   1/1     Running   0          2m

Da der Agent Sandbox-Controller jetzt ausgeführt wird, kann er automatisch Sandbox-Umgebungen für alle Sandbox-Ressourcen erstellen und verwalten, die Sie in Ihrem Cluster erstellen.

Speicher und Berechtigungen konfigurieren

In diesem Abschnitt erfahren Sie, wie Sie den Speicher und die Berechtigungen konfigurieren, die für Pod-Snapshots erforderlich sind. Sie erstellen einen Cloud Storage-Bucket und einen verwalteten Ordner, um die Snapshot-Daten zu speichern. Anschließend gewähren Sie Ihrer Sandbox und dem Snapshot-Controller die Berechtigungen, die sie für den Zugriff auf diesen Speicher benötigen.

Cloud Storage-Bucket erstellen

Erstellen Sie einen Bucket zum Speichern Ihrer Snapshots. Damit der Snapshot-Prozess schnell und kostengünstig ist, erstellen Sie den Bucket mit den folgenden Einstellungen:

  • Hierarchische Namespaces aktivieren: Mit dem Feature „Hierarchische Namespaces“ wird Ihr Bucket in einer Dateisystemhierarchie und nicht in einem flachen Namespace organisiert. Diese Konfiguration ermöglicht einen höheren Lese- und Schreibdurchsatz und beschleunigt somit das Speichern und Wiederherstellen von Snapshots.
  • Vorläufiges Löschen deaktivieren: Mit der Funktion für vorläufiges Löschen werden Daten geschützt, indem gelöschte Dateien für einen bestimmten Zeitraum aufbewahrt werden. Beim Snapshot-Prozess werden jedoch während des Uploads viele temporäre Dateien erstellt und gelöscht. Deaktivieren Sie das vorläufige Löschen, um unnötige Kosten für das Speichern dieser temporären Dateien zu vermeiden.

Führen Sie den folgenden Befehl aus, um den Bucket mit diesen Einstellungen zu erstellen:

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

Verwalteten Ordner erstellen

Erstellen Sie einen verwalteten Ordner, um Snapshots in Ihrem Bucket zu organisieren. Mit verwalteten Ordnern können Sie IAM-Berechtigungen auf einen bestimmten Ordner und nicht auf den gesamten Bucket anwenden. Durch diesen Zugriff auf Ordnerebene wird der Zugriff Ihrer Sandbox auf ihre eigenen Snapshots beschränkt und diese Snapshots werden von anderen Daten im Bucket isoliert.

Führen Sie den folgenden Befehl aus, um einen verwalteten Ordner zu erstellen:

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

Dienstkonto und IAM-Rollen konfigurieren

Damit GKE Snapshots sicher speichern kann, benötigt das Kubernetes-Dienstkonto, das von den Pods verwendet wird, die Ihre Sandbox-Arbeitslast ausführen, die Berechtigung zum Schreiben in Ihren Bucket. Sie erteilen diese Berechtigung, indem Sie IAM-Rollen von Google Cloudan das Kubernetes-Dienstkonto binden, das von den Pods verwendet wird. In diesem Abschnitt erfahren Sie, wie Sie eine benutzerdefinierte IAM-Rolle erstellen, das Kubernetes-Dienstkonto erstellen und die erforderlichen Berechtigungen konfigurieren.

  1. Erstellen Sie eine benutzerdefinierte IAM-Rolle mit dem Namen podSnapshotGcsReadWriter, die die erforderlichen Berechtigungen zum Schreiben von Snapshot-Daten enthält. Wenn diese Rolle bereits in Ihrem Projekt vorhanden ist, z. B. aus einer früheren Ausführung dieses Dokuments, überspringen Sie diesen Schritt. Andernfalls führen Sie den folgenden Befehl aus:

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

    Wenn die Rolle erstellt wurde, sieht die Ausgabe so aus:

    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
    

    Wenn der Befehl mit dem Fehler FAILED_PRECONDITION fehlschlägt, der besagt, dass die Rollen-ID zum Löschen markiert wurde, haben Sie vor Kurzem eine Rolle mit dieser ID gelöscht, z. B. in den Bereinigungsschritten einer früheren Ausführung dieses Dokuments. In IAM können Sie diese ID bis zu 37 Tage lang nicht wiederverwenden. Führen Sie den Befehl noch einmal mit einer anderen Rollen-ID aus, z. B. podSnapshotGcsReadWriter2, und verwenden Sie diese ID im weiteren Verlauf dieses Dokuments anstelle von podSnapshotGcsReadWriter.

  2. Erstellen Sie den Namespace, in dem sich Ihre Sandbox und das zugehörige Dienstkonto befinden:

    kubectl create namespace "${SNAPSHOT_NAMESPACE}"
    
  3. Erstellen Sie das Kubernetes-Dienstkonto in dem Namespace, den Sie gerade erstellt haben. Das Kubernetes-Dienstkonto und der Namespace bilden zusammen eine eindeutige Identität, mit der Ihrer Sandbox sicherer Zugriff auf Google Cloud-Ressourcen gewährt wird:

    kubectl create serviceaccount "${SNAPSHOT_KSA_NAME}" \
        --namespace "${SNAPSHOT_NAMESPACE}"
    
  4. Weisen Sie allen Dienstkonten im Namespace die Rolle roles/storage.bucketViewer zu. Mit dieser Rolle können die Konten die Metadaten des Buckets aufrufen, aber nicht die Daten selbst lesen oder schreiben:

    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. Weisen Sie dem Kubernetes-Dienstkonto für Ihre Sandbox die benutzerdefinierte Rolle podSnapshotGcsReadWriter zu. Diese Bindung ermöglicht nur diesem bestimmten Konto, Daten in den verwalteten Ordner zu schreiben. Es kann einige Minuten dauern, bis eine neue benutzerdefinierte Rolle verfügbar ist. Wenn dieser Befehl fehlschlägt, weil die Rolle nicht vorhanden ist, warten Sie eine Minute und führen Sie den Befehl dann noch einmal aus:

    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. Weisen Sie dem Kubernetes-Dienstkonto die Rolle roles/storage.objectUser zu. Diese Rolle ist erforderlich, damit der Pod-Snapshot-Agent Vorgänge für verwaltete Ordner ausführen kann:

    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"
    

Berechtigungen für den Snapshot-Controller erteilen

Weisen Sie dem Snapshot-Controller des GKE-Systems die Rolle objectUser zu. Mit dieser Berechtigung kann der Controller den Snapshot-Lebenszyklus verwalten, z. B. Snapshot-Objekte löschen, wenn Sie eine PodSnapshot-Ressource löschen:

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"

Snapshot-Ressourcen konfigurieren

In diesem Abschnitt erfahren Sie, wie Sie die Snapshot-Ressourcen für Ihre Agent Sandbox in GKE-Arbeitslast konfigurieren.

Snapshot-Speicher und -Regeln definieren

Wenn Sie festlegen möchten, wo GKE Ihre Snapshots speichert und welche Regeln für den Snapshot-Prozess gelten, erstellen Sie zwei benutzerdefinierte Ressourcen:

  • PodSnapshotStorageConfig: Diese Ressource gibt den Cloud Storage-Bucket und den Ordnerspeicherort an, an dem GKE Ihre Snapshot-Dateien speichert.
  • PodSnapshotPolicy: Diese Ressource definiert, welche Pods basierend auf ihren Kubernetes-Labels für Snapshots infrage kommen. Außerdem werden die Triggerregeln angegeben, z. B. ob Snapshots manuell oder durch die Sandbox-Arbeitslast initiiert werden. In diesem Beispiel werden Snapshots nach dem Label agents.x-k8s.io/sandbox-name-hash gruppiert, das der Agent Sandbox-Controller dem Pod jeder Sandbox hinzufügt. Diese Gruppierung bedeutet, dass GKE jede Sandbox nur aus ihren eigenen Snapshots wiederherstellt.

Führen Sie den folgenden Befehl in Cloud Shell aus, um beide Ressourcen in einem Schritt anzuwenden. So können Sie dafür sorgen, dass Ihre Umgebungsvariablen korrekt eingefügt werden:

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
  snapshotGroupingRules:
    groupByLabelValue:
      labels:
      - agents.x-k8s.io/sandbox-name-hash
EOF

Konfiguration prüfen

Nachdem Sie die Snapshot-Speicherkonfiguration und -Richtlinie angewendet haben, prüfen Sie, ob die Ressourcen einsatzbereit sind. In diesem Abschnitt erfahren Sie, wie Sie den Status dieser benutzerdefinierten Ressourcen prüfen.

  1. Prüfen Sie den Status der PodSnapshotStorageConfig-Ressource:

    kubectl get podsnapshotstorageconfigs.podsnapshot.gke.io cpu-pssc-gcs -o yaml
    

    Die Ausgabe sollte eine Bedingung mit type: Ready und status: "True" enthalten:

    status:
      conditions:
      - lastTransitionTime: "2025-10-31T18:18:02Z"
        message: Valid PodSnapshotStorageConfig
        reason: StorageConfigValid
        status: "True"
        type: Ready
    
  2. Prüfen Sie den Status der PodSnapshotPolicy-Ressource:

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

    Die Ausgabe sollte eine Bedingung mit type: Ready und status: "True" enthalten. Außerdem sollte angegeben werden, dass die referenzierte PodSnapshotStorageConfig-Ressource gefunden wurde:

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

Sandbox-Vorlage erstellen

Nachdem die Speicherrichtlinien und Berechtigungen eingerichtet sind, erstellen Sie die Ressourcen SandboxTemplate, SandboxWarmPool und SandboxClaim. Die Ressource SandboxWarmPool hält eine vorab aufgewärmte Sandbox am Laufen und die Ressource SandboxClaim fordert diese Sandbox aus dem Pool an. Damit der Snapshot-Prozess funktioniert, muss die Sandbox mit dem Kubernetes-Dienstkonto ausgeführt werden, das Sie zuvor in diesem Dokument erstellt haben. Die Sandbox muss auch die Labels enthalten, die Sie zuvor in der PodSnapshotPolicy-Ressource angegeben haben.

In diesem Beispiel wird eine Python-Anwendung verwendet, die einen inkrementierenden Zähler in die Logs schreibt. Mit diesem Zähler können Sie prüfen, ob der Status erfolgreich gespeichert und später wiederhergestellt wird.

Autopilot

Pod-Snapshots unterstützen keine E2-Maschinentypen. In Autopilot verwendet GKE möglicherweise standardmäßig Maschinentypen, die keine Pod-Snapshots unterstützen. Damit Ihre Arbeitslasten auf kompatibler Hardware ausgeführt werden, sollten Sie eine benutzerdefinierte ComputeClass verwenden, um kompatible Maschinenfamilien zu priorisieren.

  1. Speichern Sie das folgende Manifest als 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. Wenden Sie das Manifest an:

    kubectl apply -f non-e2-class.yaml
    
  3. Wenden Sie das folgende Manifest an, um die Ressourcen SandboxTemplate und SandboxWarmPool zu erstellen. Beachten Sie, dass die Ressource SandboxTemplate auf die ComputeClass verweist, die Sie gerade mit dem Knotenselektor cloud.google.com/compute-class: non-e2-class erstellt haben.

    kubectl apply -f - <<EOF
    ---
    apiVersion: extensions.agents.x-k8s.io/v1beta1
    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/v1beta1
    kind: SandboxWarmPool
    metadata:
      name: python-sandbox-warmpool
      namespace: ${SNAPSHOT_NAMESPACE}
    spec:
      replicas: 1
      sandboxTemplateRef:
        name: python-runtime-template
    EOF
    

Standard

Wenden Sie das folgende Manifest an, um die Ressourcen SandboxTemplate und SandboxWarmPool zu erstellen:

kubectl apply -f - <<EOF
---
apiVersion: extensions.agents.x-k8s.io/v1beta1
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/v1beta1
kind: SandboxWarmPool
metadata:
  name: python-sandbox-warmpool
  namespace: ${SNAPSHOT_NAMESPACE}
spec:
  replicas: 1
  sandboxTemplateRef:
    name: python-runtime-template
EOF

Nachdem Sie die Ressourcen erstellt haben, fordern Sie eine Sandbox aus dem Warmpool an:

  1. Warten Sie, bis die Sandbox des warmen Pools bereit ist:

    kubectl wait sandboxwarmpool python-sandbox-warmpool \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --for=jsonpath='{.status.readyReplicas}'=1 \
      --timeout=600s
    
  2. Erstellen Sie eine SandboxClaim-Ressource, die die Sandbox aus dem Warmpool anfordert:

    kubectl apply -f - <<EOF
    apiVersion: extensions.agents.x-k8s.io/v1beta1
    kind: SandboxClaim
    metadata:
      name: python-sandbox-example
      namespace: ${SNAPSHOT_NAMESPACE}
    spec:
      warmPoolRef:
        name: python-sandbox-warmpool
    EOF
    
  3. Warten Sie, bis die Anforderung bereit ist, und speichern Sie dann den Namen der Sandbox, die von der Anforderung verwendet wird. Der Pod der Sandbox hat denselben Namen wie die Sandbox:

    kubectl wait sandboxclaim python-sandbox-example \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --for=condition=Ready \
      --timeout=300s
    
    export SANDBOX_NAME=$(kubectl get sandboxclaim python-sandbox-example \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      -o jsonpath='{.status.sandbox.name}')
    echo "${SANDBOX_NAME}"
    

Ihre Sandbox wird jetzt mit der richtigen Identität ausgeführt und kann per Snapshot gesichert werden.

Snapshot erstellen

In diesem Abschnitt erfahren Sie, wie Sie manuell einen Snapshot Ihrer laufenden Sandbox auslösen. Sie erstellen eine Triggerressource, die auf Ihren Sandbox-Pod abzielt, und prüfen dann, ob der Snapshot-Prozess erfolgreich abgeschlossen wurde.

  1. Anfängliche Zählerlogs prüfen: Bevor Sie den Snapshot auslösen, rufen Sie die Logs der laufenden Sandbox auf, um den aktuellen Zählerwert zu sehen. Durch das Aufrufen der Logs wird eine Referenz erstellt, mit der Sie nach der Wiederherstellung vergleichen können.

    kubectl logs "${SANDBOX_NAME}" --namespace "${SNAPSHOT_NAMESPACE}" --tail=5
    

    Die Ausgabe zeigt die letzten Zeilen des Zählers, zum Beispiel:

    Count: 15
    Count: 16
    Count: 17
    

    Beachten Sie die letzten ausgegebenen „Count“-Werte.

  2. PodSnapshotManualTrigger-Ressource erstellen: Snapshot initiieren:

    kubectl apply -f - <<EOF
    apiVersion: podsnapshot.gke.io/v1
    kind: PodSnapshotManualTrigger
    metadata:
      name: cpu-snapshot-trigger
      namespace: ${SNAPSHOT_NAMESPACE}
    spec:
      targetPod: ${SANDBOX_NAME}
    EOF
    
  3. Prüfen Sie, ob der manuelle Trigger erfolgreich war:

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

    In der Ausgabe sollte der Status Complete angezeigt werden. Das bedeutet, dass GKE den Snapshot des Ziel-Pods erfolgreich ausgelöst hat:

    NAME                   TARGET POD                      STATUS     AGE
    cpu-snapshot-trigger   python-sandbox-warmpool-x7k2p   Complete   XXs
    
  4. Weitere Details zum erfassten Status ansehen, indem Sie den Trigger beschreiben:

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

    Die Ausgabe enthält einen Snapshot Created-Abschnitt mit dem eindeutigen Namen der Snapshot-Dateien, die in Ihrem Bucket gespeichert sind:

    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>
    

Aus einem Snapshot wiederherstellen

Nachdem Sie einen Snapshot erstellt haben, können Sie die Sandbox sperren, um ihre Rechenressourcen freizugeben, und die Sandbox später aus dem gespeicherten Zustand fortsetzen. Wenn Sie eine Sandbox sperren, löscht der Agent Sandbox-Controller den Pod der Sandbox, behält aber die Sandbox-Ressource bei. Wenn Sie die Sandbox fortsetzen, erstellt der Controller den Pod neu und der Pod-Snapshot-Controller stellt den Pod automatisch aus dem neuesten Snapshot dieser Sandbox wieder her.

  1. Warten Sie, bis der Snapshot bereit ist. Die GKE stellt einen Pod nur aus einem Snapshot wieder her, der bereit ist. Wenn Sie die Sandbox sperren, bevor der Snapshot bereit ist, wird die Sandbox beim Fortsetzen ohne den gespeicherten Status gestartet.

    export SNAPSHOT_NAME=$(kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io cpu-snapshot-trigger \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      -o jsonpath='{.status.snapshotCreated.name}')
    
    kubectl wait podsnapshots.podsnapshot.gke.io "${SNAPSHOT_NAME}" \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --for=condition=Ready \
      --timeout=600s
    
  2. Wenn Sie die Sandbox sperren möchten, setzen Sie das Feld operatingMode auf Suspended und warten Sie, bis der Controller den Pod der Sandbox löscht:

    kubectl patch sandbox "${SANDBOX_NAME}" \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --type=merge \
      -p '{"spec":{"operatingMode":"Suspended"}}'
    
    kubectl wait pod "${SANDBOX_NAME}" \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --for=delete \
      --timeout=120s
    
  3. Wenn Sie die Sandbox fortsetzen möchten, setzen Sie das Feld operatingMode auf Running und warten Sie, bis die Sandbox bereit ist:

    kubectl patch sandbox "${SANDBOX_NAME}" \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --type=merge \
      -p '{"spec":{"operatingMode":"Running"}}'
    
    kubectl wait sandbox "${SANDBOX_NAME}" \
      --namespace "${SNAPSHOT_NAMESPACE}" \
      --for=condition=Ready \
      --timeout=300s
    
  4. Prüfen Sie anhand der Logs, ob die Wiederherstellung stattgefunden hat. Beachten Sie, dass der Zähler an der Stelle fortgesetzt wird, an der der Snapshot erstellt wurde:

    kubectl logs "${SANDBOX_NAME}" --namespace "${SNAPSHOT_NAMESPACE}"
    

    In der Ausgabe sollte angezeigt werden, dass der Zähler fortgesetzt wird, z. B.:

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

    Wenn der Zähler stattdessen bei 0 beginnt, wurde der Pod ohne Wiederherstellung aus dem Snapshot gestartet.

Ressourcen bereinigen

Mit den folgenden Schritten können Sie vermeiden, dass Ihrem Google Cloud Konto die in diesem Dokument verwendeten Ressourcen in Rechnung gestellt werden. Löschen Sie dazu die erstellten Ressourcen:

  1. Löschen Sie die Sandbox-Anforderungen und Warm Pools, um alle laufenden Pods zu beenden und dem Agent Sandbox-Controller zu ermöglichen, die Container ordnungsgemäß zu beenden.

    kubectl delete sandboxclaims --all --namespace "${SNAPSHOT_NAMESPACE}"
    kubectl delete sandboxwarmpools --all --namespace "${SNAPSHOT_NAMESPACE}"
    
  2. Löschen Sie die Sandbox-Vorlagen und manuellen Trigger, die zum Erstellen von Sandboxes und zum Initiieren von Snapshots verwendet wurden.

    # Delete the blueprints
    kubectl delete sandboxtemplates --all --namespace "${SNAPSHOT_NAMESPACE}"
    
    # Delete the snapshot initiation objects
    kubectl delete podsnapshotmanualtriggers --all --namespace "${SNAPSHOT_NAMESPACE}"
    
  3. Löschen Sie die Snapshot-Richtlinien, die festlegen, welche Pods in Ihrem Namespace für Snapshots infrage kommen.

    kubectl delete podsnapshotpolicy cpu-psp --namespace "${SNAPSHOT_NAMESPACE}"
    
  4. Löschen Sie die Snapshot-Speicherkonfiguration, die die globale Definition Ihres Snapshot-Speicher-Backends ist. Da diese Ressource clusterbezogen ist, verwenden Sie kein Namespace-Flag.

    kubectl delete podsnapshotstorageconfig cpu-pssc-gcs
    
  5. Wenn Sie eine ComputeClass für Autopilot erstellt haben, löschen Sie sie.

    kubectl delete computeclass non-e2-class
    
  6. Löschen Sie den Kubernetes-Namespace, um das Kubernetes-Dienstkonto und alle verbleibenden Namespace-Metadaten automatisch zu entfernen.

    kubectl delete namespace "${SNAPSHOT_NAMESPACE}"
    
  7. Löschen Sie den GKE-Cluster, um die zugrunde liegende Infrastruktur und alle mit der Anleitung verknüpften Knoten zu entfernen.

    Autopilot

    gcloud container clusters delete "${CLUSTER_NAME}" \
        --location="${GKE_LOCATION}" --quiet
    

    Standard

    gcloud container clusters delete "${CLUSTER_NAME}" \
        --location="${ZONE}" --quiet
    
  8. Löschen Sie den Cloud Storage-Bucket (optional) mit dem Befehl zum rekursiven Entfernen, wenn Sie den Speicher vollständig zurücksetzen möchten. Sie können diesen Schritt überspringen, wenn Sie den korrekt konfigurierten Bucket für zukünftige Tests wiederverwenden möchten.

    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. Löschen Sie die benutzerdefinierte IAM-Rolle (optional), wenn Sie Ihr Projekt in einen vollständig sauberen Zustand zurückversetzen möchten. Da IAM-Rollen auch nach dem Löschen des Clusters erhalten bleiben, müssen Sie sie separat löschen.

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

Nächste Schritte