Codeausführung in Cloud Run

Cloud Run ist bereits sandboxed und isoliert und eignet sich daher ideal für das Hosting von KI-Agents. Wenn Sie Cloud Run-Sandboxes aktivieren, ist das sandbox Befehlszeilentool in Ihrem Container verfügbar. Mit diesem Befehlszeilentool können Sie nicht vertrauenswürdigen Code, der in einer beliebigen Sprache geschrieben wurde, in einer hochoptimierten Sandbox-Umgebung ausführen, die vom Rest Ihres Containers isoliert ist.

KI-Agents können Sandboxes nutzen, um Sub-Agents sicher auszuführen, Berechnungsaufgaben auszuführen oder Browser in einer schnellen, isolierten Umgebung zu öffnen, ohne das Hostsystem zu gefährden.

Cloud Run-Sandboxes bieten folgende Hauptvorteile:

  • Schnelle Erstellung: Sandboxes sind interaktiv und können Befehle fast sofort ausführen. Wenn Sie Sandboxes in einer vorhandenen Cloud Run-Ressource erstellen, in der Ihr Agent ausgeführt wird, verkürzen Sie die Erstellungszeiten im Vergleich zur Erstellung einer neuen Cloud Run-Ressource für jede Aufgabe. Diese Effizienz trägt dazu bei, dass Ihr Agent reaktionsfähig bleibt.

  • Sicherheit: Sandboxes isolieren die Ausführung von Prozessen. Standardmäßig haben Sandboxes keinen Zugriff auf die übergeordnete Arbeitslast, Umgebungsvariablen, Secrets oder den Google Cloud Metadatenserver. Alle Sandboxes sind vollständig voneinander isoliert.

  • Zugriffssteuerung und Umgebung: Prozesse werden mit sudo Berechtigungen als Nicht-Root-Nutzer ausgeführt. So können Sie während der Ausführung Tools mit Paketmanagern wie apt, pip oder npm installieren. Die Sandbox-Umgebung ist zwar kurzlebig und wird nach Abschluss gelöscht, Sie können aber persistente Verzeichnisse oder Snapshots verwenden, um bestimmte Arbeitsbereiche zu speichern oder Daten einem Cloud Storage-Bucket zuzuordnen.

Hinweis

  1. Melden Sie sich in Ihrem Google Cloud -Konto an. Wenn Sie mit Google Cloudnoch nicht vertraut sind, erstellen Sie ein Konto, um die Leistung unserer Produkte in der Praxis sehen und bewerten zu können. Neukunden erhalten außerdem ein Guthaben von 300 $, um Arbeitslasten auszuführen, zu testen und bereitzustellen.
  2. 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

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

  4. 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

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

  6. Installieren und initialisieren Sie die gcloud CLI.
  7. Stellen Sie eine Cloud Run-Ressource bereit, z. B. einen Dienst der zweiten Generation , Job, Worker-Pool oder eine Instanz.

Sandboxes aktivieren

Wenn Sie Sandboxes verwenden möchten, müssen Sie sie zuerst für Ihre Cloud Run-Ressource mit dem Flag --sandbox-launcher oder dem YAML-Attribut sandboxLauncher aktivieren. Wählen Sie für detaillierte Konfigurationsschritte einen der folgenden Ressourcentypen aus:

Sandboxes starten

Nachdem Sie Sandboxes aktiviert haben, können Sie sie in Ihrer Container-Ausführungsumgebung starten. Die Sandbox-Binärdatei befindet sich unter /usr/local/gcp/bin/sandbox.

In den Beispielen in diesem Leitfaden wird der Befehl sandbox anstelle des absoluten Pfads /usr/local/gcp/bin/sandbox verwendet.

Sie können die Binärdatei ausführen, indem Sie in Ihrem Quellcode auf den absoluten Pfad verweisen. Wenn Sie beispielsweise Hello in Ihrer isolierten Sandbox ausgeben möchten, wählen Sie eine der folgenden Optionen aus:

Node.js

Wenn Sie den Sandbox-Befehl über eine Node.js-Anwendung ausführen möchten, fügen Sie den folgenden Code ein:

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

