Agent-Sandbox im GKE-Speicher verwalten

In diesem Dokument finden Sie Referenzimplementierungen für die Verwaltung des Speichers für die Agent Sandbox in GKE, die auf die Anforderungen des Datenlebenszyklus Ihrer Agenten zugeschnitten sind.

Wählen Sie je nach den Anforderungen des Datenlebenszyklus Ihrer Agenten eine der folgenden Konfigurationen aus:

Weitere Informationen zur Auswahl einer Speicherlösung finden Sie unter Speicher für KI-Agenten-Arbeitslasten auswählen.

In diesem Dokument wird die StorageClass dynamic-rwo für die automatische Auswahl des Laufwerktyps verwendet, um Laufwerke bereitzustellen, die mit den Maschinentypen der Knoten kompatibel sind, auf denen Agent Sandbox in GKE-Pods geplant ist. Damit GKE Hyperdisk Balanced-Volumes für den Speicher Ihrer Agenten bereitstellt, müssen Sie Ihre Agent Sandbox in GKE-Pods auf den Knoten kompatibler Maschinenfamilien wie N4 planen. Andernfalls greift GKE auf pd-balanced zurück.

In diesem Dokument wird der Datenzugriffsmodus Privater isolierter Arbeitsbereich mit dem Zugriff ReadWriteOnce (RWO) implementiert. In diesem Modus wird ein Agent mit einem privaten isolierten Speicherverzeichnis gestartet, auf das er allein Lese- und Schreibzugriff hat.

Sofern nicht anders angegeben, verwenden die Referenzimplementierungen in diesem Dokument die direkte Sandbox-Erstellung, die für Agenten geeignet ist, die eine Startlatenz von mehreren Sekunden tolerieren. Um eine Startlatenz von weniger als einer Sekunde für statusbehaftete oder zu einem bestimmten Zeitpunkt wiederherstellbare Arbeitsbereiche zu erreichen, müssen Sie Agent Sandbox in GKE Warm Pools verwenden. Das Binden von Speicher an einen beanspruchten Warm Pool-Pod erfordert benutzerdefinierte Skripts und ein privilegiertes DaemonSet. Eine Referenzimplementierung finden Sie in diesem GitHub-Beispiel.

Alternative Zugriffsmodi

Um alternative Zugriffsmodi zu unterstützen, können Sie die Volume- und Snapshot-Definitionen in den Konfigurationen ändern:

  • Arbeitsbereich für die Zusammenarbeit: Ändern Sie accessModes in ReadWriteMany und verwenden Sie eine RWX-fähige StorageClass wie Filestore Multishares (Enterprise) (enterprise-multishare-rwx).
  • Arbeitsbereich für die Verzweigung von Erkundungen: Stellen Sie den Vorlagenordner mit Lesezugriff bereit und stellen Sie ein separates beschreibbares Scratchpad bereit. Für die Basisvorlage müssen Sie Speicher verwenden, der mehrere schreibgeschützte Anhänge unterstützt, z. B. Hyperdisk ML mit ReadOnlyMany (ROX) Zugriffsmodus oder Filestore Multishares mit dem Zugriffsmodus RWX.

Hinweis

Aktivieren Sie Agent Sandbox in GKE in Ihrem Cluster.

Statusbehafteten Arbeitsbereich konfigurieren

Verwenden Sie dieses Muster, um den neuesten Status der Dateien eines Agenten beizubehalten. Es ist nützlich, wenn der Status beibehalten werden muss, wenn die Agentensitzung pausiert oder beendet wird (Agent Sandbox wird gelöscht), und die Daten aus dem neuesten Status wiederhergestellt werden müssen, wenn die Agentensitzung aktiviert wird (Agent Sandbox wird neu erstellt).

Die Referenzimplementierung in diesem Abschnitt verwendet die direkte Sandbox-Erstellung und ist für Agenten geeignet, die eine Startlatenz von mehreren Sekunden tolerieren.

