Isolare l'esecuzione del codice AI con Agent Sandbox

Puoi eseguire il deployment di un ambiente di sviluppo per utilizzare il client Python di Agent Sandbox in un cluster Google Kubernetes Engine (GKE). Questa configurazione ti aiuta a eseguire e testare in modo sicuro il codice generato dall'AI isolando il codice non attendibile all'interno di un ambiente Python in sandbox. Questo isolamento è fondamentale per proteggere il sistema da potenziali vulnerabilità nel codice generato dall'AI, aumentare la velocità di sviluppo e garantire implementazioni sicure. Per una panoramica di come la funzionalità Agent Sandbox isola il codice non attendibile generato con l'AI, consulta Informazioni su GKE Agent Sandbox.

Costi

Agent Sandbox è offerto senza costi aggiuntivi in GKE. I prezzi di GKE si applicano alle risorse che crei.

Prima di iniziare

  1. Nella console Cloud de Confiance , nella pagina di selezione del progetto, seleziona o crea un progetto Cloud de Confiance .

    Ruoli richiesti per selezionare o creare un progetto

    • Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per il quale ti è stato concesso un ruolo.
    • Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto (roles/resourcemanager.projectCreator), che contiene l'autorizzazione resourcemanager.projects.create. Scopri come concedere i ruoli.

    Vai al selettore di progetti

  2. Verifica che la fatturazione sia attivata per il tuo progetto Cloud de Confiance .

  3. Abilita le API Artifact Registry e Kubernetes Engine.

    Ruoli richiesti per abilitare le API

    Per abilitare le API, devi disporre del ruolo IAM Amministratore utilizzo dei servizi (roles/serviceusage.serviceUsageAdmin), che include l'autorizzazione serviceusage.services.enable. Scopri come concedere i ruoli.

    Abilita le API

  4. Nella console Cloud de Confiance , attiva Cloud Shell.

    Attiva Cloud Shell

  5. Verifica di disporre delle autorizzazioni necessarie per completare questa guida.
  6. Devi avere un cluster GKE con la funzionalità Agent Sandbox abilitata. Se non ne hai uno, segui le istruzioni riportate in Abilitare Agent Sandbox su GKE per creare un nuovo cluster o aggiornarne uno esistente.

Ruoli obbligatori

Per ottenere le autorizzazioni necessarie per creare e gestire sandbox, chiedi all'amministratore di concederti il ruolo IAM Kubernetes Engine Admin (roles/container.admin) nel progetto. Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.

Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

Definisci le variabili di ambiente

Per semplificare i comandi eseguiti in questo documento, puoi impostare le variabili di ambiente in Cloud Shell. In Cloud Shell, definisci le seguenti variabili di ambiente utili eseguendo questi comandi:

export PROJECT_ID=$(gcloud config get project)
export CLUSTER_NAME="agent-sandbox-cluster"
export LOCATION="us-central1"
export NODE_POOL_NAME="agent-sandbox-node-pool"
export MACHINE_TYPE="e2-standard-2"

Ecco una spiegazione di queste variabili di ambiente:

  • PROJECT_ID: l'ID del tuo progetto Cloud de Confiance by S3NS corrente. La definizione di questa variabile consente di garantire che tutte le risorse, come il cluster GKE, vengano create nel progetto corretto.
  • CLUSTER_NAME: il nome del cluster GKE, ad esempio agent-sandbox-cluster.
  • LOCATION: la Cloud de Confiance by S3NS regione o la zona in cui si trova il cluster GKE. Imposta questo valore sulla regione (ad esempio, us-central1) se utilizzi un cluster Autopilot o sulla zona (ad esempio, us-central1-a) se utilizzi un cluster Standard.
  • NODE_POOL_NAME: il nome del pool di nodi che eseguirà i carichi di lavoro in sandbox, ad esempio agent-sandbox-node-pool.
  • MACHINE_TYPE: il tipo di macchina dei nodi nel pool di nodi, ad esempio e2-standard-2. Per informazioni dettagliate sulle diverse serie di macchine e sulla scelta tra le diverse opzioni, consulta la guida alle risorse e al confronto per le famiglie di macchine.