Python

Wenn Sie den Sandbox-Befehl über eine Python-Anwendung ausführen möchten, fügen Sie den folgenden Code ein:

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

Los

Wenn Sie den Sandbox-Befehl über eine Go-Anwendung ausführen möchten, fügen Sie den folgenden Code ein:

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

Sandbox-Befehlszeile

Wenn Sie den Sandbox-Befehl direkt über die Befehlszeile ausführen möchten, führen Sie den folgenden Befehl aus:

sandbox do -- /bin/echo "Hello"

Führen Sie den Befehl sandbox -h aus, um die vollständige Liste der verfügbaren Befehle aufzurufen.

Funktionen der Sandbox-Befehlszeile verwenden

Das Befehlszeilentool sandbox enthält Befehle zum Ausführen, Konfigurieren und Verwalten von Sandboxes.

Befehl in der Sandbox ausführen

Mit dem Befehl sandbox do können Sie eine Anweisung in einer neuen, kurzlebigen Sandbox ausführen. Der Befehl sandbox do führt die folgenden Aufgaben aus:

  1. Startet eine Sandbox-Umgebung (sandbox run).
  2. Führt den angegebenen Befehl aus (sandbox exec).
  3. Löscht die Sandbox nach erfolgreicher Ausführung (sandbox delete).

Wenn Sie beispielsweise eine mathematische Berechnung in der Sandbox durchführen möchten, führen Sie die folgenden Code-Snippets für Ihre bevorzugte Sprache aus. Achten Sie darauf, dass alle Befehle oder Tools, die Sie ausführen, z. B. python3, in Ihrem Container-Image installiert sind:

Node.js

So führen Sie den Sandbox-Befehl über eine Node.js-Anwendung aus:

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

Python

So führen Sie den Sandbox-Befehl über eine Python-Anwendung aus:

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}

Los

So führen Sie den Sandbox-Befehl über eine Go-Anwendung aus:

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

Sandbox-Befehlszeile

So führen Sie den Sandbox-Befehl direkt über die Befehlszeile aus:

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

Wenn Sie einen Befehl nach Namen ohne absoluten Pfad ausführen, z. B. python3 anstelle von /usr/bin/python3, konfigurieren Sie die Umgebungsvariable PATH in der Sandbox explizit mit dem Flag --env.

Daten über verschiedene Ausführungen hinweg beibehalten

Sandboxes sind standardmäßig kurzlebig. Wenn Sie Daten über verschiedene Sandbox-Ausführungen innerhalb derselben Cloud Run-Instanz hinweg beibehalten möchten, können Sie den Dateisystemstatus des Arbeitsbereichs mit Standard-tar-Archivdateien importieren und exportieren. Alternativ, können Sie Bind-Mounts konfigurieren, um Verzeichnisse direkt zwischen dem Hostcontainer und den Sandbox-Umgebungen freizugeben.

Verwenden Sie die folgenden Flags, wenn Sie den Befehl sandbox do ausführen:

  • --export-tar: Erfasst geänderte Overlay-Dateien nach Abschluss in einer tar-Archivdatei.
  • --import-tar: Extrahiert Dateien aus einer tar-Archivdatei in die Sandbox, bevor sie ausgeführt wird.
  • --sync-tar: Führt eine bidirektionale Synchronisierung durch, indem vor der Ausführung importiert und nach Abschluss exportiert wird.

Wenn Sie beispielsweise Daten zwischen zwei Sandbox-Aufrufen mit Archivdateien übergeben möchten, führen Sie die folgenden Befehle aus:

  1. Schreiben Sie Daten in eine Sandbox und exportieren Sie den Status in eine Archivdatei:

    sandbox do --write --export-tar=/tmp/work.tar \
      -- /usr/bin/bash -c "mkdir -p /tmp/work && echo 'task-complete' > /tmp/work/status.txt"
    
  2. Importieren Sie die Archivdatei in einem nachfolgenden Aufruf, um die Daten abzurufen:

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

