Speicherplatz für Agent Sandbox verwalten

In diesem Dokument finden Sie Referenzimplementierungen für die Verwaltung von Speicher für Agent-Sandboxes, die auf die Anforderungen des Datenlebenszyklus Ihrer Agents zugeschnitten sind.

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

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

Im folgenden Dokument wird die StorageClass dynamic-rwo für die automatische Auswahl des Festplattentyps verwendet, um Laufwerke bereitzustellen, die mit den Maschinentypen der Knoten kompatibel sind, auf denen Agent-Sandbox-Pods geplant sind. Damit GKE Hyperdisk Balanced-Volumes für den Speicher Ihrer Agents bereitstellt, müssen Sie Ihre Agent-Sandboxes auf den Knoten kompatibler Maschinen familien 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 Agents geeignet ist, die eine Startlatenz von mehreren Sekunden tolerieren. Um eine Startlatenz von weniger als einer Sekunde für zustandsorientierte oder wiederherstellungsfähige Arbeitsbereiche zu erzielen, müssen Sie GKE Agent Sandbox Warm Pools verwenden. Das Binden von Speicher an einen beanspruchten Warm Pool-Pod erfordert benutzerdefiniertes Scripting und ein privilegiertes DaemonSet. Eine Referenzimplementierung finden Sie in diesem GitHub-Beispiel.

Alternative Zugriffsmodi

Zur Unterstützung alternativer Zugriffsmodi 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 Tests: Stellen Sie den Vorlagenordner schreibgeschützt 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 die Agent-Sandbox in Ihrem Cluster.

Zustandsorientierten Arbeitsbereich konfigurieren

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

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

Bei diesem Ansatz werden standardmäßige 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 zustandsorientierte Arbeitsbereiche folgt dieser Ereignisreihenfolge:

  1. Bereitstellung: Der Administrator oder Orchestrator stellt manuell einen privaten PVC für jede Agentsitzung mit einer deterministischen ID bereit (z. B. pvc-agent-1).
  2. Referenzierung: In der Sandbox-Ressource geben Sie im Block volumes mit dem Feld persistentVolumeClaim den genauen claimName des vorhandenen Volumes an.
  3. Latenz: Wenn die Sandbox erstellt wird, muss GKE die Compute Engine-Festplatte dynamisch an die Knoten-VM anhängen, was zu einer standardmäßigen Verzögerung von mehreren Sekunden führt.
  4. Persistenz: Bei Beendigung der Sitzung (Löschen der Sandbox) trennt GKE die Festplatte, 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 zustandsorientierten Arbeitsbereich zu konfigurieren, in dem Daten zwischen Sitzungen beibehalten werden.

Nichtflüchtigen Arbeitsbereich (PVC) 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 die Festplatte noch nicht an einen Knoten angehängt. Sie bleibt im Status Pending, bis ein Pod, der sie 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. Das dauert einige Sekunden. Der Container wird in einem gVisor-Kernel im Nutzerbereich initialisiert.

Daten vom Agent schreiben

Simulieren Sie einen aktiven KI-Agent, der Dateimodifikationen in seinem Arbeitsbereich ausführt, indem Sie eine Textdatei auf die bereitgestellte Festplatte 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

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

Agentsitzung wieder aktivieren

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

kubectl apply -f sandbox-agent-1.yaml

Die Festplatte 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 Eigentumsübertragung konfigurieren

Verwenden Sie dieses Muster, um Datasets für parallele Tests, Debugging oder unabhängige Arbeit zu klonen. Der Arbeitsbereich eines Agents 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 Agents 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 historischen Daten 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 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

Agentsitzung beenden

Um die Agentsitzung 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.

Zustandslose 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

Überwachen Sie den Pod-Status, um die Verzögerung beim Anhängen zu beobachten, 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

Agentsitzung 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