Codeausführung in Cloud Run

Cloud Run ist bereits in einer Sandbox ausgeführt und isoliert, was es zum idealen Ort für das Hosting von KI-Agents macht. 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 Unter-Agents sicher auszuführen, Rechenaufgaben zu erledigen oder Browser in einer schnellen, isolierten Umgebung zu öffnen, ohne das Hostsystem zu gefährden.

Cloud Run-Sandboxes bieten die folgenden wichtigen Vorteile:

  • 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ürzt sich die Erstellungszeit im Vergleich zum Erstellen einer neuen Cloud Run-Ressource für jede Aufgabe. So bleibt Ihr Agent reaktionsfähig.

  • Sicherheit: Sandboxes isolieren die Ausführung von Prozessen. Standardmäßig haben Sandboxes keinen Zugriff auf die übergeordnete Arbeitslast, Umgebungsvariablen, Secrets oder den Metadatenserver Google Cloud . 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 Kartendaten 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 Leistungsfähigkeit 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 einen Cloud Run-Dienst in der Ausführungsumgebung der zweiten Generation bereit.

Sandboxes aktivieren

Wenn Sie Sandboxes aktivieren, wird Ihr Cloud Run-Dienst in der Ausführungsumgebung der zweiten Generation bereitgestellt. Verwenden Sie die Google Cloud CLI oder eine YAML-Konfiguration, um Sandboxes in Cloud Run-Diensten zu aktivieren:

gcloud

Geben Sie zum Bereitstellen oder Aktualisieren des Dienstes das Flag --sandbox-launcher an:

  • Führen Sie den folgenden Befehl aus, um einen neuen Dienst bereitzustellen:

    gcloud beta run deploy SERVICE --image IMAGE_URL --sandbox-launcher

    Ersetzen Sie Folgendes:

    • SERVICE: Der Name Ihres Cloud Run-Dienstes.
    • IMAGE_URL: ein Verweis auf das Container-Image, z. B. us-docker.pkg.dev/cloudrun/container/hello:latest Wenn Sie Artifact Registry verwenden, muss das Repository REPO_NAME bereits erstellt sein. Die URL hat das Format LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG.
  • Führen Sie den folgenden Befehl aus, um einen vorhandenen Dienst zu aktualisieren:

    gcloud beta run services update SERVICE --sandbox-launcher

YAML

  1. Wenn Sie einen neuen Dienst erstellen, überspringen Sie diesen Schritt. Wenn Sie einen vorhandenen Dienst aktualisieren, laden Sie die zugehörige YAML-Konfiguration herunter:

    gcloud run services describe SERVICE --format export > service.yaml
  2. Aktualisieren Sie die YAML-Datei Ihres Dienstes, sodass die Containerkonfiguration das Attribut sandboxLauncher mit dem Wert true enthält:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: SERVICE
      annotations:
        run.googleapis.com/launch-stage: BETA
    spec:
      template:
        spec:
          containers:
          - name: CONTAINER
            image: IMAGE_URL
            sandboxLauncher: true
            port: 8080
    

    Ersetzen Sie Folgendes:

    • SERVICE: Der Name Ihres Cloud Run-Dienstes.
    • CONTAINER: Der Name des Containers.
    • IMAGE_URL: ein Verweis auf das Container-Image, z. B. us-docker.pkg.dev/cloudrun/container/hello:latest Wenn Sie Artifact Registry verwenden, muss das Repository REPO_NAME bereits erstellt sein. Die URL hat das Format LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG.
  3. Erstellen oder aktualisieren Sie den Dienst mit dem folgenden Befehl:

    gcloud run services replace service.yaml

    Der Befehl gcloud run services replace verwendet standardmäßig die Datei service.yaml, sofern sie vorhanden ist.

Sandboxes nutzen die CPU und den Arbeitsspeicher, die dem Hostcontainer zugewiesen sind. Achten Sie darauf, dass die Limits für CPU und Arbeitsspeicher Ihres Hauptcontainers ausreichen, um sowohl Ihre Anwendung als auch alle aktiven Sandboxes, die Sie gleichzeitig ausführen, zu unterstützen.

Sandboxes deaktivieren

Wenn Sie die Möglichkeit zum Starten einer Sandbox in Ihrem Dienst deaktivieren möchten, verwenden Sie die Google Cloud CLI oder eine YAML-Konfiguration:

gcloud

Aktualisieren Sie den Dienst mit dem Flag --no-sandbox-launcher, indem Sie den folgenden Befehl ausführen:

gcloud beta run services update SERVICE --no-sandbox-launcher

Ersetzen Sie SERVICE durch den Namen Ihres Dienstes.

YAML

  1. Wenn Sie einen neuen Dienst erstellen, überspringen Sie diesen Schritt. Wenn Sie einen vorhandenen Dienst aktualisieren, laden Sie die zugehörige YAML-Konfiguration herunter:

    gcloud run services describe SERVICE --format export > service.yaml
  2. Aktualisieren Sie die YAML-Datei Ihres Dienstes, um das Attribut sandboxLauncher aus der Containerkonfiguration zu entfernen:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: SERVICE
    spec:
      template:
        spec:
          containers:
          - name: CONTAINER
            image: IMAGE_URL
            port: 8080
    

    Ersetzen Sie Folgendes:

    • SERVICE: Der Name Ihres Cloud Run-Dienstes.
    • CONTAINER: Der Name des Containers.
    • IMAGE_URL: ein Verweis auf das Container-Image, z. B. us-docker.pkg.dev/cloudrun/container/hello:latest Wenn Sie Artifact Registry verwenden, muss das Repository REPO_NAME bereits erstellt sein. Die URL hat das Format LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG.
  3. Erstellen oder aktualisieren Sie den Dienst mit dem folgenden Befehl:

    gcloud run services replace service.yaml

    Der Befehl gcloud run services replace verwendet standardmäßig die Datei service.yaml, sofern sie vorhanden ist.