Alternativ können Sie mit --sync-tar=/tmp/work.tar den vorhandenen Archivstatus automatisch importieren und neue Änderungen in einem einzigen Befehl exportieren. Wenn ein Sandbox-Prozess beendet wird, löscht Cloud Run endgültig kurzlebige Overlay-Dateien, die nicht in eine Archivdatei exportiert wurden.

Befehl im Hintergrund ausführen

Verwenden Sie das Flag --detach, um lang andauernde Prozesse, Headless-Browser oder Hintergrundserver auszuführen, z. B. eine Hintergrund-Agent-Schleife, die kontinuierlich auf eingehende Anfragen wartet.

Führen Sie beispielsweise den folgenden Befehl aus, um eine getrennte Sandbox mit einem inaktiven oder Hintergrundprogramm zu starten:

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

Mit dem Flag detach können Sie dieselbe Sandbox für mehrere Tests wiederverwenden. Wenn Sie mit einer ausgeführten getrennten Sandbox interagieren oder zusätzliche Befehle darin ausführen möchten, verwenden Sie den Befehl sandbox exec und geben Sie die Sandbox anhand ihres Namens an.

Wenn Sie beispielsweise einen Testbefehl in Ihrer vorhandenen my-web-server-Hintergrund-Sandbox ausführen möchten, führen Sie den folgenden Befehl aus:

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

Umgebungsvariablen konfigurieren

Konfigurieren Sie Umgebungs variablen in Sandboxes genauso wie in jedem anderen Container. Sandboxes übernehmen keine Umgebungsvariablen vom Hostcontainer. Sie müssen sie explizit mit dem Flag --env angeben, wenn Sie den Befehl sandbox ausführen.

Wenn Sie beispielsweise eine Konfigurationsvariable an eine Sandbox übergeben möchten, führen Sie den folgenden Befehl aus:

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

Übergeben Sie keine Secrets mit dem Flag env, da sie für die Sandbox-Prozesse sichtbar sein können.

Dateisystem-Snapshots erstellen

Stellen Sie eine benannte Sandbox im Hintergrund bereit, um kontinuierliche Aufgaben wie Webserver oder KI-Agenten mit langer Ausführungszeit zu verarbeiten, Befehle dynamisch für die Sandbox auszuführen und den geänderten Dateisystemstatus in einer tar-Archivdatei zu erfassen.

Wenn Sie beispielsweise eine Hintergrund-Sandbox bereitstellen, eine Datei in ihr Overlay schreiben und ihren Status erfassen möchten, um zu prüfen, ob die Daten erfasst wurden, führen Sie die folgenden Befehle aus:

  1. Stellen Sie eine benannte Sandbox im Hintergrund bereit, bei der der Schreibzugriff aktiviert ist, und erstellen Sie eine Datei in ihrem Arbeitsbereich:

    sandbox run --write my-sandbox --detach -- /usr/bin/bash -c "echo 'hi' > /tmp/hello.txt && sleep 1h"
    
  2. Erstellen Sie mit dem Befehl sandbox tar einen Snapshot des geänderten Dateisystems der ausgeführten Sandbox:

    sandbox tar my-sandbox --file=/tmp/foo.tar
    
  3. Extrahieren Sie die Snapshot-Archivdatei und prüfen Sie, ob sie die in der Sandbox geschriebenen Daten enthält:

    tar -xvf /tmp/foo.tar
    

    Sie sollten die folgenden Ergebnisse sehen:

    ./
    ./tmp/
    ./tmp/hello.txt
    

Netzwerk konfigurieren

Standardmäßig wird der gesamte ausgehende Traffic von der Sandbox blockiert. Verwenden Sie das Flag --allow-egress, um den ausgehenden Netzwerkzugriff zuzulassen:

Wenn Sie beispielsweise Daten von einem externen Endpunkt abrufen möchten, führen Sie den folgenden Befehl aus:

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

Dieser Befehl gibt den Standard-HTTP-Statuscode 200 zurück, der eine erfolgreiche Verbindung anzeigt.

Auf das Dateisystem zugreifen

