Verwenden Sie Agent Sandbox für Google Kubernetes Engine (GKE)-Snapshots in einem Cluster, um den Status Ihrer Sandbox-Umgebungen beizubehalten. Dieser Ansatz ermöglicht ein konsistentes Debugging, beschleunigt die Entwicklungsiteration und erleichtert die schnelle Wiederherstellung komplexer Setups. In dieser Anleitung stellen Sie diese Funktion bereit und testen sie, indem Sie eine Clientanwendung ausführen, die programmatisch Sandbox-Umgebungen im Cluster erstellt, pausiert und fortsetzt.
Weitere Informationen zum Erstellen von Snapshots von Pods finden Sie unter Aus einem Pod-Snapshot wiederherstellen.
Kosten
Agent Sandbox in GKE ist eine Open-Source-Software, die Sie ohne zusätzliche Kosten verwenden können. Die GKE-Preise gelten für die von Ihnen erstellten Ressourcen, einschließlich der vom Agent Sandbox-Controller verwendeten Rechenressourcen.
Hinweis
-
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 Berechtigungresourcemanager.projects.createenthält. Informationen zum Zuweisen von Rollen
-
Prüfen Sie, ob die Abrechnung für Ihr Google Cloud -Projekt aktiviert ist.
Aktivieren Sie die Artifact Registry API, die Kubernetes Engine API und die Cloud Build API, 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-
Aktivieren Sie Cloud Shell in der Google Cloud Console.
- Prüfen Sie, ob Sie die Berechtigungen haben, die für diese Anleitung erforderlich sind.
Erforderliche Rollen
Bitten Sie Ihren Administrator, Ihnen die IAM-Rolle Kubernetes Engine-Administrator (roles/container.admin) für Ihr Projekt zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Erstellen und Verwalten von Sandboxen benötigen.
Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.
Sie können die erforderlichen Berechtigungen auch über benutzerdefinierte Rollen oder andere vordefinierte Rollen erhalten.
Beschränkungen
Pod-Snapshots erfordern gVisor und funktionieren nicht mit MicroVM-Sandboxes.
In einem regionalen Cluster können Knoten in verschiedenen Zonen unterschiedliche CPU-Mikroarchitekturen haben. Da Snapshots den CPU-Status erfassen, schlägt die Wiederherstellung eines Snapshots auf einem Knoten mit fehlenden CPU-Features fehl (z. B. mit dem Fehler OCI runtime restore failed: incompatible FeatureSet).
Verwenden Sie die entsprechende Konfiguration für Ihre Umgebung, um dieses Problem zu vermeiden:
- Produktion: Um die Hochverfügbarkeit im gesamten Cluster aufrechtzuerhalten, sollten Sie Arbeitslasten nicht an eine bestimmte Zone binden. Sorgen Sie stattdessen für eine einheitliche CPU-Funktionalität in allen Zonen, indem Sie eine kleinstmögliche CPU-Plattform angeben. Weitere Informationen finden Sie unter Mindest-CPU-Plattform auswählen.
- Testen: Um die Einrichtung zu vereinfachen und anfängliche CPU-Konfliktfehler zu vermeiden, können Sie ein
nodeSelector-Feld in IhremSandboxTemplate-Manifest verwenden, um den Pod an eine bestimmte Zone wieus-central1-aanzuhängen. Im Beispiel in dieser Anleitung wird diese Testkonfiguration verwendet.
Umgebungsvariablen definieren
Um die Befehle zu vereinfachen, die Sie in dieser Anleitung ausführen, können Sie Umgebungsvariablen in Cloud Shell festlegen. Definieren Sie in Cloud Shell die folgenden nützlichen Umgebungsvariablen, indem Sie die folgenden Befehle ausführen:
export PROJECT_ID=$(gcloud config get project)
export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
export CLUSTER_NAME="test-snapshot"
export LOCATION="us-central1"
export ZONE="us-central1-a"
export BUCKET_LOCATION="us"
export MACHINE_TYPE="n2-standard-2"
export REPOSITORY_NAME="agent-sandbox"
export BUCKET_NAME="${PROJECT_ID}_snapshots"
export CLOUDBUILD_BUCKET_NAME="${PROJECT_ID}_cloudbuild"
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.PROJECT_NUMBER: Die Projektnummer Ihres aktuellen Google Cloud -Projekts.CLUSTER_NAME: der Name Ihres GKE-Cluster, z. B.test-snapshot.LOCATION: die Google Cloud Region für Ihr Artifact Registry-Repository (z. B.us-central1). Wenn Sie einen Autopilot-Cluster erstellen, verwendet der Cluster auch diese Region.ZONE: die Zone für Ihren Cluster. Wenn Sie einen Standardcluster erstellen, legen Sie hier eine Zone in der RegionLOCATIONfest (z. B.us-central1-a). Die Sandbox-Vorlage, die Sie später in dieser Anleitung erstellen, führt Sandboxes inus-central1-aaus. Wenn Sie eine andere Zone verwenden, ändern Sie die Zone auch in der Vorlage.BUCKET_LOCATION: der Standort Ihrer Cloud Storage-Buckets, z. B.us.BUCKET_NAME: der Name des Cloud Storage-Bucket, der für Snapshots verwendet wird, z. B.PROJECT_ID_snapshots. Bucket-Namen müssen global eindeutig sein.CLOUDBUILD_BUCKET_NAME: Der Name des Cloud Storage-Bucket, der für Cloud Build-Logs verwendet wird. Dieser Wert ist der Standardname des Cloud Build-Buckets. Ändern Sie ihn daher nicht.MACHINE_TYPE: der Maschinentyp, der für die Clusterknoten und den gVisor-Knotenpool verwendet werden soll, z. B.n2-standard-2. Pod-Snapshots unterstützen keine E2-Maschinentypen.REPOSITORY_NAME: der Name des Artifact Registry-Repositorys, z. B.agent-sandbox.
Übersicht über die Konfigurationsschritte
Wenn Sie Pod-Snapshots der Agent Sandbox in GKE-Umgebungen in Ihrem Cluster aktivieren und testen möchten, müssen Sie mehrere Konfigurationsschritte ausführen. Um diese Schritte nachvollziehen zu können, ist es hilfreich, zuerst die am gesamten Workflow beteiligten Komponenten zu verstehen.
Schlüsselkomponenten
In dieser Anleitung werden die folgenden beiden Python-Anwendungen verwendet, um den Snapshot-Prozess zu testen:
- Clientanwendung: Ein Python-Skript, das in einem Standard-Pod in Ihrem Cluster ausgeführt wird. Diese Anwendung verwaltet den Sandbox-Lebenszyklus: Sie erstellt die Sandbox programmatisch, pausiert sie, um einen Snapshot auszulösen, setzt die Sandbox fort und prüft, ob der Status beibehalten wurde. In dieser Anleitung erstellen Sie ein Kubernetes-Dienstkonto mit dem Namen
agent-sandbox-client-saund gewähren ihm RBAC-Berechtigungen, damit der Pod der Clientanwendung benutzerdefinierte Sandbox-Ressourcen und Snapshot-Triggerobjekte mithilfe der Kubernetes API verwalten kann. - Sandbox-Anwendung: Ein Python-Script, das jede Sekunde einen Zähler erhöht und ausgibt. Diese Anwendung wird sicher in der isolierten Sandbox-Umgebung ausgeführt, um einen sich ändernden Status zu generieren, den die Clientanwendung prüfen kann. In dieser Anleitung erstellen Sie ein dediziertes Kubernetes-Dienstkonto mit dem Namen
snapshot-saund konfigurieren Workload Identity, um den Pod in der Sandbox zu autorisieren, Snapshot-Objekte in Cloud Storage sicher zu lesen und zu schreiben.
Konfiguration und Tests
In der folgenden Liste sind die Schritte zusammengefasst, die Sie ausführen müssen, um Ihre Umgebung einzurichten und den Test auszuführen:
- Cluster erstellen: Erstellen Sie einen Autopilot- oder Standardcluster mit aktivierten Pod-Snapshots.
- Artifact Registry-Repository erstellen: Erstellen Sie ein Docker-Repository, um das Container-Image für Ihre Clientanwendung zu speichern.
- Agent Sandbox installieren: Installieren Sie die wichtigsten Agent Sandbox-Komponenten und -Erweiterungen in Ihrem Cluster.
- Speicher und Berechtigungen konfigurieren: Erstellen Sie einen Cloud Storage-Bucket und konfigurieren Sie Workload Identity-Berechtigungen, damit Snapshots sicher gespeichert werden können.
- Pod-Snapshots konfigurieren: Erstellen und wenden Sie die Snapshot-Speicherkonfiguration, die Snapshot-Richtlinie, die Sandbox-Vorlage und den Warm-Pool an.
- Clientanwendung erstellen: Erstellen Sie das Container-Image für die Clientanwendung und übertragen Sie es per Push in Ihr Artifact Registry-Repository.
- Test ausführen: Stellen Sie den Pod der Clientanwendung bereit. Dadurch wird die Sandbox erstellt, pausiert, um einen Snapshot zu erstellen, fortgesetzt und geprüft, ob der Status des Zählers erfolgreich wiederhergestellt wurde.
Cluster erstellen
Erstellen Sie einen neuen GKE-Cluster mit aktivierten Pod-Snapshots. Wenn Sie die volle Funktionskompatibilität nutzen möchten, geben Sie die schnelle Veröffentlichung an.
Autopilot
Erstellen Sie einen Autopilot-Cluster mit den erforderlichen Features:
gcloud container clusters create-auto ${CLUSTER_NAME} \
--enable-pod-snapshots \
--release-channel=rapid \
--location=${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} \
--enable-pod-snapshots \
--release-channel=rapid \
--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 aktiviertem gVisor:
gcloud container node-pools create gvisor-pool \
--cluster ${CLUSTER_NAME} \
--machine-type=${MACHINE_TYPE} \
--num-nodes=1 \
--location=${ZONE} \
--project=${PROJECT_ID} \
--sandbox type=gvisor
Artifact Registry-Repository erstellen
Erstellen Sie ein Docker-Repository in Artifact Registry, um das Container-Image für Ihre Clientanwendung (die Anwendung, die die Sandbox erstellt und verwaltet) zu speichern:
gcloud artifacts repositories create ${REPOSITORY_NAME} \
--repository-format=docker \
--location=${LOCATION} \
--description="Docker repository for Agent Sandbox"
Agent Sandbox installieren
Installieren Sie die Kernkomponenten und Erweiterungen von Agent Sandbox in Ihrem Cluster. In dieser Anleitung wird die Version 1.0.6 verwendet:
# Install the core agent-sandbox components and the extensions (e.g., Warm Pools, Claims)
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/v1.0.6/sandbox-with-extensions.yaml
Weitere Informationen zur Installation der Agent Sandbox finden Sie unter Agent Sandbox in GKE installieren.
Speicher und Berechtigungen konfigurieren
Konfigurieren Sie einen Cloud Storage-Bucket zum Speichern von Pod-Snapshots und gewähren Sie dem Dienstkonto snapshot-sa und dem GKE-Dienst-Agent die erforderlichen Workload Identity-Berechtigungen. So können Ihre Sandbox-Arbeitslasten Snapshot-Objekte sicher speichern und abrufen:
Erstellen Sie einen neuen Cloud Storage-Bucket:
gcloud storage buckets create "gs://${BUCKET_NAME}" \ --uniform-bucket-level-access \ --enable-hierarchical-namespace \ --soft-delete-duration=0d \ --location="${BUCKET_LOCATION}"Erstellen Sie ein Kubernetes-Dienstkonto im Namespace
default. Ihre Sandbox-Anwendung (das Python-Zählerskript) verwendet diese Identität, um sich bei externen APIs zu authentifizieren und sicher auf Snapshot-Objekte zuzugreifen, die in Cloud Storage gespeichert sind:kubectl create serviceaccount "snapshot-sa" \ --namespace "default"Binden Sie die Rolle
storage.bucketViewermithilfe von Workload Identity an Ihr Dienstkonto. Mit dieser Rolle kann die Sandbox-Arbeitslast den Bucket-Inhalt auflisten und bestimmte Snapshots finden: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/default/sa/snapshot-sa" \ --role="roles/storage.bucketViewer"Binden Sie die Rolle
storage.objectUsermithilfe von Workload Identity an Ihr Dienstkonto. Diese Rolle gewährt die Berechtigung zum Lesen, Speichern und Löschen von Snapshot-Binärobjekten im Bucket: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/default/sa/snapshot-sa" \ --role="roles/storage.objectUser"Gewähren Sie dem GKE-Dienst-Agent Berechtigungen zum Verwalten (Erstellen, Auflisten, Lesen und Löschen) von Snapshot-Objekten im Bucket:
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"
Pod-Snapshots konfigurieren
Erstellen Sie die Konfigurationsdateien und wenden Sie sie an, um die erforderlichen benutzerdefinierten Kubernetes-Ressourcen zu installieren. Diese Ressourcen definieren, wie der Cluster Pod-Snapshots speichert und verwaltet:
PodSnapshotStorageConfig: Gibt den Cloud Storage-Bucket an, der zum Speichern von binären Snapshot-Objekten vorgesehen ist.PodSnapshotPolicy: Definiert, wie Snapshots manuell ausgelöst werden, wie oft sie gruppiert werden und welche Aufbewahrungsrichtlinien gelten.SandboxTemplate: Definiert den zugrunde liegenden Container, die Knotenauswahl und die Dienstkonten zum Ausführen der isolierten Sandbox-Arbeitslast.SandboxWarmPool: Hält eine vorab initialisierte Sandbox, die aus derSandboxTemplate-Ressource erstellt wurde, für die Clientanwendung bereit.
Erstellen Sie ein neues Verzeichnis für die Testclientdateien:
mkdir test_clientRufen Sie das neue Verzeichnis auf:
cd test_clientErstellen Sie eine Datei mit dem Namen
snapshot_storage_config.yaml. In dieser Konfiguration wird der Cloud Storage-Ziel-Bucket angegeben, in dem der Cluster den binären Pod-Snapshot-Status speichert:apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotStorageConfig metadata: name: example-pod-snapshot-storage-config spec: snapshotStorageConfig: gcs: bucket: "$BUCKET_NAME"Ersetzen Sie den Platzhalter für die Umgebungsvariable in der Konfigurationsdatei:
sed -i "s/\$BUCKET_NAME/${BUCKET_NAME}/g" snapshot_storage_config.yamlWenden Sie das Speicherkonfigurationsmanifest an:
kubectl apply -f snapshot_storage_config.yamlWarten Sie, bis die Speicherkonfiguration bereit ist:
kubectl wait --for=condition=Ready podsnapshotstorageconfig/example-pod-snapshot-storage-config --timeout=60sErstellen Sie eine Datei mit dem Namen
snapshot_policy.yaml. Mit dieser Konfiguration wird eine Aufbewahrungsregel festgelegt, die maximal zwei Snapshots für Ihre Sandbox-Arbeitslast aufbewahrt. Der Triggertyp ist aufmanualfestgelegt. Dadurch kann die Clientanwendung Snapshots nach Bedarf steuern:apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotPolicy metadata: name: example-pod-snapshot-policy namespace: default spec: storageConfigName: example-pod-snapshot-storage-config selector: matchLabels: app: agent-sandbox-workload triggerConfig: type: manual postCheckpoint: resume snapshotGroupingRules: groupByLabelValue: labels: ["agents.x-k8s.io/sandbox-name-hash", "tenant-id", "user-id"] groupRetentionPolicy: maxSnapshotCountPerGroup: 2Wenden Sie das Manifest der Snapshot-Richtlinie an:
kubectl apply -f snapshot_policy.yamlErstellen Sie eine Datei mit dem Namen
python-counter-template.yaml. Diese Konfiguration definiert den Sandbox-Pod und weist ihm die Dienstkontoidentitätsnapshot-sazu. Diese Zuweisung trägt dazu bei, dass die Sandbox sicher ausgeführt wird. In diesem Pod gibt die Sandbox-Anwendung (ein Python-Skript) kontinuierlich einen inkrementierenden Zähler in den Containerlogs aus:apiVersion: extensions.agents.x-k8s.io/v1beta1 kind: SandboxTemplate metadata: name: python-counter-template namespace: default spec: podTemplate: metadata: labels: app: agent-sandbox-workload spec: serviceAccountName: snapshot-sa runtimeClassName: gvisor nodeSelector: topology.kubernetes.io/zone: us-central1-a # Pin to a zone to avoid CPU mismatch during restore containers: - name: python-counter image: python:3.13-slim command: ["python3", "-c"] args: - | import time i = 0 while True: print(f"Count: {i}", flush=True) i += 1 time.sleep(1)Wenden Sie das Manifest der Sandbox-Vorlage an:
kubectl apply -f python-counter-template.yamlErstellen Sie eine Datei mit dem Namen
python-counter-pool.yaml. Mit dieser Konfiguration wird ein Warmpool erstellt, der eine vorab aufgewärmte Sandbox, die aus der Vorlagepython-counter-templateerstellt wurde, für die Clientanwendung bereithält:apiVersion: extensions.agents.x-k8s.io/v1beta1 kind: SandboxWarmPool metadata: name: python-counter-pool namespace: default spec: replicas: 1 sandboxTemplateRef: name: python-counter-templateWenden Sie das Warm-Pool-Manifest an:
kubectl apply -f python-counter-pool.yaml
Clientanwendung erstellen
Erstellen Sie das Container-Image für die Clientanwendung und laden Sie es in Artifact Registry hoch.
Erstellen Sie eine Datei mit dem Namen
Dockerfile.client. In dieser Datei werden die Python-Laufzeitumgebung und die Abhängigkeiten für die Clientanwendung definiert:FROM python:3.13-slim WORKDIR /app RUN pip install "k8s-agent-sandbox[tracing]==1.0.6" # Copy test script COPY client_test.py /app/client_test.py CMD ["python", "/app/client_test.py"]Erstellen Sie eine Datei mit dem Namen
client_test.py. Dieses Script verwaltet den Lebenszyklus der Sandbox und prüft, ob der Status nach dem Erstellen eines Snapshots erfolgreich fortgesetzt wird:import time import logging import re from kubernetes import config, client from k8s_agent_sandbox.gke_extensions.snapshots import PodSnapshotSandboxClient logging.basicConfig(level=logging.INFO) def get_last_count(pod_name, namespace): v1 = client.CoreV1Api() try: logs = v1.read_namespaced_pod_log(name=pod_name, namespace=namespace) counts = re.findall(r"Count: (\d+)", logs) if counts: return int(counts[-1]) return None except Exception as e: logging.error(f"Failed to read logs for pod {pod_name}: {e}") return None def get_current_count(sandbox): # The sandbox's Pod has the same name as the Sandbox resource. pod_name = sandbox.get_pod_name() if not pod_name: logging.error(f"Could not determine pod name for sandbox {sandbox.sandbox_id}") return None return get_last_count(pod_name, sandbox.namespace) def suspend_sandbox(sandbox): logging.info("Pausing sandbox (using snapshots)...") try: suspend_resp = sandbox.suspend(snapshot_before_suspend=True) if suspend_resp.success: logging.info("Sandbox paused successfully.") if suspend_resp.snapshot_response: logging.info(f"Snapshot created: {suspend_resp.snapshot_response.snapshot_uid}") return suspend_resp else: logging.error(f"Failed to pause: {suspend_resp.error_reason}") exit(1) except Exception as e: logging.error(f"Failed to pause sandbox: {e}") exit(1) def resume_sandbox(sandbox): logging.info("Resuming sandbox (using snapshots)...") try: resume_resp = sandbox.resume() if resume_resp.success: logging.info("Sandbox resumed successfully.") if resume_resp.restored_from_snapshot: logging.info(f"Restored from snapshot: {resume_resp.snapshot_uid}") return resume_resp else: logging.error(f"Failed to resume: {resume_resp.error_reason}") exit(1) except Exception as e: logging.error(f"Failed to resume sandbox: {e}") exit(1) def verify_continuity(count_before, count_after): if count_before is not None and count_after is not None: logging.info(f"Verification: Count before={count_before}, Count after={count_after}") if count_after >= count_before: logging.info("SUCCESS: Sandbox resumed from where it left off (or later).") else: logging.error("FAIL: Sandbox counter reset or went backwards!") else: logging.warning("Could not verify counter continuity.") def main(): try: config.load_incluster_config() except config.ConfigException: config.load_kube_config() client_reg = PodSnapshotSandboxClient() logging.info("Creating sandbox...") sandbox = client_reg.create_sandbox(warmpool="python-counter-pool", namespace="default") logging.info(f"Sandbox created with ID: {sandbox.sandbox_id}") logging.info("Waiting for sandbox to run...") time.sleep(10) count_before = get_current_count(sandbox) logging.info(f"Count before suspend: {count_before}") suspend_sandbox(sandbox) logging.info("Waiting 10 seconds...") time.sleep(10) resume_sandbox(sandbox) logging.info("Waiting for sandbox to be ready again...") time.sleep(10) count_after = get_current_count(sandbox) logging.info(f"Count after resume: {count_after}") verify_continuity(count_before, count_after) logging.info("Snapshot test completed successfully.") if __name__ == "__main__": main()Erstellen Sie das Client-Container-Image und laden Sie es in Artifact Registry hoch. Wenn in Ihrer Umgebung (z. B. Cloud Shell) Docker installiert ist, können Sie Docker verwenden, um das Image lokal zu erstellen. Wenn Sie in einer Umgebung ohne Docker arbeiten, können Sie Cloud Build verwenden, um das Image remote zu erstellen und per Push zu übertragen:
Docker
Konfigurieren Sie die Docker-Authentifizierung für Artifact Registry:
gcloud auth configure-docker "${LOCATION}-docker.pkg.dev"Erstellen Sie das Client-Container-Image lokal und übertragen Sie es per Push:
docker build -t "${LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/sandbox-client:latest" -f Dockerfile.client . docker push "${LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/sandbox-client:latest"
Cloud Build
Erstellen Sie eine Datei mit dem Namen
cloudbuild.yaml:steps: - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', '$LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY_NAME/sandbox-client:latest', '-f', 'Dockerfile.client', '.'] images: - '$LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY_NAME/sandbox-client:latest'Ersetzen Sie die Platzhalter für Umgebungsvariablen in der Konfigurationsdatei:
sed -i "s/\$REPOSITORY_NAME/${REPOSITORY_NAME}/g" cloudbuild.yaml sed -i "s/\$LOCATION/${LOCATION}/g" cloudbuild.yaml sed -i "s/\$PROJECT_ID/${PROJECT_ID}/g" cloudbuild.yamlErstellen Sie den Cloud Storage-Bucket für Cloud Build-Logs. Wenn Ihr Projekt bereits Cloud Build verwendet hat, ist dieser Bucket möglicherweise bereits vorhanden und der Befehl schlägt mit einem Fehler fehl, der besagt, dass Sie den Bucket bereits besitzen. Sie können diesen Fehler einfach ignorieren:
gcloud storage buckets create "gs://${CLOUDBUILD_BUCKET_NAME}" \ --location="${BUCKET_LOCATION}"Erteilen Sie dem Cloud Build-Dienstkonto die erforderlichen Berechtigungen.
In den folgenden Befehlen wird das Compute Engine-Standarddienstkonto (
$PROJECT_NUMBER-compute@developer.gserviceaccount.com) verwendet, das für die meisten Projekte standardmäßig verwendet wird. Wenn Ihr Projekt das Legacy-Cloud Build-Dienstkonto verwendet, ersetzen Sie die E-Mail-Adresse des Mitglieds in den folgenden Befehlen durch$PROJECT_NUMBER@cloudbuild.gserviceaccount.com.Da Sie Ihrem Projekt zuvor in dieser Anleitung eine bedingte IAM-Bindung hinzugefügt haben, sollten Sie beim Hinzufügen dieser neuen Bindungen das Flag
--condition=Noneangeben. Dadurch wird verhindert, dassgcloudpausiert, um eine interaktive Bestätigung anzufordern:gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/artifactregistry.writer" \ --condition=None gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/logging.logWriter" \ --condition=None gcloud storage buckets add-iam-policy-binding "gs://${CLOUDBUILD_BUCKET_NAME}" \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/storage.objectAdmin"Führen Sie den Build mit Cloud Build aus:
gcloud builds submit --config cloudbuild.yaml
Testen
Stellen Sie die Clientanwendung bereit, um die Sandbox zu erstellen, einen Snapshot auszulösen und zu prüfen, ob der interne Zähler erfolgreich aus dem gespeicherten Zustand fortgesetzt wird.
Erstellen Sie eine Datei mit dem Namen
client_sa.yaml. In diesem Manifest werden das Dienstkontoagent-sandbox-client-saund die erforderlichen RBAC-Berechtigungen zum Verwalten benutzerdefinierter Sandbox-Ressourcen definiert:apiVersion: v1 kind: ServiceAccount metadata: name: agent-sandbox-client-sa namespace: default --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: agent-sandbox-client-role namespace: default rules: - apiGroups: ["agents.x-k8s.io"] resources: ["sandboxes"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["extensions.agents.x-k8s.io"] resources: ["sandboxclaims"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["podsnapshot.gke.io"] resources: ["podsnapshotmanualtriggers", "podsnapshots"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: [""] resources: ["pods", "pods/log"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: agent-sandbox-client-rolebinding namespace: default subjects: - kind: ServiceAccount name: agent-sandbox-client-sa namespace: default roleRef: kind: Role name: agent-sandbox-client-role apiGroup: rbac.authorization.k8s.ioWenden Sie das Clientdienstkonto und das RBAC-Manifest an:
kubectl apply -f client_sa.yamlErstellen Sie eine Datei mit dem Namen
client_pod.yaml. Mit diesem Manifest wird der Pod der Clientanwendung mit dem vordefinierten Container-Image erstellt:apiVersion: v1 kind: Pod metadata: name: agent-sandbox-client-pod namespace: default spec: serviceAccountName: agent-sandbox-client-sa containers: - name: client image: $LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY_NAME/sandbox-client:latest imagePullPolicy: Always restartPolicy: NeverErsetzen Sie die Platzhalter für Umgebungsvariablen im Manifest:
sed -i "s/\$REPOSITORY_NAME/${REPOSITORY_NAME}/g" client_pod.yaml sed -i "s/\$LOCATION/${LOCATION}/g" client_pod.yaml sed -i "s/\$PROJECT_ID/${PROJECT_ID}/g" client_pod.yamlWarten Sie, bis die Sandbox des warmen Pools bereit ist:
kubectl wait sandboxwarmpool python-counter-pool \ --for=jsonpath='{.status.readyReplicas}'=1 \ --timeout=600sIm nächsten Schritt erstellt die Clientanwendung eine
SandboxClaim-Ressource. Wenn die Anwendung die Anforderung erstellt, bevor die Sandbox des Pools bereit ist, erstellt der Controller möglicherweise eine neue Sandbox für die Anforderung, anstatt die Sandbox aus dem Pool zuzuweisen. In einem Autopilot-Cluster kann es mehrere Minuten dauern, bis die Sandbox bereit ist, da GKE möglicherweise einen Knoten dafür erstellen muss.Wenden Sie das Pod-Manifest der Clientanwendung an:
kubectl apply -f client_pod.yamlStreamen Sie die Pod-Logs, um den Ausführungsablauf zu prüfen:
kubectl logs -f agent-sandbox-client-pod
Wenn der Test korrekt ausgeführt wird, sieht die Ausgabe in etwa so aus (hier aus Gründen der Lesbarkeit gekürzt):
2026-04-21 23:02:39,030 - INFO - Creating sandbox...
...
2026-04-21 23:02:51,755 - INFO - Count before suspend: 23
2026-04-21 23:02:51,755 - INFO - Pausing sandbox (using snapshots)...
...
2026-04-21 23:03:07,115 - INFO - Resuming sandbox (using snapshots)...
...
2026-04-21 23:03:21,329 - INFO - Count after resume: 38
2026-04-21 23:03:21,329 - INFO - Verification: Count before=23, Count after=38
2026-04-21 23:03:21,329 - INFO - SUCCESS: Sandbox resumed from where it left off (or later).
Die Ausgabe zeigt, dass die Sandbox ihren Status beim Sperren und Fortsetzen beibehält. Der Zähler wird nicht mehr erhöht, während die Sandbox gesperrt ist, da der Agent Sandbox-Controller den Pod der Sandbox löscht. Wenn die Sandbox fortgesetzt wird, erstellt der Controller den Pod neu, der aus dem Snapshot wiederhergestellt wird, und der Zähler wird fortgesetzt. Ohne die Sperrung wäre der Zähler während des Sperrzeitraums weitergelaufen und die Anzahl wäre deutlich höher.
Ressourcen bereinigen
Löschen Sie die erstellten Ressourcen, damit Ihrem Google Cloud -Konto keine Gebühren in Rechnung gestellt werden:
Löschen Sie den GKE-Cluster. Dadurch werden auch der Knotenpool und alle darin enthaltenen Kubernetes-Dienstkonten gelöscht:
Autopilot
gcloud container clusters delete ${CLUSTER_NAME} \ --location="${LOCATION}" --quietStandard
gcloud container clusters delete ${CLUSTER_NAME} \ --location="${ZONE}" --quietLöschen Sie das Artifact Registry-Repository, um das Docker-Repository zu entfernen, das Sie für das Test-Image erstellt haben:
gcloud artifacts repositories delete ${REPOSITORY_NAME} --location="${LOCATION}" --quietLöschen Sie den Cloud Storage-Bucket und alle darin enthaltenen Snapshots. Dadurch werden die auf den Bucket angewendeten IAM-Bindungen für Workload Identity auf Bucket-Ebene automatisch entfernt:
gcloud storage rm --recursive "gs://${BUCKET_NAME}"Entfernen Sie die IAM-Bindung auf Projektebene für den GKE-Dienst-Agent:
gcloud projects remove-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"Wenn Sie das Container-Image mit Cloud Build anstelle von Docker erstellt und per Push übertragen haben, bereinigen Sie die Cloud Build-Ressourcen. Löschen Sie nur die Ressourcen, die Sie für diese Anleitung erstellt haben, da andere Arbeitslasten in Ihrem Projekt möglicherweise von Ressourcen abhängen, die bereits vorhanden waren:
Wenn der Cloud Build-Bucket vor Beginn dieser Anleitung nicht vorhanden war, löschen Sie ihn:
gcloud storage rm --recursive "gs://${CLOUDBUILD_BUCKET_NAME}"Wenn das Compute Engine-Standarddienstkonto vor Beginn dieser Anleitung nicht die Rollen
roles/artifactregistry.writerundroles/logging.logWriterhatte, entfernen Sie sie:gcloud projects remove-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/artifactregistry.writer" \ --condition=None gcloud projects remove-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/logging.logWriter" \ --condition=None
Nächste Schritte
- KI-Code-Ausführung mit Agent Sandbox in der GKE isolieren
- Agent Sandbox in GKE-Umgebungen speichern und wiederherstellen
- Informationen zu den Isolierungsebenen, die Ihre nicht vertrauenswürdigen Arbeitslasten schützen, finden Sie unter GKE Sandbox.
- Sehen Sie sich das Open-Source-Projekt Agent Sandbox auf GitHub an.
- Open-Source-Kata-Container mit Agent Sandbox in GKE verwenden Kata Containers ist kein Produkt von Google Cloud . Wenn Sie diese Software installieren und verwenden, sind Sie für die Verwaltung und Fehlerbehebung verantwortlich. Der Support und die SLAs von Google gelten nicht für Kata Containers.