Bei diesem Ansatz werden Standard-GKE-PersistentVolumeClaim-Ressourcen (PVC) verwendet, um eine Sandbox mit einem vorhandenen PVC zu verknüpfen, das die Daten eines Nutzers enthält.

Das Muster für statusbehaftete Arbeitsbereiche folgt dieser Ereignisreihenfolge:

  1. Bereitstellung: Der Administrator oder Orchestrator stellt manuell einen privaten PVC für jede Agentensitzung mit einer deterministischen ID bereit (z. B. pvc-agent-1).
  2. Referenzierung: In der Sandbox-Ressource verwenden Sie das persistentVolumeClaim Feld im volumes Block, um den genauen claimName des vorhandenen Volumes anzugeben.
  3. Latenz: Wenn die Sandbox erstellt wird, muss GKE das Compute Engine-Laufwerk dynamisch an die Knoten-VM anhängen, was zu einer Standardverzögerung von mehreren Sekunden führt.
  4. Persistenz: Bei Beendigung der Sitzung (Löschen der Sandbox) trennt GKE das Laufwerk, löscht aber nicht den PVC. So wird sichergestellt, dass der aktuelle Status für die nächste Sitzung beibehalten wird.

Führen Sie die Schritte in den folgenden Unterabschnitten aus, um einen statusbehafteten Arbeitsbereich zu konfigurieren, in dem Daten zwischen Sitzungen beibehalten werden.

PersistentVolumeClaim (PVC) für einen persistenten Arbeitsbereich bereitstellen

Erstellen Sie einen privaten PersistentVolumeClaim (PVC) mit einer deterministischen ID wie pvc-agent-1.

  1. Speichern Sie das folgende Manifest als pvc-agent-1.yaml:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-agent-1 # Derived directly from the deterministic assignment ID
      namespace: default
    spec:
      accessModes:
        - ReadWriteOnce
      storageClassName: dynamic-rwo # Selects disk type compatible with the node machine family
      resources:
        requests:
          storage: 10Gi
    
  2. Wenden Sie das Manifest an:

    kubectl apply -f pvc-agent-1.yaml
    

Da die Speicherklasse die dynamische Volume-Bindung verwendet, ist das Laufwerk noch nicht an einen Knoten angehängt. Es bleibt im Status Pending, bis ein Pod, der es anfordert, geplant ist.

Agent Sandbox bereitstellen

Stellen Sie die benutzerdefinierte Sandbox-Ressource bereit und verweisen Sie auf den deterministischen PVC.

  1. Speichern Sie das folgende Manifest als sandbox-agent-1.yaml:

    apiVersion: agents.x-k8s.io/v1alpha1
    kind: Sandbox
    metadata:
      name: sandbox-agent-1 # Traceable sandbox name
      namespace: default
    spec:
      replicas: 1
      podTemplate:
        spec:
          runtimeClassName: gvisor # Required
          automountServiceAccountToken: false # Required
          securityContext:
            runAsNonRoot: true # Required
            runAsUser: 1000
            fsGroup: 1000 # Grant group access to the volume
          nodeSelector:
            sandbox.gke.io/runtime: gvisor # Required
          tolerations:
          - key: "sandbox.gke.io/runtime"
            value: "gvisor"
            effect: "NoSchedule" # Required
          containers:
          - name: agent
            image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0
            ports:
            - containerPort: 8888
            volumeMounts:
            - name: workspace-disk
              mountPath: /workspace # Mounts the private disk into the container
            resources:
              limits:
                cpu: "500m"
                memory: "1Gi" # Required
            securityContext:
              capabilities:
                drop: ["ALL"] # Required
          volumes:
          - name: workspace-disk
            persistentVolumeClaim:
              claimName: pvc-agent-1 # Binds this specific Sandbox to Agent 1's PVC
          restartPolicy: OnFailure
    
  2. Wenden Sie das Manifest an:

    kubectl apply -f sandbox-agent-1.yaml
    

