Esecuzione del codice in Cloud Run

Le sandbox di Cloud Run ti consentono di eseguire codice non attendibile in un ambiente isolato direttamente all'interno dei workload dei container. Questa funzionalità aiuta gli agenti AI a eseguire in sicurezza sub-agenti, attività di calcolo o browser automatizzati senza rischiare di compromettere il sistema host.

Principali vantaggi

Le sandbox di Cloud Run offrono i seguenti vantaggi principali:

  • Creazione rapida: le sandbox sono interattive e pronte per eseguire i comandi quasi istantaneamente. Creando sandbox all'interno di una risorsa Cloud Run esistente in cui viene eseguito l'agente, riduci i tempi di creazione rispetto alla creazione di una nuova risorsa Cloud Run per ogni attività. Questa efficienza contribuisce a garantire che l'agente rimanga reattivo.

  • Sicurezza: le sandbox isolano l'esecuzione dei processi. Per impostazione predefinita, le sandbox non hanno accesso al workload principale, alle variabili di ambiente, ai secret o al server di metadati Google Cloud . Tutte le sandbox sono completamente isolate tra loro.

  • Controllo degli accessi e ambiente: i processi vengono eseguiti con privilegi sudo come utente non root, consentendoti di installare strumenti utilizzando gestori di pacchetti come apt, pip o npm durante l'esecuzione. Sebbene l'ambiente sandbox sia temporaneo e venga eliminato al termine, puoi utilizzare directory persistenti o snapshot per salvare aree di lavoro specifiche o mappare i dati a un bucket Cloud Storage.

Prima di iniziare

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. Verify that billing is enabled for your Google Cloud project.

  3. Installa e inizializza gcloud CLI.
  4. Esegui il deployment di una risorsa Cloud Run, ad esempio un servizio, un job, un pool di worker o un'istanza di seconda generazione .

Abilita le sandbox

Per utilizzare le sandbox, devi prima abilitarle nella risorsa Cloud Run utilizzando il flag --sandbox-launcher o l'attributo YAML sandboxLauncher. Per i passaggi di configurazione dettagliati, scegli uno dei seguenti tipi di risorse:

Avvia sandbox

Una volta attivate le sandbox, puoi avviarle dall'ambiente di esecuzione del container. Il file binario della sandbox si trova in /usr/local/gcp/bin/sandbox.

Gli esempi in questa guida utilizzano il comando sandbox anziché il percorso assoluto /usr/local/gcp/bin/sandbox.

Puoi eseguire il file binario facendo riferimento al suo percorso assoluto nel codice sorgente. Ad esempio, per stampare Hello all'interno della sandbox isolata, scegli una delle seguenti opzioni:

Node.js

Per eseguire il comando sandbox da un'applicazione Node.js, includi il seguente codice:

exec(`sandbox do -- /bin/echo "Hello"`, (e, stdout, stderr) => {
    res.send({ stdout, stderr });
});

Python

Per eseguire il comando sandbox da un'applicazione Python, includi il seguente codice:

import subprocess
result = subprocess.run(
    ["sandbox", "do", "--", "/bin/echo", "Hello"],
    capture_output=True,
    text=True,
)
return {"stdout": result.stdout, "stderr": result.stderr}

Vai

Per eseguire il comando sandbox da un'applicazione Go, includi il seguente codice:

cmd := exec.Command("sandbox", "do", "--", "/bin/echo", "Hello")
out, err := cmd.CombinedOutput()

Interfaccia a riga di comando di Sandbox

Per eseguire il comando sandbox direttamente dalla riga di comando, esegui questo comando:

sandbox do -- /bin/echo "Hello"

Per visualizzare l'elenco completo dei comandi disponibili, esegui il comando sandbox -h.

Utilizza le funzionalità della riga di comando della sandbox

Lo strumento a riga di comando sandbox contiene i comandi per eseguire, configurare e gestire le sandbox.

Esegui un comando nella sandbox