Esegui il deployment di un ambiente sandbox

Questa sezione mostra come creare il blueprint della sandbox (SandboxTemplate), eseguire il deployment del router di rete necessario e installare il client Python che utilizzerai per interagire con la sandbox.

Il modo consigliato per creare e interagire con la sandbox è utilizzare il client Python Agentic Sandbox. Questo client fornisce un'interfaccia che semplifica l'intero ciclo di vita di una sandbox, dalla creazione alla pulizia. È una libreria Python che puoi utilizzare per creare, utilizzare ed eliminare sandbox in modo programmatico.

Il client utilizza un router sandbox come punto di accesso centrale per tutto il traffico. Nell'esempio descritto in questo documento, il client crea un tunnel a questo router utilizzando il comando kubectl port-forward, in modo da non dover esporre indirizzi IP pubblici. Tieni presente che l'utilizzo di kubectl port-forward non è una soluzione sicura e il suo utilizzo deve essere limitato agli ambienti di sviluppo.

Crea un SandboxTemplate e un SandboxWarmPool

Ora definisci la configurazione per il tuo sandbox creando una risorsa SandboxTemplate e una risorsa SandboxWarmPool. SandboxTemplate funge da progetto riutilizzabile che il controller della sandbox dell'agente utilizza per creare ambienti sandbox coerenti e preconfigurati. La risorsa SandboxWarmPool contribuisce a garantire che un numero specificato di pod pre-warmed sia sempre in esecuzione e pronto per essere rivendicato. Un sandbox pre-riscaldato è un pod in esecuzione già inizializzato. Questa pre-inizializzazione consente di creare nuove sandbox in meno di un secondo ed evita la latenza di avvio di una sandbox normale:

  1. In Cloud Shell, crea un file denominato sandbox-template-and-pool.yaml con il seguente contenuto:

    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxTemplate
    metadata:
      name: python-runtime-template
      namespace: default
    spec:
      podTemplate:
        metadata:
          labels:
            sandbox: python-sandbox-example
        spec:
          runtimeClassName: gvisor
          automountServiceAccountToken: false # Required
          securityContext:
            runAsNonRoot: true # Required
          nodeSelector:
            sandbox.gke.io/runtime: gvisor # Required
          tolerations:
          - key: "sandbox.gke.io/runtime"
            value: "gvisor"
            effect: "NoSchedule" # Required
          containers:
          - name: python-runtime
            image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0
            ports:
            - containerPort: 8888
            readinessProbe:
              httpGet:
                path: "/"
                port: 8888
              initialDelaySeconds: 0
              periodSeconds: 1
            resources:
              requests:
                cpu: "250m"
                memory: "512Mi"
              limits:
                cpu: "500m"
                memory: "1Gi" # Required
            securityContext:
              capabilities:
                drop: ["ALL"] # Required
          restartPolicy: "OnFailure"
    ---
    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxWarmPool
    metadata:
      name: python-sandbox-warmpool
      namespace: default
    spec:
      replicas: 2
      sandboxTemplateRef:
        name: python-runtime-template
    
  2. Applica il manifest SandboxTemplate e SandboxWarmPool:

    kubectl apply -f sandbox-template-and-pool.yaml
    

Esegui il deployment del router sandbox

Il client Python che utilizzerai per creare e interagire con gli ambienti sandbox utilizza un componente chiamato router sandbox per comunicare con le sandbox.

Per questo esempio, utilizzi la modalità sviluppatore del client per i test. Questa modalità è pensata per lo sviluppo locale e utilizza il comando kubectl port-forward per stabilire un tunnel diretto dalla tua macchina locale al servizio Sandbox Router in esecuzione nel cluster. Questo approccio di tunneling evita la necessità di un indirizzo IP pubblico o di una configurazione di ingresso complessa e semplifica l'interazione con le sandbox dal tuo ambiente locale.