Standardmäßig haben Prozesse, die Sie in der Sandbox ausführen, schreibgeschützten Zugriff auf das Root-Dateisystem des Hostcontainers. Mit dem Flag --write können Sie das Schreiben in ein temporäres Dateisystem-Overlay (tmpfs) aktivieren. Die Schreibvorgänge gehen jedoch verloren, wenn die Sandbox gelöscht wird. Wenn Sie das persistente Schreiben in den Hostcontainer aktivieren möchten, können Sie Bind-Mounts konfigurieren.

Standardmäßiger schreibgeschützter Zugriff

In der Sandbox können Prozesse Dateien aus dem Hostcontainer lesen, aber nicht in das Root-Dateisystem schreiben.

In den folgenden Beispielen wird davon ausgegangen, dass Sie Befehle im Stammverzeichnis (/) Ihres Hostcontainers ausführen.

Führen Sie die folgenden Befehle aus, um den standardmäßigen schreibgeschützten Zugriff zu prüfen:

  1. Erstellen Sie ein Python-Skript im Hostcontainer:

    mkdir -p /tmp/my-scripts
    echo "print('hi')" > /tmp/my-scripts/task.py
    
  2. Prüfen Sie, ob die Datei lokal vorhanden ist:

    cat /tmp/my-scripts/task.py
    
  3. Führen Sie die Datei in Ihrer Sandbox aus:

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

    Dieser Befehl gibt hi zurück und bestätigt, dass die Sandbox Lesezugriff hat.

    Wenn Sie versuchen, Daten ohne zusätzliche Konfiguration direkt in das Root-Dateisystem der Sandbox zu schreiben, schlägt die Ausführung fehl. Wenn Sie beispielsweise in der Standardsandbox in /tmp schreiben, wird ein Fehler für ein schreibgeschütztes Dateisystem zurückgegeben:

    Führen Sie den folgenden Befehl aus, um in das Root-Dateisystem zu schreiben:

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

    Der Befehl schlägt mit dem folgenden Fehler fehl:

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

Daten mit Bind-Mounts freigeben

Wenn Prozesse in der Sandbox persistente Daten schreiben dürfen, hängen Sie mit dem Flag --mount ein freigegebenes Volume an:

  1. Erstellen Sie ein freigegebenes Volume-Verzeichnis im Hostcontainer und füllen Sie es mit einer ersten Datei:

    mkdir -p /tmp/my-volume
    echo 'read' > /tmp/my-volume/readwrite.txt
    
  2. Führen Sie die Sandbox aus, um die Datei über den Bind-Mount-Pfad zu lesen:

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

    Dieser Befehl gibt read zurück.

  3. Führen Sie die Sandbox aus, um neue Daten aus dem Mount zurück auf den Host zu schreiben:

    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. Prüfen Sie im Hostcontainer, ob die Datei von der Sandbox erfolgreich geändert wurde:

    cat /tmp/my-volume/readwrite.txt
    

    Dieser Befehl gibt write zurück.

Schreibgeschützte Mounts konfigurieren

Wenn Sie der Sandbox Zugriff auf ein Hostverzeichnis gewähren, aber explizit verhindern möchten, dass sie Dateien ändert, hängen Sie das Attribut readonly an die Mount-Spezifikation an.

Führen Sie beispielsweise den folgenden Befehl aus, um Schreibbeschränkungen für einen schreibgeschützten Bind-Mount zu testen:

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"

Der Schreibversuch schlägt mit dem folgenden Fehler fehl:

/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

Logs ansehen

Cloud Run erfasst automatisch Sandbox-Lebenszyklusereignisse wie Ausführungsstarts und -beendigungen in Cloud Logging.

Die sandbox-Befehlszeile schreibt die Standardausgabe (stdout) und die Standardfehlerausgabe (stderr) von Sandbox-Befehlen direkt in die Standardstreams des aufrufenden Prozesses. Wenn Sie diese Logs in Cloud Logging ansehen möchten, leiten Sie die Streams an die Standardausgabe und die Standardfehlerausgabe Ihres Containers weiter:

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,
)

Go

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

Nächste Schritte