Puoi eseguire un'istruzione in una nuova sandbox temporanea utilizzando il comando sandbox do. Il comando sandbox do esegue le seguenti attività:

  1. Avvia un ambiente sandbox (sandbox run).
  2. Esegue il comando specificato (sandbox exec).
  3. Elimina la sandbox dopo l'esecuzione riuscita (sandbox delete).

Ad esempio, per eseguire un calcolo matematico all'interno della sandbox, esegui i seguenti snippet di codice per il linguaggio che preferisci. Assicurati che tutti i comandi o gli strumenti che esegui, ad esempio python3, siano installati nell'immagine container:

Node.js

Per eseguire il comando sandbox da un'applicazione Node.js:

exec(`sandbox do -- /usr/bin/python3 -c "print(1+2)"`, (e, stdout, stderr) => {
    res.send({ stdout, stderr });
});

Python

Per eseguire il comando sandbox da un'applicazione Python:

import subprocess
result = subprocess.run(
    ["sandbox", "do", "--", "/usr/bin/python3", "-c", "print(1+2)"],
    capture_output=True,
    text=True,
)
return {"stdout": result.stdout, "stderr": result.stderr}

Vai

Per eseguire il comando sandbox da un'applicazione Go:

cmd := exec.Command("sandbox", "do", "--", "/usr/bin/python3", "-c", "print(1+2)")
out, err := cmd.CombinedOutput()

Interfaccia a riga di comando di Sandbox

Per eseguire il comando sandbox direttamente dalla riga di comando:

sandbox do -- /usr/bin/python3 -c "print(1+2)"

Se esegui un comando per nome senza il relativo percorso assoluto, ad esempio python3 anziché /usr/bin/python3, configura in modo esplicito la variabile di ambiente PATH nella sandbox utilizzando il flag --env.

Rendere persistenti i dati tra diverse esecuzioni

Le sandbox sono temporanee per impostazione predefinita. Per rendere persistenti i dati tra diverse esecuzioni della sandbox all'interno della stessa istanza Cloud Run, puoi importare ed esportare lo stato del file system dell'area di lavoro utilizzando file di archivio tar standard. In alternativa, puoi configurare i punti di montaggio per condividere le directory direttamente tra il container host e gli ambienti sandbox.

Utilizza i seguenti flag quando esegui il comando sandbox do:

  • --export-tar: acquisisce i file di overlay modificati in un file di archivio tar al termine.
  • --import-tar: estrae i file da un file di archivio tar nella sandbox prima dell'esecuzione.
  • --sync-tar: esegue una sincronizzazione bidirezionale importando prima dell'esecuzione ed esportando al termine.

La directory /tmp all'interno della sandbox non fa parte dell'overlay del file system principale, pertanto i file di archivio non includono i file scritti in /tmp. Per rendere persistenti i dati, scrivili in una directory diversa, ad esempio /workspace.

Ad esempio, per passare dati tra due chiamate alla sandbox utilizzando file di archivio, esegui questi comandi:

  1. Scrivi i dati all'interno di una sandbox ed esporta lo stato in un file di archivio:

    sandbox do --write --export-tar=/tmp/work.tar \
      -- /usr/bin/bash -c "mkdir -p /workspace && echo 'task-complete' > /workspace/status.txt"
    
  2. Importa il file di archivio in una chiamata successiva per recuperare i dati:

    sandbox do --write --import-tar=/tmp/work.tar \
      -- /usr/bin/bash -c "cat /workspace/status.txt"
    

In alternativa, per importare automaticamente lo stato dell'archivio esistente ed esportare le nuove modifiche in un unico comando, utilizza --sync-tar=/tmp/work.tar. Quando un processo di sandbox termina, Cloud Run elimina definitivamente i file di overlay temporanei che non sono stati esportati in un file di archivio.

Esegui un comando in background

Per eseguire processi a lunga esecuzione, browser headless o server in background, come un loop dell'agente in background che ascolta continuamente le richieste in entrata, utilizza il flag --detach.

Ad esempio, esegui questo comando per avviare una sandbox scollegata con un programma inattivo o in background:

sandbox run my-web-server --detach -- /usr/bin/long_running_or_idle_program

Puoi utilizzare il flag detach per riutilizzare la stessa sandbox per più test. Per interagire con una sandbox scollegata in esecuzione o eseguire altri comandi al suo interno, utilizza il comando sandbox exec e scegli come target la sandbox in base al nome.

Ad esempio, per eseguire un comando di test all'interno della sandbox in background my-web-server esistente, esegui questo comando:

sandbox exec my-web-server -- /usr/bin/python3 -c "print('test-complete')"

Configura le variabili di ambiente

Configura le variabili di ambiente nelle sandbox come faresti con qualsiasi altro container. Le sandbox non ereditano le variabili di ambiente dal container host. Devi fornirli esplicitamente utilizzando il flag --env quando esegui il comando sandbox.

Ad esempio, per passare una variabile di configurazione a una sandbox, esegui questo comando:

sandbox do --env AGENT_MODE="test" -- /usr/bin/bash -c "echo \$AGENT_MODE"

Evita di passare i secret utilizzando il flag env, poiché potrebbero essere visibili ai processi della sandbox.

Crea snapshot del file system

Esegui il deployment di una sandbox denominata in background per gestire attività continue come server web o Agentic Workflows a lunga esecuzione, esegui comandi sulla sandbox in modo dinamico e acquisisci lo stato del file system modificato in un file di archivio tar.

Ad esempio, per eseguire il deployment di una sandbox in background, scrivere un file nel relativo overlay e acquisire uno snapshot del suo stato per verificare che i dati siano stati acquisiti, esegui questi comandi:

  1. Esegui il deployment di una sandbox denominata in background con l'accesso in scrittura abilitato, creando un file all'interno del relativo workspace. Scrivi il file in un percorso esterno a /tmp, perché i file scritti in /tmp all'interno della sandbox non vengono acquisiti negli snapshot:

    sandbox run --write my-sandbox --detach -- /usr/bin/bash -c "echo 'hi' > /workspace/hello.txt && sleep 1h"
    
  2. Crea uno snapshot del file system modificato della sandbox in esecuzione utilizzando il comando sandbox tar:

    sandbox tar my-sandbox --file=/tmp/foo.tar
    
  3. Estrai e verifica che il file di archivio dello snapshot contenga i dati scritti all'interno della sandbox:

    tar -xvf /tmp/foo.tar
    

    Dovresti vedere i seguenti risultati:

    ./
    ./workspace/
    ./workspace/hello.txt
    

Configura il networking

Per impostazione predefinita, tutto il traffico in uscita dalla sandbox è bloccato. Per consentire l'accesso alla rete in uscita, utilizza il flag --allow-egress:

Ad esempio, per recuperare i dati da un endpoint esterno, esegui questo comando:

sandbox do --allow-egress -- /usr/bin/python3 -c 'import urllib.request; print(urllib.request.urlopen("https://google.com").getcode())'

Questo comando restituisce il codice di stato HTTP standard 200, che indica una connessione riuscita.

Accedere al file system

Per impostazione predefinita, i processi eseguiti all'interno della sandbox hanno accesso di sola lettura al file system principale del container host. Puoi utilizzare il flag --write per abilitare la scrittura in un overlay del file system temporaneo (tmpfs). Tuttavia, le scritture andranno perse quando la sandbox verrà eliminata. Per abilitare la scrittura permanente nel container host, puoi configurare i punti di montaggio.

La directory /tmp all'interno della sandbox è sempre scrivibile, anche senza il flag --write. La directory /tmp viene eliminata quando viene eliminata la sandbox e non è inclusa negli snapshot o nei file di archivio.

Accesso di sola lettura predefinito

All'interno della sandbox, i processi possono leggere i file dal container host, ma non possono scrivere nel file system principale al di fuori di /tmp.

Gli esempi seguenti presuppongono che tu stia eseguendo i comandi dalla directory root (/) del container host.