GKE prüft die Knotenkapazität und hängt das Laufwerk an, was einige Sekunden dauert. Der Container wird in einem gVisor-Kernel im Nutzerbereich initialisiert.

Daten vom Agent schreiben

Simulieren Sie einen aktiven KI-Agenten, der Dateimodifikationen in seinem Arbeitsbereich ausführt, indem Sie eine Textdatei auf das bereitgestellte Laufwerk schreiben.

# Set the active Pod name
POD_NAME=sandbox-agent-1

# Write a state file to the persistent directory
kubectl exec $POD_NAME -- sh -c "echo 'Workspace State Saved - Agent 1' > /workspace/modified_data.txt"

# Confirm the file exists on the disk
kubectl exec $POD_NAME -- cat /workspace/modified_data.txt

Agentensitzung beenden

Um das Herunterskalieren oder Beenden der Sitzung zu simulieren, wenn der Agent inaktiv wird, löschen Sie die Sandbox-Ressource, behalten aber den zugrunde liegenden Speicher bei.

kubectl delete sandbox sandbox-agent-1

GKE hebt die Bereitstellung des Laufwerks auf und trennt es. Der PVC pvc-agent-1 bleibt erhalten und die Daten werden beibehalten.

Agentensitzung reaktivieren

Um die Sitzung zu reaktivieren, stellen Sie eine neue Sandbox-Ressource bereit, die auf denselben PVC verweist.

kubectl apply -f sandbox-agent-1.yaml

Das Laufwerk wird wieder angehängt (was zu einer Verzögerung beim Anhängen führt) und der Container wird gestartet.

Datenbeibehaltung prüfen

Prüfen Sie den neu erstellten Sandbox-Container, um zu bestätigen, dass die Daten der vorherigen Sitzung beibehalten wurden.

# Set the active Pod name of the new session
NEW_POD_NAME=sandbox-agent-1

# Read the file from the newly booted sandbox
kubectl exec -it $NEW_POD_NAME -- cat /workspace/modified_data.txt

Die Ausgabe sollte Workspace State Saved - Agent 1 enthalten.

Ressourcen bereinigen

Löschen Sie die Agent Sandbox und den zugehörigen PersistentVolumeClaim:

kubectl delete sandbox sandbox-agent-1
kubectl delete pvc pvc-agent-1

Wiederherstellung zu einem bestimmten Zeitpunkt und Übertragung der Eigentumsrechte konfigurieren

Verwenden Sie dieses Muster, um Datasets für parallele Experimente, Debugging oder unabhängige Arbeit zu klonen. Der Arbeitsbereich eines Agenten wird aus einem historischen Dataset (oder einem gemeinsamen Status) initialisiert. Nachfolgende Änderungen werden in einer separaten, privaten beschreibbaren Ebene gespeichert, ohne die Basisvorlage zu ändern.

Die Referenzimplementierung in diesem Abschnitt verwendet die direkte Sandbox-Erstellung und ist für Agenten geeignet, die eine Startlatenz von mehreren Sekunden tolerieren. Bei diesem Ansatz stellt der Orchestrator dynamisch neue PersistentVolumeClaims (PVCs) aus historischen VolumeSnapshots bereit, bevor eine neue Sandbox-Sitzung gestartet wird.

VolumeSnapshotClass erstellen

Erstellen Sie eine VolumeSnapshotClass, die den CSI-Treiber und die Richtlinie zur Datenlöschung angibt. Verwenden Sie für Hyperdisk den Treiber pd.csi.storage.gke.io.

  1. Speichern Sie das folgende Manifest als 1-snapshot-class.yaml:

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshotClass
    metadata:
      name: standard-rwo-snapshot
    driver: pd.csi.storage.gke.io
    deletionPolicy: Delete
    
  2. Wenden Sie das Manifest an:

    kubectl apply -f 1-snapshot-class.yaml
    

Anfänglichen Arbeitsbereich bereitstellen

