Ce tutoriel explique comment déployer et tester la fonctionnalité d'instantané Agent Sandbox dans un cluster Google Kubernetes Engine (GKE). Vous apprendrez à exécuter une application cliente dans le cluster pour créer, mettre en pause et reprendre des environnements en bac à sable de manière programmatique.
Pour en savoir plus sur la création d'instantanés de pods, consultez Restaurer à partir d'un instantané de pod.
Coûts
Agent Sandbox est proposé sans frais supplémentaires dans GKE. Les tarifs de GKE s'appliquent aux ressources que vous créez.
Avant de commencer
-
Dans la Cloud de Confiance console, sur la page de sélection du projet, sélectionnez ou créez un Cloud de Confiance projet.
Rôles requis pour sélectionner ou créer un projet
- Sélectionner un projet : la sélection d'un projet ne nécessite pas de rôle IAM spécifique Vous pouvez sélectionner n'importe quel projet pour lequel un rôle vous a été attribué.
-
Créer un projet : pour créer un projet, vous avez besoin du rôle Créateur de projet
(
roles/resourcemanager.projectCreator), qui contient l'autorisationresourcemanager.projects.create. Découvrez comment attribuer des rôles.
-
Vérifiez que la facturation est activée pour votre Cloud de Confiance projet.
Activez les API Artifact Registry et Kubernetes Engine.
Rôles requis pour activer les API
Pour activer les API, vous avez besoin du rôle IAM Administrateur d'utilisation du service (
roles/serviceusage.serviceUsageAdmin), qui contient l'autorisationserviceusage.services.enable. Découvrez comment attribuer des rôles.-
Dans la Cloud de Confiance console, activez Cloud Shell.
- Vérifiez que vous disposez des autorisations requises pour suivre ce tutoriel.
Rôles requis
Pour obtenir les autorisations nécessaires pour créer et gérer des bacs à sable, demandez à votre administrateur de vous attribuer le rôle IAM Administrateur Kubernetes Engine (roles/container.admin) sur votre projet.
Pour en savoir plus sur l'attribution de rôles, consultez Gérer l'accès aux projets, aux dossiers et aux organisations.
Vous pouvez également obtenir les autorisations requises via des rôles personnalisés ou d'autres rôles prédéfinis.
Limites
Dans un cluster régional, les nœuds de différentes zones peuvent avoir des microarchitectures de processeur différentes. Comme les instantanés capturent l'état du processeur, la restauration d'un instantané sur un nœud dont les fonctionnalités de processeur sont manquantes échoue (par exemple, avec l'erreur OCI runtime restore failed: incompatible FeatureSet).
Pour éviter ce problème, utilisez la configuration appropriée pour votre environnement :
- Production : pour préserver la haute disponibilité dans votre cluster, n'épinglez pas les charges de travail à une zone spécifique. Au lieu de cela, assurez-vous de la cohérence des fonctionnalités du processeur dans toutes les zones en spécifiant une configuration minimale de la plate-forme du processeur. Pour en savoir plus, consultez Choisir une configuration minimum de plate-forme de processeur.
- Tests : pour simplifier la configuration et éviter les erreurs initiales d'incompatibilité du processeur, vous
pouvez utiliser un champ
nodeSelectordans votre fichier manifesteSandboxTemplatepour épingler le pod à une zone spécifique, telle queus-central1-a. L'exemple de ce tutoriel utilise cette configuration de test.
Définir des variables d'environnement
Pour simplifier les commandes que vous exécutez dans ce tutoriel, vous pouvez définir des variables d'environnement dans Cloud Shell. Dans Cloud Shell, définissez les variables d'environnement utiles suivantes en exécutant les commandes suivantes :
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 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"
Voici une explication de ces variables d'environnement :
PROJECT_ID: ID de votre projet actuel. Cloud de Confiance by S3NS La définition de cette variable permet de s'assurer que toutes les ressources sont créées dans le bon projet.PROJECT_NUMBER: numéro de votre projet actuel Cloud de Confiance by S3NS .CLUSTER_NAME: nom de votre cluster GKE, par exempletest-snapshot.LOCATION: région dans laquelle se trouvent votre cluster GKE et votre dépôt Artifact Registry, par exempleus-central1. Cloud de Confiance by S3NSBUCKET_LOCATION: emplacement de vos buckets Cloud Storage, par exempleus.BUCKET_NAME: nom du bucket Cloud Storage utilisé pour les instantanés.CLOUDBUILD_BUCKET_NAME: nom du bucket Cloud Storage utilisé pour les journaux Cloud Build.MACHINE_TYPE: type de machine à utiliser pour les nœuds de cluster, par exemplee2-standard-8.REPOSITORY_NAME: nom du dépôt Artifact Registry, par exempleagent-sandbox.
Présentation des étapes de configuration
Pour activer et tester les instantanés de pods des environnements Agent Sandbox depuis votre cluster, vous devez effectuer plusieurs étapes de configuration. Pour comprendre ces étapes, il est utile de commencer par comprendre les composants impliqués dans le workflow global.
Composants clés
Ce tutoriel utilise les deux applications Python suivantes pour tester le processus d'instantané :
- Application cliente : script Python exécuté dans un pod standard de votre
cluster. Cette application gère le cycle de vie du bac à sable : elle crée le bac à sable de manière programmatique, le met en pause pour déclencher un instantané, le reprend et vérifie que l'état a été conservé. Dans ce tutoriel, vous allez créer un compte de service Kubernetes nommé
agent-sandbox-client-saet lui accorder des autorisations RBAC afin que le pod de l'application cliente puisse gérer les ressources personnalisées du bac à sable et les objets de déclenchement d'instantanés à l'aide de l'API Kubernetes. - Application en bac à sable : script Python qui incrémente et affiche un
compteur toutes les secondes. Cette application s'exécute de manière sécurisée dans l'environnement de bac à sable isolé pour générer un état changeant que l'application cliente peut vérifier. Dans ce tutoriel, vous allez créer un compte de service Kubernetes dédié nommé
snapshot-saet configurer Workload Identity pour autoriser le pod en bac à sable à lire et à écrire de manière sécurisée des objets d'instantané dans Cloud Storage.
Processus de configuration et de test
La liste suivante récapitule les étapes à suivre pour configurer votre environnement et exécuter le test :
- Créer un cluster : créez un cluster Autopilot ou Standard avec les instantanés de pods et la fonctionnalité Agent Sandbox activés.
- Créer un dépôt Artifact Registry: créez un dépôt Docker pour stocker l'image de conteneur de votre application cliente.
- Installer Agent Sandbox : installez les composants et extensions principaux d'Agent Sandbox sur votre cluster.
- Configurer le stockage et les autorisations: créez un bucket Cloud Storage et configurez les autorisations Workload Identity pour permettre l'enregistrement sécurisé des instantanés.
- Configurer les instantanés de pods : créez et appliquez la configuration de stockage des instantanés, la règle d'instantané et le modèle de bac à sable.
- Créer l'application cliente : créez l' image de conteneur pour l'application cliente et transmettez-la à votre dépôt Artifact Registry.
- Exécuter le test : déployez le pod de l'application cliente, qui crée le bac à sable, le met en pause pour capturer un instantané, le reprend et vérifie que l'état du compteur a bien été restauré.
Créer un cluster
Créez un cluster GKE avec les instantanés de pods activés. Pour une compatibilité totale des fonctionnalités, spécifiez le version disponible rapide.
Autopilot
Créez un cluster Autopilot avec les fonctionnalités requises :
gcloud beta container clusters create-auto ${CLUSTER_NAME} \
--enable-pod-snapshots \
--release-channel=rapid \
--location=${LOCATION}
Standard
Créez un cluster standard avec les fonctionnalités requises :
gcloud beta 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=${LOCATION}
Créez un pool de nœuds avec gVisor activé :
gcloud container node-pools create gvisor-pool \
--cluster ${CLUSTER_NAME} \
--num-nodes=1 \
--location=${LOCATION} \
--project=${PROJECT_ID} \
--sandbox type=gvisor
Créer un dépôt Artifact Registry
Créez un dépôt Docker dans Artifact Registry pour stocker l'image de conteneur de votre application cliente (l'application qui crée et gère le bac à sable) :
gcloud artifacts repositories create ${REPOSITORY_NAME} \
--repository-format=docker \
--location=${LOCATION} \
--description="Docker repository for Agent Sandbox"
Installer Agent Sandbox
Installez les composants et extensions principaux d'Agent Sandbox sur votre cluster (en utilisant la version v0.4.6 comme exemple) :
# Install the core agent-sandbox components
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/v0.4.6/manifest.yaml
# Install the extensions (e.g., Warm Pools, Claims)
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/v0.4.6/extensions.yaml
Configurer le stockage et les autorisations
Configurez un bucket Cloud Storage pour stocker les instantanés de pods et accordez les autorisations Workload Identity requises au compte de service snapshot-sa et à l'agent de service GKE. Cela permet à vos charges de travail en bac à sable d'enregistrer et de récupérer des objets d'instantané de manière sécurisée :
Créez un bucket Cloud Storage :
gcloud storage buckets create "gs://${BUCKET_NAME}" \ --uniform-bucket-level-access \ --enable-hierarchical-namespace \ --soft-delete-duration=0d \ --location="${BUCKET_LOCATION}"Créez un compte de service Kubernetes dans l'espace de noms
default. Votre application en bac à sable (le script de compteur Python) utilise cette identité pour s'authentifier auprès des API externes et accéder de manière sécurisée aux objets d'instantané stockés dans Cloud Storage :kubectl create serviceaccount "snapshot-sa" \ --namespace "default"Associez le rôle
storage.bucketViewerà votre compte de service à l'aide de Workload Identity. Ce rôle permet à la charge de travail en bac à sable de lister le contenu du bucket et de localiser des instantanés spécifiques :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"Associez le rôle
storage.objectUserà votre compte de service à l'aide de Workload Identity. Ce rôle fournit l'autorisation de lire, d'enregistrer et de supprimer des objets binaires d'instantané dans le 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"Accordez à l'agent de service GKE les autorisations nécessaires pour gérer (créer, lister, lire et supprimer) les objets d'instantané dans le 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"
Configurer les instantanés de pods
Créez et appliquez les fichiers de configuration pour installer les ressources personnalisées Kubernetes requises. Ces ressources définissent comment le cluster stocke et gère les instantanés de pods :
- PodSnapshotStorageConfig : spécifie le bucket Cloud Storage désigné pour stocker les objets binaires d'instantané.
- PodSnapshotPolicy : définit comment les instantanés sont déclenchés manuellement, leur fréquence de regroupement et leurs règles de conservation.
- SandboxTemplate : définit le conteneur sous-jacent, les sélecteurs de nœuds et les comptes de service pour exécuter la charge de travail en bac à sable isolée.
Créez un fichier nommé
test_client/snapshot_storage_config.yaml. Cette configuration spécifie le bucket Cloud Storage cible dans lequel le cluster enregistre l'état binaire de l'instantané de pod :apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotStorageConfig metadata: name: example-pod-snapshot-storage-config spec: snapshotStorageConfig: gcs: bucket: "$BUCKET_NAME"Remplacez l'espace réservé de la variable d'environnement dans le fichier de configuration :
sed -i "s/\$BUCKET_NAME/$BUCKET_NAME/g" test_client/snapshot_storage_config.yamlAppliquez le fichier manifeste de configuration du stockage :
kubectl apply -f test_client/snapshot_storage_config.yamlAttendez que la configuration du stockage soit prête :
kubectl wait --for=condition=Ready podsnapshotstorageconfig/example-pod-snapshot-storage-config --timeout=60sCréez un fichier nommé
test_client/snapshot_policy.yaml. Cette configuration établit une règle de conservation qui conserve un maximum de deux instantanés pour votre charge de travail en bac à sable. Le type de déclencheur est défini surmanual: cela permet à l'application cliente de contrôler les instantanés à la demande :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: 2Appliquez le fichier manifeste de la règle d'instantané :
kubectl apply -f test_client/snapshot_policy.yamlCréez un fichier nommé
test_client/python-counter-template.yaml. Cette configuration définit le pod en bac à sable et lui attribue l'identité du compte de servicesnapshot-sa. Cette attribution permet de garantir que le bac à sable s'exécute de manière sécurisée. Dans ce pod, l'application en bac à sable (un script Python) affiche en continu un compteur incrémentiel dans les journaux du conteneur :apiVersion: extensions.agents.x-k8s.io/v1alpha1 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)Appliquez le fichier manifeste du modèle de bac à sable :
kubectl apply -f test_client/python-counter-template.yaml
Créer l'application cliente
Créez l'image de conteneur pour l'application cliente et transmettez-la à Artifact Registry.
Créez un fichier nommé
test_client/Dockerfile.client. Ce fichier définit l'environnement d'exécution Python et les dépendances de l'application cliente :FROM python:3.13-slim WORKDIR /app RUN pip install "k8s-agent-sandbox[tracing]==0.4.6" # Copy test script COPY client_test.py /app/client_test.py CMD ["python", "/app/client_test.py"]Créez un fichier nommé
test_client/client_test.py. Ce script gère le cycle de vie du bac à sable et vérifie que l'état reprend correctement après la création d'un instantané :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_pod_name(sandbox_id, namespace): custom_api = client.CustomObjectsApi() try: sandbox_cr = custom_api.get_namespaced_custom_object( group="agents.x-k8s.io", version="v1alpha1", namespace=namespace, plural="sandboxes", name=sandbox_id ) metadata = sandbox_cr.get("metadata", {}) annotations = metadata.get("annotations", {}) return annotations.get("agents.x-k8s.io/pod-name") except Exception as e: logging.error(f"Failed to get sandbox CR: {e}") return None def get_current_count(sandbox_id, namespace="default"): pod_name = get_current_pod_name(sandbox_id, namespace) if not pod_name: logging.error(f"Could not determine pod name for sandbox {sandbox_id}") return None return get_last_count(pod_name, 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(template="python-counter-template", 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.sandbox_id) 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.sandbox_id) logging.info(f"Count after resume: {count_after}") verify_continuity(count_before, count_after) logging.info("Snapshot test completed successfully.") if __name__ == "__main__": main()Créez l'image de conteneur client et transmettez-la à Artifact Registry. Si Docker est installé dans votre environnement (tel que Cloud Shell), vous pouvez l'utiliser pour créer l'image en local. Si vous travaillez dans un environnement sans Docker, vous pouvez utiliser Cloud Build pour créer et transmettre l'image à distance :
Docker
Configurez l'authentification Docker pour Artifact Registry :
gcloud auth configure-docker "${LOCATION}-docker.pkg.dev"Créez et transmettez l'image de conteneur client en local :
docker build -t "${LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/sandbox-client:latest" -f test_client/Dockerfile.client test_client docker push "${LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/sandbox-client:latest"
Cloud Build
Créez un fichier nommé
test_client/cloudbuild.yaml:steps: - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', '$LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY_NAME/sandbox-client:latest', '-f', 'test_client/Dockerfile.client', 'test_client'] images: - '$LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY_NAME/sandbox-client:latest'Remplacez les espaces réservés des variable d'environnement dans le fichier de configuration :
sed -i "s/\$REPOSITORY_NAME/$REPOSITORY_NAME/g" test_client/cloudbuild.yaml sed -i "s/\$LOCATION/$LOCATION/g" test_client/cloudbuild.yaml sed -i "s/\$PROJECT_ID/$PROJECT_ID/g" test_client/cloudbuild.yamlAccordez les autorisations nécessaires au compte de service Cloud Build :
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/artifactregistry.writer" gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/logging.logWriter" gcloud storage buckets add-iam-policy-binding "gs://$CLOUDBUILD_BUCKET_NAME" \ --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/storage.objectAdmin"Exécutez la compilation à l'aide de Cloud Build :
gcloud builds submit --config test_client/cloudbuild.yaml
Exécuter le test
Déployez l'application cliente pour créer le bac à sable, déclencher un instantané et vérifier que le compteur interne reprend correctement à partir de son état enregistré.
Créez un fichier nommé
test_client/client_sa.yaml. Ce fichier manifeste définit le compte de serviceagent-sandbox-client-saet les autorisations RBAC requises pour gérer les ressources personnalisées du bac à sable :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.ioAppliquez le fichier manifeste du compte de service client et de RBAC :
kubectl apply -f test_client/client_sa.yamlCréez un fichier nommé
test_client/client_pod.yaml. Ce fichier manifeste crée le pod de l'application cliente à l'aide de l'image de conteneur prédéfinie :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: NeverRemplacez les espaces réservés des variable d'environnement dans le fichier manifeste :
sed -i "s/\$REPOSITORY_NAME/$REPOSITORY_NAME/g" test_client/client_pod.yaml sed -i "s/\$LOCATION/$LOCATION/g" test_client/client_pod.yaml sed -i "s/\$PROJECT_ID/$PROJECT_ID/g" test_client/client_pod.yamlAppliquez le fichier manifeste du pod de l'application cliente :
kubectl apply -f test_client/client_pod.yamlDiffusez les journaux du pod pour vérifier le flux d'exécution :
kubectl logs -f agent-sandbox-client-pod
Lorsque le test s'exécute correctement, le résultat ressemble à ceci (raccourci ici pour plus de lisibilité) :
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).
Le résultat indique que le bac à sable conserve correctement son état lorsqu'il est suspendu et repris. Le compteur cesse d'avancer lorsque le bac à sable est suspendu (mis en pause et mis à l'échelle à zéro), et reprend le compteur lorsque le bac à sable est restauré. Sans suspension, le compteur aurait continué à avancer pendant la période de suspension et le nombre serait beaucoup plus élevé.
Effectuer un nettoyage des ressources
Pour éviter que des frais ne soient facturés sur votre Cloud de Confiance by S3NS compte, supprimez les ressources que vous avez créées :
Supprimez le cluster GKE. Cette opération supprime également le pool de nœuds et tous les comptes de service Kubernetes qu'il contient :
gcloud beta container clusters delete test-snapshot --location="${LOCATION}" --quietSupprimez le dépôt Artifact Registry pour supprimer le dépôt Docker que vous avez créé pour l'image de test :
gcloud artifacts repositories delete ${REPOSITORY_NAME} --location="${LOCATION}" --quietSupprimez le bucket Cloud Storage et tous les instantanés qu'il contient. Cette opération supprime automatiquement les liaisons IAM Workload Identity au niveau du bucket qui lui sont appliquées :
gcloud storage rm --recursive "gs://${BUCKET_NAME}"Supprimez la liaison IAM au niveau du projet pour l'agent de service GKE :
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"Si vous avez utilisé Cloud Build au lieu de Docker pour créer et transmettre l'image de conteneur, supprimez le bucket de journaux et supprimez les autorisations du compte de service :
gcloud storage rm --recursive "gs://${CLOUDBUILD_BUCKET_NAME}" gcloud projects remove-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/artifactregistry.writer" gcloud projects remove-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/logging.logWriter"
Étape suivante
- Découvrez comment isoler l'exécution du code d'IA : déclencheur externe.
- Découvrez comment enregistrer et restaurer des environnements Agent Sandbox.
- Pour comprendre les couches d'isolation qui protègent vos charges de travail non approuvées, consultez GKE Sandbox.
- Explorez le projet Open Source Agent Sandbox sur GitHub.