Gestire lo spazio di archiviazione della sandbox dell'agente

Questo documento fornisce implementazioni di riferimento per la gestione dello spazio di archiviazione per le sandbox dell'agente personalizzate in base alle esigenze del ciclo di vita dei dati degli agenti.

A seconda delle esigenze del ciclo di vita dei dati degli agenti, scegli una delle seguenti configurazioni:

Per ulteriori informazioni sulla scelta di una soluzione di archiviazione, consulta Scegliere lo spazio di archiviazione per i carichi di lavoro degli agenti AI.

Il seguente documento utilizza la StorageClass dynamic-rwo per la selezione automatica del tipo di disco per il provisioning dei dischi compatibili con i tipi di macchina dei nodi in cui sono pianificati i pod della sandbox dell'agente. Per assicurarti che GKE esegua il provisioning dei volumi Hyperdisk bilanciati per lo spazio di archiviazione degli agenti, devi pianificare le sandbox dell'agente sui nodi delle famiglie di macchine compatibili, ad esempio N4. In caso contrario, GKE esegue il fallback a pd-balanced.

Questo documento implementa la modalità di accesso ai dati Spazio di lavoro privato isolato utilizzando l'accesso ReadWriteOnce (RWO). In questa modalità, un agente viene avviato con una directory di archiviazione privata isolata a cui ha accesso in lettura e scrittura.

Se non diversamente specificato, le implementazioni di riferimento in questo documento utilizzano la creazione diretta della sandbox, applicabile agli agenti che tollerano una latenza di avvio di più secondi. Per ottenere una latenza di avvio inferiore al secondo per gli spazi di lavoro stateful o di ripristino point-in-time, devi utilizzare i pool di pod pre-riscaldati della sandbox dell'agente GKE. L'associazione dello spazio di archiviazione a un pod del pool di pod pre-riscaldati richiesto richiede script personalizzati e un DaemonSet con privilegi. Per un'implementazione di riferimento, consulta questo esempio di GitHub.

Modalità di accesso alternative

Per supportare modalità di accesso alternative, puoi modificare le definizioni di volumi e snapshot nelle configurazioni:

  • Spazio di lavoro collaborativo: modifica accessModes in ReadWriteMany e utilizza una StorageClass con funzionalità RWX, ad esempio Filestore Multishares (Enterprise) (enterprise-multishare-rwx).
  • Spazio di lavoro di branching di esplorazione: monta la cartella del modello come di sola lettura e fornisci un blocco appunti scrivibile separato. Per il modello di base, devi utilizzare lo spazio di archiviazione che supporta più collegamenti di sola lettura, ad esempio Hyperdisk ML con ReadOnlyMany (ROX) modalità di accesso o Filestore Multishares con la modalità di accesso RWX.

Prima di iniziare

Abilita la sandbox dell'agente nel cluster.

Configurare uno spazio di lavoro stateful