Erstellen Sie ein Volume, in dem der Agent seine erste Arbeit ausführt.

  1. Speichern Sie das folgende Manifest als 2-source-pvc.yaml:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: agent-source-pvc
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: dynamic-rwo
      resources:
        requests:
          storage: 10Gi
    
  2. Wenden Sie das Manifest an:

    kubectl apply -f 2-source-pvc.yaml
    

Statusdaten generieren

Stellen Sie einen Sandbox-Pod bereit, um Daten in das Volume zu schreiben.

  1. Speichern Sie das folgende Manifest als 3-source-sandbox.yaml:

    apiVersion: agents.x-k8s.io/v1alpha1
    kind: Sandbox
    metadata:
      name: agent-session-v1
      namespace: default
    spec:
      replicas: 1
      podTemplate:
        spec:
          runtimeClassName: gvisor
          automountServiceAccountToken: false # Required
          securityContext:
            runAsNonRoot: true # Required
            runAsUser: 1000
            fsGroup: 1000 # Grant group access to the volume
          nodeSelector:
            sandbox.gke.io/runtime: gvisor # Required
          tolerations:
          - key: "sandbox.gke.io/runtime"
            value: "gvisor"
            effect: "NoSchedule" # Required
          containers:
          - name: agent
            image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0
            ports:
            - containerPort: 8888
            volumeMounts:
            - name: workspace
              mountPath: /workspace
            resources:
              limits:
                cpu: "500m"
                memory: "1Gi" # Required
            securityContext:
              capabilities:
                drop: ["ALL"] # Required
          volumes:
          - name: workspace
            persistentVolumeClaim:
              claimName: agent-source-pvc
          restartPolicy: OnFailure
    
  2. Wenden Sie das Manifest an:

    kubectl apply -f 3-source-sandbox.yaml
    
  3. Warten Sie, bis der Pod ausgeführt wird, und schreiben Sie dann eine Statusdatei:

    POD_NAME=agent-session-v1
    kubectl exec $POD_NAME -- sh -c "echo 'Point-in-Time Snapshot - v1' > /workspace/state.txt"
    

Historischen Status archivieren (CSI VolumeSnapshot)

Lösen Sie einen CSI VolumeSnapshot aus, um den aktuellen Status einzufrieren. Beachten Sie beim Erstellen eines Snapshots die Best Practices für Laufwerk-Snapshots.

  1. Speichern Sie das folgende Manifest als 4-volume-snapshot.yaml:

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshot
    metadata:
      name: agent-session-v1-snapshot
    spec:
      volumeSnapshotClassName: standard-rwo-snapshot
      source:
        persistentVolumeClaimName: agent-source-pvc
    
  2. Wenden Sie das Manifest an:

    kubectl apply -f 4-volume-snapshot.yaml
    

Volume aus dem Snapshot wiederherstellen

Stellen Sie einen neuen PVC bereit, dessen dataSource auf den CSI VolumeSnapshot verweist.

  1. Speichern Sie das folgende Manifest als 5-restored-pvc.yaml:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: agent-restored-pvc
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: dynamic-rwo
      dataSource:
        name: agent-session-v1-snapshot
        kind: VolumeSnapshot
        apiGroup: snapshot.storage.k8s.io
      resources:
        requests:
          storage: 10Gi
    
  2. Wenden Sie das Manifest an:

    kubectl apply -f 5-restored-pvc.yaml
    

Wiederhergestellte Agent Sandbox-Sitzung starten