Segui questi passaggi per eseguire il deployment del router sandbox:

  1. In Cloud Shell, crea un file denominato sandbox-router.yaml con il seguente contenuto:

    # A ClusterIP Service to provide a stable endpoint for the router pods.
    apiVersion: v1
    kind: Service
    metadata:
      name: sandbox-router-svc
      namespace: default
    spec:
      type: ClusterIP
      selector:
        app: sandbox-router
      ports:
      - name: http
        protocol: TCP
        port: 8080 # The port the service will listen on
        targetPort: 8080 # The port the router container listens on (from the sandbox_router/Dockerfile)
    ---
    # The Deployment to manage and run the router pods.
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sandbox-router-deployment
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sandbox-router
      template:
        metadata:
          labels:
            app: sandbox-router
        spec:
          # Ensure pods are spread across different zones for HA
          topologySpreadConstraints:
            - maxSkew: 1
              topologyKey: topology.kubernetes.io/zone
              whenUnsatisfiable: ScheduleAnyway
              labelSelector:
                matchLabels:
                  app: sandbox-router
          containers:
          - name: router
            image: us-central1-docker.pkg.dev/k8s-staging-images/agent-sandbox/sandbox-router:latest-main
            ports:
            - containerPort: 8080
            readinessProbe:
              httpGet:
                path: /healthz
                port: 8080
              initialDelaySeconds: 5
              periodSeconds: 5
            livenessProbe:
              httpGet:
                path: /healthz
                port: 8080
              initialDelaySeconds: 10
              periodSeconds: 10
            resources:
              requests:
                cpu: "100m"
                memory: "512Mi"
              limits:
                cpu: "1000m"
                memory: "1Gi"
          securityContext:
            runAsUser: 1000
            runAsGroup: 1000
    
  2. Applica il manifest per eseguire il deployment del router nel tuo cluster:

    kubectl apply -f sandbox-router.yaml
    
  3. Verifica che il deployment del router sandbox sia in esecuzione correttamente:

    kubectl get deployment sandbox-router-deployment
    

    Attendi che il deployment mostri 2/2 o 1/1 nella colonna READY.

Installa il client Python

Ora che i componenti in-cluster come il router sandbox sono implementati, l'ultimo passaggio preparatorio consiste nell'installare il client Python di Agentic Sandbox sulla tua macchina locale. Ricorda che questo client è una libreria Python che ti consente di creare, utilizzare ed eliminare sandbox in modo programmatico. Lo utilizzerai nella sezione successiva per testare l'ambiente:

  1. Crea e attiva un ambiente virtuale Python:

    python3 -m venv .venv
    source .venv/bin/activate
    
  2. Installa il pacchetto client:

    pip install k8s-agent-sandbox
    

Testare la sandbox