Per verificare l'accesso di sola lettura predefinito, esegui questi comandi:

  1. Crea uno script Python nel container host:

    mkdir -p /tmp/my-scripts
    echo "print('hi')" > /tmp/my-scripts/task.py
    
  2. Verifica che il file esista localmente:

    cat /tmp/my-scripts/task.py
    
  3. Esegui il file all'interno della sandbox:

    sandbox do -- /usr/bin/python3 /tmp/my-scripts/task.py
    

    Questo comando restituisce hi, confermando che la sandbox ha accesso in lettura.

    Se tenti di scrivere dati direttamente nel file system radice della sandbox senza una configurazione aggiuntiva, l'esecuzione non va a buon fine. Ad esempio, il tentativo di scrivere nella directory root (/) all'interno della sandbox predefinita restituisce un errore di file system di sola lettura:

    Esegui questo comando per scrivere nel file system root:

    sandbox do -- /usr/bin/bash -c "echo 'hi' > /testfile.txt"
    

    Il comando non va a buon fine e restituisce il seguente errore:

    /usr/bin/bash: line 1: /testfile.txt: Read-only file system
    Error: failed to exec in container: cmd.Wait(exec) failed: exit status 1
    

Condividi i dati utilizzando i montaggi di associazione

Per consentire ai processi all'interno della sandbox di scrivere dati persistenti, collega un volume condiviso utilizzando il flag --mount:

  1. Crea una directory del volume condiviso sul container host e inserisci un file iniziale:

    mkdir -p /tmp/my-volume
    echo 'read' > /tmp/my-volume/readwrite.txt
    
  2. Esegui la sandbox per leggere il file dal percorso del punto di montaggio:

    sandbox do --mount type=bind,source=/tmp/my-volume,destination=/mnt/my-mount -- /usr/bin/bash -c "cat /mnt/my-mount/readwrite.txt"
    

    Questo comando restituisce read.

  3. Esegui la sandbox per scrivere nuovi dati nell'host dall'interno del mount:

    sandbox do --mount type=bind,source=/tmp/my-volume,destination=/mnt/my-mount -- /usr/bin/bash -c "echo 'write' > /mnt/my-mount/readwrite.txt"
    
  4. Verifica sul container host che la sandbox abbia modificato correttamente il file:

    cat /tmp/my-volume/readwrite.txt
    

    Questo comando restituisce write.

Configura i montaggi di sola lettura

Per concedere alla sandbox l'accesso a una directory host impedendole esplicitamente di modificare i file, aggiungi l'attributo readonly alla specifica di montaggio.

Ad esempio, esegui questo comando per testare le limitazioni di scrittura su un montaggio di associazione di sola lettura:

sandbox do --mount type=bind,source=/tmp/my-volume,destination=/mnt/my-mount,readonly -- /usr/bin/bash -c "echo 'fails' > /mnt/my-mount/hello.txt"

Il tentativo di scrittura non va a buon fine con il seguente errore:

/usr/bin/bash: line 1: /mnt/my-mount/hello.txt: Read-only file system
Error: failed to exec in container: cmd.Wait(exec) failed: exit status 1

Visualizza i log

Cloud Run acquisisce automaticamente gli eventi del ciclo di vita della sandbox, come l'avvio e l'uscita dall'esecuzione, in Cloud Logging.

L'interfaccia a riga di comando sandbox scrive l'output standard (stdout) e l'errore standard (stderr) dei comandi in sandbox direttamente negli stream standard del processo di chiamata. Per visualizzare questi log in Cloud Logging, indirizza i flussi all'output standard e all'errore standard del container:

Node.js

const { exec } = require('child_process');
const child = exec('sandbox do -- /usr/bin/python3 -c "print(1+2)"');
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);

Python

subprocess.run(
    ["sandbox", "do", "--", "/usr/bin/python3", "-c", "print(1+2)"],
    stdout=sys.stdout,
    stderr=sys.stderr,
)

Vai

cmd := exec.Command("sandbox", "do", "--", "/usr/bin/python3", "-c", "print(1+2)")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()

Passaggi successivi