Sandboxes starten

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

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

Node.js

Fügen Sie den folgenden Code ein, um den Sandbox-Befehl über eine Node.js-Anwendung auszuführen:

exec(`/usr/local/gcp/bin/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(
    ["/usr/local/gcp/bin/sandbox", "do", "--", "/bin/echo", "Hello"],
    capture_output=True,
    text=True,
)
return {"stdout": result.stdout, "stderr": result.stderr}

Go

Fügen Sie den folgenden Code ein, um den Sandbox-Befehl über eine Go-Anwendung auszuführen:

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

Sandbox-Befehlszeile

Führen Sie den folgenden Befehl aus, um den Sandbox-Befehl direkt über die Befehlszeile auszuführen:

/usr/local/gcp/bin/sandbox do -- /bin/echo "Hello"

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

Wenn Sie die vollständige Liste der verfügbaren Befehle aufrufen möchten, führen Sie den Befehl /usr/local/gcp/bin/sandbox -h aus.

Sandbox-Befehlszeilenfunktionen verwenden

Das sandbox-Befehlszeilentool 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 Anleitung in einer neuen, kurzlebigen Sandbox ausführen. Mit dem Befehl sandbox do werden folgende Aufgaben ausgeführt:

  1. Startet eine Sandbox-Umgebung (sandbox run).
  2. Führt den von Ihnen angegebenen Befehl (sandbox exec) aus.
  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}

Go

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 über den Namen ohne den 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 sitzungsspezifisch. Wenn Sie Daten über verschiedene Sandbox-Ausführungen hinweg in derselben Cloud Run-Instanz beibehalten möchten, können Sie den Status des Arbeitsbereich-Dateisystems mithilfe von Standard-tar-Archivdateien importieren und exportieren. Alternativ können Sie Bind-Mounts konfigurieren, um Verzeichnisse direkt zwischen dem Host-Container 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: Dateien werden vor der Ausführung aus einer tar-Archivdatei in die Sandbox extrahiert.
  • --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 mithilfe von Archivdateien übergeben möchten, führen Sie die folgenden Befehle aus:

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

    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 temporäre Overlay-Dateien, die nicht in eine Archivdatei exportiert wurden, dauerhaft.

Befehl im Hintergrund ausführen

Verwenden Sie das Flag --detach, um Prozesse mit langer Laufzeit, monitorlose 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, verwenden Sie den folgenden Befehl:

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

Umgebungsvariablen konfigurieren

Umgebungsvariablen lassen sich in Sandboxes genauso konfigurieren wie in anderen Containern. Sandboxen ü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 in 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önnten.

Dateisystem-Snapshots erstellen

Stellen Sie eine benannte Sandbox im Hintergrund bereit, um kontinuierliche Aufgaben wie Webserver oder lang andauernde Agent-Workflows zu verarbeiten, führen Sie Befehle dynamisch für die Sandbox aus und erfassen Sie den geänderten Dateisystemstatus in einer tar-Archivdatei.

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 mit aktiviertem Schreibzugriff bereit und erstellen Sie eine Datei im zugehörigen 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 laufenden Sandbox:

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

    tar -xvf /tmp/foo.tar
    

    Die folgenden Ergebnisse sollten angezeigt werden:

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

Netzwerk konfigurieren

Standardmäßig wird der gesamte ausgehende Traffic aus 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 standardmäßigen HTTP-Statuscode 200 zurück, der eine erfolgreiche Verbindung angibt.

Auf das Dateisystem zugreifen

Standardmäßig haben Prozesse, die Sie in der Sandbox ausführen, schreibgeschützten Zugriff auf das Root-Dateisystem des Host-Containers. 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 dauerhafte Schreiben in den Hostcontainer aktivieren möchten, können Sie Bind-Mounts konfigurieren.

Standardmäßiger Lesezugriff

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 schreibgeschützten Standardzugriff zu überprü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, was bestätigt, dass die Sandbox Lesezugriff hat.

    Wenn Sie versuchen, Daten ohne zusätzliche Konfiguration direkt in das Stammdateisystem der Sandbox zu schreiben, schlägt die Ausführung fehl. Wenn Sie beispielsweise versuchen, in der Standardsandbox in /tmp zu 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 persistierbare 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 Startdatei:

    mkdir -p /tmp/my-volume
    echo 'read' > /tmp/my-volume/readwrite.txt
    
  2. Führen Sie die Sandbox aus, um die Datei aus dem 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 vom Mount aus 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 Sandbox die Datei erfolgreich geändert hat:

    cat /tmp/my-volume/readwrite.txt
    

    Dieser Befehl gibt write zurück.

Schreibgeschützte Bereitstellungen konfigurieren

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

Führen Sie beispielsweise den folgenden Befehl aus, um Schreibbeschränkungen für eine schreibgeschützte Bind-Mount-Bereitstellung 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 den Standardfehler (stderr) von Sandbox-Befehlen direkt in die Standardstreams des aufrufenden Prozesses. Wenn Sie diese Logs in Cloud Logging aufrufen 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