Con tutti i componenti di configurazione in posizione, ora puoi creare e interagire con una sandbox utilizzando il client Python Agentic Sandbox.

  1. Nella directory agent-sandbox, crea uno script Python denominato test_sandbox.py con il seguente contenuto:

    from k8s_agent_sandbox import SandboxClient
    from k8s_agent_sandbox.models import SandboxLocalTunnelConnectionConfig
    
    # Automatically tunnels to svc/sandbox-router-svc
    client = SandboxClient(
        connection_config=SandboxLocalTunnelConnectionConfig()
    )
    
    sandbox = client.create_sandbox(template="python-runtime-template", namespace="default")
    try:
        print(sandbox.commands.run("echo 'Hello from the sandboxed environment!'").stdout)
    except Exception as e:
        print(f"An error occurred: {e}")
    
  2. Dal terminale (con l'ambiente virtuale ancora attivo), esegui lo script di test:

    python3 test_sandbox.py
    

Dovresti vedere il messaggio "Hello from the sandboxed environment!" (Ciao dall'ambiente sandbox!), che è l'output della sandbox.

Complimenti! Hai eseguito correttamente un comando shell all'interno di una sandbox sicura. Utilizzando il metodo sandbox.run(), puoi eseguire qualsiasi comando shell e la sandbox dell'agente esegue il comando all'interno di una barriera sicura che protegge i nodi del cluster e altri carichi di lavoro da codice non attendibile. In questo modo, un agente AI o qualsiasi workflow automatizzato può eseguire le attività in modo sicuro e affidabile.

Quando esegui lo script, SandboxClient gestisce tutti i passaggi per te. Crea la risorsa SandboxClaim per avviare la sandbox, attende che sia pronta e poi utilizza il metodo sandbox.run() per eseguire i comandi della shell bash all'interno del container sicuro. Il client acquisisce e stampa quindi il stdout da questo comando. La sandbox viene eliminata automaticamente dopo l'esecuzione del programma.

Quando viene creata una risorsa SandboxClaim, viene assegnato un pod disponibile dal pool caldo all'oggetto Sandbox e la richiesta viene contrassegnata come pronta. Il SandboxWarmPool si ripristina automaticamente per mantenere il numero di repliche configurato.

Per verificare se una sandbox specifica è rivendicata o disponibile, controlla ownerReferences nei metadati del pod sandbox. Se il valore del campo kind è Sandbox, il pod è in uso. Se il valore del campo kind è SandboxWarmPool, il pod è inattivo e in attesa di essere rivendicato.

Esegui sandbox in produzione

In questo documento, interagisci con le sandbox dall'esterno del cluster utilizzando Cloud Shell. Il client Python utilizza le credenziali utente per autenticarsi al cluster e gestire le risorse sandbox e utilizza il comando kubectl port-forward per stabilire una connessione con le sandbox. Questi passaggi sono ideali per gli scenari di sviluppo.

In uno scenario di produzione, un'applicazione controller (come un orchestratore AI) è responsabile della creazione e della gestione delle risorse sandbox. Per utilizzare la sandbox dell'agente in produzione, tieni presente quanto segue:

  • Autenticazione: l'applicazione controller deve autenticarsi nel server dell'API cluster per eseguire le sandbox. La configurazione dell'autenticazione dipende da dove viene eseguita l'applicazione controller, come segue:

    • Se l'applicazione controller viene eseguita come pod nello stesso cluster, utilizza RBAC Kubernetes o Workload Identity Federation for GKE con i criteri IAM per concedere all'account di servizio Kubernetes del pod le autorizzazioni necessarie per monitorare le sandbox o rilevare gli endpoint di rete.
    • Se l'applicazione controller viene eseguita al di fuori del cluster, utilizza Workload Identity Federation o i service account IAM per assegnare all'applicazione un'identità a cui puoi fare riferimento nelle policy di autorizzazione.
  • Routing: le richieste del client Python nell'applicazione controller devono raggiungere il router sandbox nel cluster. In produzione, utilizza uno dei seguenti metodi per stabilire una connessione di rete:

    • Se l'applicazione controller viene eseguita nello stesso cluster, utilizza la funzione SandboxDirectConnectionConfig per scegliere come target l'URL e la porta utilizzati dal servizio Sandbox Router.
    • Se l'applicazione controller viene eseguita al di fuori del cluster, utilizza l'API GKE Gateway per creare un bilanciatore del carico interno o esterno. Nel codice client, utilizza la funzione SandboxGatewayConnectionConfig per fare riferimento al tuo gateway.

    Per maggiori informazioni su questi metodi di routing, consulta gli esempi di utilizzo su GitHub e i passaggi di deployment del gateway per il router.

  • Accesso alla sandbox alle risorse: se il codice sandbox deve inviare richieste alle API Cloud de Confiance , ad esempio Cloud Storage, utilizza un criterio IAM con Workload Identity Federation for GKE per concedere al service account Kubernetes utilizzato dal pod sandbox le autorizzazioni necessarie per l'accesso. Cloud de Confiance Poiché la policy di rete predefinita blocca l'accesso al server di metadati (169.254.169.254), devi personalizzare la policy di rete per consentire questo traffico. Cloud de Confiance by S3NS

  • Limitazioni dei criteri di rete: per impostazione predefinita, Agent Sandbox applica una postura di rete sicura per impostazione predefinita (networkPolicyManagement: Managed). A questa postura si applicano le seguenti limitazioni:

    • L'ingresso è bloccato da tutte le origini tranne il router sandbox designato.
    • L'uscita è consentita a internet pubblico, ma l'uscita verso intervalli LAN privati (RFC 1918), DNS del cluster interno (CoreDNS) e il server dei metadati del provider di servizi cloud (169.254.0.0/16) è esplicitamente bloccata.

    Per utilizzare Workload Identity Federation for GKE o accedere ad altre risorse private, devi definire policy di rete personalizzate in SandboxTemplate. Per informazioni dettagliate sulla configurazione e modelli personalizzabili (come sandbox air-gap o integrazione di Workload Identity Federation for GKE), vedi Gestione delle norme di rete della sandbox dell'agente.

Norme di sicurezza della sandbox

Per contribuire a garantire un ambiente sicuro per impostazione predefinita, il componente aggiuntivo Sandbox dell'agente GKE utilizza i criteri di controllo dell'ammissione di Kubernetes (VAP) per applicare i vincoli di sicurezza alle risorse Sandbox e SandboxTemplate. Questi criteri vengono applicati automaticamente.

Il componente aggiuntivo divide l'applicazione della sicurezza in un modello di criteri a due livelli per una maggiore flessibilità. Le sezioni seguenti descrivono queste policy: la policy di base rigorosamente gestita e la policy di hardening personalizzabile.

Policy di sicurezza di base (sandbox-core-policy)

Il criterio di sicurezza principale applica i requisiti di isolamento che contribuiscono a proteggere l'integrità della sandbox. Questa policy include regole che richiedono l'utilizzo di gVisor, l'isolamento di rete, ad esempio la disattivazione di hostNetwork, e l'isolamento del file system, ad esempio il blocco di hostPath. Poiché GKE gestisce questo criterio tramite l'impostazione addonmanager.kubernetes.io/mode: Reconcile, non puoi modificare o eseguire l'override di queste regole di base.

Policy di sicurezza di hardening (sandbox-hardening-policy)

La policy di sicurezza di hardening fornisce ulteriori best practice per la sicurezza e opzioni di gestione. Applica vincoli come l'eliminazione di tutte le funzionalità, impedisce l'aggiunta di nuove funzionalità e richiede che i container vengano eseguiti come non root con limiti di risorse. GKE implementa questo criterio in modalità EnsureExists tramite l'impostazione addonmanager.kubernetes.io/mode: EnsureExists. Questa impostazione indica che GKE crea la policy se non è presente, ma puoi modificare o eliminare la policy o il relativo binding, se necessario.

Modificare o rimuovere i vincoli di hardening

Poiché il criterio di hardening viene implementato in modalità EnsureExists, GKE crea il criterio se non è presente, ma non sovrascrive le tue modifiche. Se i tuoi workload richiedono esenzioni da queste regole di hardening, puoi modificare la policy per rimuovere vincoli specifici o eliminare completamente l'associazione della policy.

Per modificare la policy di hardening e rimuovere un vincolo specifico (ad esempio, per consentire l'esecuzione dei container come root o omettere i limiti delle risorse), modifica la risorsa ValidatingAdmissionPolicy:

kubectl edit validatingadmissionpolicy sandbox-hardening-policy

Nell'editor di testo che si apre, individua la sezione validations e rimuovi o modifica l'espressione di vincolo che blocca il tuo workload.

In alternativa, se vuoi disattivare completamente la norma di hardening per il tuo cluster, elimina l'associazione della norma:

kubectl delete validatingadmissionpolicybinding sandbox-hardening-binding

Problemi noti

Questa sezione descrive i problemi noti durante l'utilizzo di Agent Sandbox in GKE e come risolverli o aggirarli.

La policy di sicurezza blocca le funzionalità quando utilizzi un mesh di servizi

Se tenti di eseguire il deployment di una sandbox che si integra con un file collaterale della rete mesh di servizi (ad esempio Envoy o Istio), la creazione della sandbox potrebbe essere bloccata dalla policy di sicurezza di hardening con un errore simile al seguente:

sandbox create error: sandboxes.agents.x-k8s.io "claude-cli-claim-managed" is forbidden:
ValidatingAdmissionPolicy 'sandbox-hardening-policy' with binding 'sandbox-hardening-binding'
denied request: Security Violation: Capabilities.add must be empty. You cannot add capabilities.
  • Causa: i sidecar di service mesh spesso utilizzano un container init, ad esempio istio-init o proxy-init. Questi container di inizializzazione richiedono funzionalità come NET_ADMIN o NET_RAW per configurare le regole iptables per il routing di uscita trasparente. Per impostazione predefinita, sandbox-hardening-policy di GKE blocca tutte le aggiunte di funzionalità in tutti i tipi di container.
  • Soluzione alternativa: poiché il criterio di hardening di GKE viene implementato in modalità EnsureExists, puoi modificare ValidatingAdmissionPolicy per consentire a specifici init container attendibili di richiedere le funzionalità NET_ADMIN e NET_RAW. Per istruzioni su come modificare o rimuovere questi vincoli di hardening, consulta Modificare o rimuovere i vincoli di hardening. Ad esempio, puoi aggiornare le espressioni di convalida o le variabili della policy per esentare i nomi dei container attendibili dalla regola delle funzionalità.

Latenza in uscita o timeout durante la connessione alle API di Google tramite IPv6

I carichi di lavoro all'interno della sandbox potrebbero riscontrare timeout di connessione o latenza elevata, fino a due minuti, quando tentano di connettersi a risorse esterne o alle API di Google (come Vertex AI o Cloud Storage).

  • Causa: se il cluster GKE ha IPv6 dual-stack abilitato, la risoluzione DNS per le API di Google restituisce indirizzi IPv4 (A) e IPv6 (AAAA). Alcuni algoritmi nei motori di runtime, come Node.js, tentano di connettersi prima tramite IPv6. Se il tuo VPC GKE non ha una route di uscita IPv6 valida, ad esempio un gateway Cloud NAT o internet per IPv6, la connessione TCP smette di rispondere (per saperne di più, consulta https://developers.google.com/style/word-list#hang) fino alla scadenza del timeout TCP SYN. Quindi, la connessione TCP torna a IPv4.
  • Soluzione: per risolvere il problema, esegui una delle seguenti operazioni:

    • Configura l'uscita IPv6: per consentire al traffico IPv6 in uscita di tornare al cluster, configura un gateway Cloud NAT o internet IPv6 valido nella tua rete VPC.
    • Preferisci IPv4 nel workload: per preferire la risoluzione DNS IPv4, configura il runtime del workload. Ad esempio, in un'applicazione Node.js, puoi impostare le seguenti variabili di ambiente nella definizione di SandboxTemplate:

      env:
      - name: NODE_OPTIONS
        value: "--dns-result-order=ipv4first --no-network-family-autoselection"
      

Esegui la pulizia delle risorse

Per evitare che al tuo account Cloud de Confiance by S3NS vengano addebitati costi, devi eliminare il cluster GKE che hai creato:

gcloud container clusters delete $CLUSTER_NAME --location=$LOCATION --quiet

Passaggi successivi