Utilizza questo pattern per conservare l'ultimo stato dei file di un agente. È utile quando l'agente deve conservare lo stato quando la sessione dell'agente viene messa in pausa o terminata (la sandbox dell'agente viene eliminata) e ripristinare i dati dall'ultimo stato quando la sessione dell'agente viene attivata (la sandbox dell'agente viene ricreata).

L'implementazione di riferimento in questa sezione utilizza la creazione diretta della sandbox ed è applicabile agli agenti che tollerano una latenza di avvio di più secondi.

Questo approccio utilizza le risorse PersistentVolumeClaim (PVC) standard di GKE per collegare una sandbox a una PVC preesistente contenente i dati di un utente.

Il pattern dello spazio di lavoro stateful segue questa sequenza di eventi:

  1. Provisioning: l'amministratore o l'orchestratore esegue manualmente il provisioning di una PVC privata per ogni sessione dell'agente utilizzando un identificatore deterministico (ad esempio, pvc-agent-1).
  2. Riferimento: nella risorsa Sandbox, utilizza il persistentVolumeClaim campo all'interno del volumes blocco per specificare l' esatto claimName del volume esistente.
  3. Latenza: quando viene creata la sandbox, GKE deve collegare dinamicamente il disco Compute Engine alla VM del nodo, il che comporta un ritardo standard di più secondi.
  4. Persistenza: al termine della sessione (eliminazione della sandbox), GKE scollega il disco, ma non elimina la PVC, il che contribuisce a garantire che l'ultimo stato venga conservato per la sessione successiva.

Per configurare uno spazio di lavoro stateful che conservi i dati tra le sessioni, completa i passaggi nelle seguenti sottosezioni.

Eseguire il provisioning di uno spazio di lavoro permanente (PVC)

Crea una PersistentVolumeClaim (PVC) privata che utilizza un identificatore deterministico, ad esempio pvc-agent-1.

  1. Salva il seguente manifest come 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. Applica il manifest:

    kubectl apply -f pvc-agent-1.yaml
    

Poiché la classe di archiviazione utilizza l'associazione dinamica dei volumi, il disco non è ancora collegato a nessun nodo. Rimane nello stato Pending finché non viene pianificato un pod che lo richiede.

Eseguire il deployment della sandbox dell'agente

Esegui il deployment della risorsa personalizzata Sandbox, facendo riferimento alla PVC deterministica.

  1. Salva il seguente manifest come 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. Applica il manifest:

    kubectl apply -f sandbox-agent-1.yaml
    

GKE verifica la capacità del nodo e collega il disco, un'operazione che richiede alcuni secondi. Il container viene inizializzato all'interno di un kernel gVisor dello spazio utente.

Scrivere dati dall'agente

Simula un agente AI attivo che esegue modifiche ai file all'interno del suo spazio di lavoro scrivendo un file di testo sul disco montato.

# 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

Terminare la sessione dell'agente

Per simulare lo scale down o la terminazione della sessione quando l'agente diventa inattivo, elimina la risorsa Sandbox, ma conserva lo spazio di archiviazione sottostante.

kubectl delete sandbox sandbox-agent-1

GKE smonta e scollega il disco. La PVC pvc-agent-1 rimane, conservando i dati.

Riattivare la sessione dell'agente

Per riattivare la sessione, esegui di nuovo il deployment di una nuova risorsa Sandbox che fa riferimento alla stessa PVC.

kubectl apply -f sandbox-agent-1.yaml

Il disco viene ricollegato (con il ritardo di collegamento) e il container viene avviato.

Verificare la conservazione dei dati

Ispeziona il container della sandbox appena creato per verificare che i dati della sessione precedente siano stati conservati.

# 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

L'output dovrebbe mostrare Workspace State Saved - Agent 1.

Liberare spazio dalle risorse

Elimina la sandbox dell'agente e la richiesta di volume permanente associata:

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

Configurare un ripristino point-in-time e un trasferimento di proprietà

Utilizza questo pattern per clonare i set di dati per eseguire esperimenti paralleli, eseguire il debug o lavorare in modo indipendente. Lo spazio di lavoro di un agente viene inizializzato da un set di dati storico (o stato condiviso), salvando le modifiche successive in un livello scrivibile privato separato senza modificare il modello di base.

L'implementazione di riferimento in questa sezione utilizza la creazione diretta della sandbox ed è applicabile agli agenti che tollerano una latenza di avvio di più secondi. Questo approccio si basa sull'orchestratore per eseguire dinamicamente il provisioning di nuove PersistentVolumeClaim (PVC) da VolumeSnapshot storici prima di avviare una nuova sessione della sandbox.

Creare la VolumeSnapshotClass

Crea una VolumeSnapshotClass che specifichi il driver CSI e la politica di cancellazione. Per Hyperdisk, utilizza il driver pd.csi.storage.gke.io.

  1. Salva il seguente manifest come 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. Applica il manifest:

    kubectl apply -f 1-snapshot-class.yaml
    

Eseguire il provisioning dello spazio di lavoro iniziale

Crea un volume in cui l'agente eseguirà il suo lavoro iniziale.

  1. Salva il seguente manifest come 2-source-pvc.yaml:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: agent-source-pvc
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: dynamic-rwo
      resources:
        requests:
          storage: 10Gi
    
  2. Applica il manifest:

    kubectl apply -f 2-source-pvc.yaml
    

Generare dati di stato

Esegui il deployment di un pod della sandbox per scrivere dati nel volume.

  1. Salva il seguente manifest come 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. Applica il manifest:

    kubectl apply -f 3-source-sandbox.yaml
    
  3. Attendi che il pod sia in esecuzione, quindi scrivi un file di stato:

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

Archiviare lo stato storico (CSI VolumeSnapshot)

Attiva un CSI VolumeSnapshot per bloccare lo stato attuale. Quando acquisisci uno snapshot, segui le best practice per gli snapshot dei dischi.

  1. Salva il seguente manifest come 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. Applica il manifest:

    kubectl apply -f 4-volume-snapshot.yaml
    

Ripristinare il volume dallo snapshot

Esegui il deployment di una nuova PVC con il relativo dataSource che punta al CSI VolumeSnapshot.

  1. Salva il seguente manifest come 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. Applica il manifest:

    kubectl apply -f 5-restored-pvc.yaml
    

Avviare la sessione della sandbox dell'agente ripristinata

Esegui il provisioning di una nuova risorsa Sandbox che fa riferimento alla PVC appena ripristinata.

  1. Salva il seguente manifest come 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. Applica il manifest:

    kubectl apply -f 6-restored-sandbox.yaml
    

Verificare la persistenza e il ripristino

Verifica che l'agente possa leggere i dati storici.

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

Output previsto: Point-in-Time Snapshot - v1

Liberare spazio dalle risorse

Elimina le sandbox dell'agente, le PVC e 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

Configurare uno spazio di lavoro temporaneo

Utilizza il pattern dello spazio di lavoro temporaneo quando un agente ha bisogno di un volume di archiviazione per archiviare i file temporanei mentre l'agente è attivo. Non è necessario conservare i dati durante l'eliminazione della sandbox dell'agente.

Configurare con avvio inferiore al secondo

Utilizza i pool di pod pre-riscaldati della sandbox dell'agente per eseguire il provisioning preliminare dei volumi vuoti in background.

Definire SandboxTemplate

Definisci il backup dello spazio di archiviazione temporaneo all'interno del blocco volumeClaimTemplate.

  1. Salva il seguente manifest come 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
    

Avviare il pool di pod pre-riscaldati della sandbox

  1. Salva il seguente manifest come 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. Applica entrambi i manifest:

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

Richiedere la sandbox

Definisci una SandboxClaim che si attiva quando un utente avvia una sessione.

  1. Salva il seguente manifest come 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. Applica il manifest:

    kubectl apply -f stateless-sandbox-claim.yaml
    

Verificare l'esecuzione inferiore al secondo

Acquisisci il nome del pod della sandbox dell'agente e verifica che la directory /workspace sia montata e pronta per l'uso immediato:

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

Terminare la sessione dell'agente

Per terminare la sessione dell'agente e rilasciare la sandbox richiesta, elimina la risorsa SandboxClaim:

kubectl delete sandboxclaim agent-1-claim

Liberare spazio dalle risorse

Elimina il pool di pod pre-riscaldati della sandbox e il modello della sandbox:

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

Configurare con avvio di più secondi

Per implementare uno spazio di lavoro temporaneo che tollera una latenza di più secondi, utilizza la creazione diretta della sandbox dell'agente senza un pool di pod pre-riscaldati.

Definire una sandbox dell'agente senza stato

  1. Salva il seguente manifest come 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
    

Eseguire il deployment della sandbox dell'agente

Per eseguire dinamicamente il provisioning del disco e collegarlo al nodo pianificato, applica il manifest:

kubectl apply -f sandbox-direct-stateless.yaml

Verificare la latenza di avvio e l'esecuzione

Monitora lo stato del pod per osservare il ritardo di collegamento prima che il pod passi allo stato Running:

kubectl get pods -w

Dopo che il pod è in esecuzione, acquisisci il nome del pod e verifica che la directory /workspace sia disponibile:

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

Terminare la sessione dell'agente

Elimina la risorsa Sandbox per terminare automaticamente il pod ed eliminare lo spazio di archiviazione temporaneo:

kubectl delete sandbox sandbox-direct-stateless

Passaggi successivi