Stellen Sie eine neue Sandbox-Ressource bereit, die auf den neu wiederhergestellten PVC verweist.

  1. Speichern Sie das folgende Manifest als 6-restored-sandbox.yaml:

    apiVersion: agents.x-k8s.io/v1alpha1
    kind: Sandbox
    metadata:
      name: agent-session-v2-restored
      namespace: default
    spec:
      replicas: 1
      podTemplate:
        spec:
          runtimeClassName: gvisor
          automountServiceAccountToken: false # Required
          securityContext:
            runAsNonRoot: true # Required
            runAsUser: 1000
            fsGroup: 1000 # Grant group access to the volume
          nodeSelector:
            sandbox.gke.io/runtime: gvisor # Required
          tolerations:
          - key: "sandbox.gke.io/runtime"
            value: "gvisor"
            effect: "NoSchedule" # Required
          containers:
          - name: agent
            image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0
            ports:
            - containerPort: 8888
            volumeMounts:
            - name: workspace
              mountPath: /workspace
            resources:
              limits:
                cpu: "500m"
                memory: "1Gi" # Required
            securityContext:
              capabilities:
                drop: ["ALL"] # Required
          volumes:
          - name: workspace
            persistentVolumeClaim:
              claimName: agent-restored-pvc
          restartPolicy: OnFailure
    
  2. Wenden Sie das Manifest an:

    kubectl apply -f 6-restored-sandbox.yaml
    

Persistenz und Wiederherstellung prüfen

Prüfen Sie, ob der Agent die Verlaufsdaten lesen kann.

NEW_POD_NAME=agent-session-v2-restored
kubectl exec $NEW_POD_NAME -- cat /workspace/state.txt

Erwartete Ausgabe: Point-in-Time Snapshot - v1

Ressourcen bereinigen

Löschen Sie die Agent Sandboxes, PVCs und den VolumeSnapshot:

kubectl delete sandbox agent-session-v1
kubectl delete sandbox agent-session-v2-restored
kubectl delete pvc agent-source-pvc
kubectl delete pvc agent-restored-pvc
kubectl delete volumesnapshot agent-session-v1-snapshot
kubectl delete volumesnapshotclass standard-rwo-snapshot

Sitzungsspezifischen Arbeitsbereich konfigurieren

Verwenden Sie das Muster für sitzungsspezifische Arbeitsbereiche, wenn ein Agent ein Speichervolume zum Speichern temporärer Dateien benötigt, während er aktiv ist. Beim Löschen der Agent Sandbox müssen keine Daten beibehalten werden.

Mit Start in weniger als einer Sekunde konfigurieren

Verwenden Sie Agent Sandbox in GKE Warm Pools, um leere Volumes im Hintergrund vorzubereiten.

SandboxTemplate definieren

Definieren Sie den sitzungsspezifischen Speicher im Block volumeClaimTemplate.

  1. Speichern Sie das folgende Manifest als stateless-template.yaml:

    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxTemplate
    metadata:
      name: stateless-sandbox-template
      namespace: default
    spec:
      podTemplate:
        spec:
          runtimeClassName: gvisor
          automountServiceAccountToken: false
          securityContext:
            runAsNonRoot: true
            runAsUser: 1000
            fsGroup: 1000 # Grant group access to the volume
          nodeSelector:
            sandbox.gke.io/runtime: gvisor
          tolerations:
          - key: "sandbox.gke.io/runtime"
            value: "gvisor"
            effect: "NoSchedule"
          containers:
          - name: agent
            image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0
            ports:
            - containerPort: 8888
            volumeMounts:
            - name: ephemeral-disk
              mountPath: /workspace
            resources:
              limits:
                cpu: "500m"
                memory: "1Gi" # Required
            securityContext:
              capabilities:
                drop: ["ALL"] # Required
      volumeClaimTemplates:
      - metadata:
          name: ephemeral-disk
        spec:
          accessModes: ["ReadWriteOnce"]
          storageClassName: dynamic-rwo # Selects disk type compatible with node machine family
          resources:
            requests:
              storage: 10Gi
    

Sandbox Warm Pool starten

  1. Speichern Sie das folgende Manifest als stateless-warmpool.yaml:

    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxWarmPool
    metadata:
      name: stateless-warmpool
      namespace: default
    spec:
      replicas: 5 # Keep five standby Pods with pre-attached empty disks
      sandboxTemplateRef:
        name: stateless-sandbox-template
    
  2. Wenden Sie beide Manifeste an:

    kubectl apply -f stateless-template.yaml
    kubectl apply -f stateless-warmpool.yaml
    

Sandbox beanspruchen

Definieren Sie einen SandboxClaim, der ausgelöst wird, wenn ein Nutzer eine Sitzung startet.

  1. Speichern Sie das folgende Manifest als stateless-sandbox-claim.yaml:

    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxClaim
    metadata:
      name: agent-1-claim
    spec:
      sandboxTemplateRef:
        name: stateless-sandbox-template
    
  2. Wenden Sie das Manifest an:

    kubectl apply -f stateless-sandbox-claim.yaml
    

Ausführung in weniger als einer Sekunde prüfen

Erfassen Sie den Namen des Agent Sandbox-Pods und prüfen Sie, ob das Verzeichnis /workspace bereitgestellt und sofort einsatzbereit ist:

export POD_NAME=$(kubectl get sandboxclaim agent-1-claim -o jsonpath='{.status.sandbox.name}')
kubectl exec $POD_NAME -- ls -la /workspace

Agentensitzung beenden

Um die Agentensitzung zu beenden und die beanspruchte Sandbox freizugeben, löschen Sie die SandboxClaim-Ressource:

kubectl delete sandboxclaim agent-1-claim

Ressourcen bereinigen

Löschen Sie den Sandbox Warm Pool und die Sandbox-Vorlage:

kubectl delete sandboxwarmpool stateless-warmpool
kubectl delete sandboxtemplate stateless-sandbox-template

Mit Start in mehreren Sekunden konfigurieren

Wenn Sie einen sitzungsspezifischen Arbeitsbereich implementieren möchten, der eine Latenz von mehreren Sekunden toleriert, verwenden Sie die direkte Erstellung der Agent Sandbox ohne Warm Pool.

Statuslose Agent Sandbox definieren

  1. Speichern Sie das folgende Manifest als sandbox-direct-stateless.yaml:

    apiVersion: agents.x-k8s.io/v1alpha1
    kind: Sandbox
    metadata:
      name: sandbox-direct-stateless
      namespace: default
    spec:
      replicas: 1
      podTemplate:
        spec:
          runtimeClassName: gvisor
          automountServiceAccountToken: false
          securityContext:
            runAsNonRoot: true
            runAsUser: 1000
            fsGroup: 1000 # Grant group access to the volume
          nodeSelector:
            sandbox.gke.io/runtime: gvisor
          tolerations:
          - key: "sandbox.gke.io/runtime"
            value: "gvisor"
            effect: "NoSchedule"
          containers:
          - name: agent
            image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0
            ports:
            - containerPort: 8888
            volumeMounts:
            - name: ephemeral-disk
              mountPath: /workspace
            resources:
              limits:
                cpu: "500m"
                memory: "1Gi" # Required
            securityContext:
              capabilities:
                drop: ["ALL"] # Required
          restartPolicy: OnFailure
      volumeClaimTemplates:
      - metadata:
          name: ephemeral-disk
        spec:
          accessModes: ["ReadWriteOnce"]
          storageClassName: dynamic-rwo
          resources:
            requests:
              storage: 10Gi
    

Agent Sandbox bereitstellen

Wenden Sie das Manifest an, um das Laufwerk dynamisch bereitzustellen und an den geplanten Knoten anzuhängen:

kubectl apply -f sandbox-direct-stateless.yaml

Startlatenz und Ausführung prüfen

Beobachten Sie den Pod-Status, um die Verzögerung beim Anhängen zu sehen, bevor der Pod in den Status Running wechselt:

kubectl get pods -w

Nachdem der Pod ausgeführt wurde, erfassen Sie den Pod-Namen und prüfen Sie, ob das Verzeichnis /workspace verfügbar ist:

POD_NAME=sandbox-direct-stateless
kubectl exec $POD_NAME -- ls -la /workspace

Agentensitzung beenden

Löschen Sie die Sandbox-Ressource, um den Pod automatisch zu beenden und den sitzungsspezifischen Speicher zu löschen:

kubectl delete sandbox sandbox-direct-stateless

Nächste Schritte