Administra Agent Sandbox en el almacenamiento de GKE

En este documento, se proporcionan implementaciones de referencia para administrar el almacenamiento de Agent Sandbox en GKE adaptadas a las necesidades del ciclo de vida de los datos de tus agentes.

Según las necesidades del ciclo de vida de los datos de tus agentes, elige una de las siguientes configuraciones:

Para obtener más información sobre cómo elegir una solución de almacenamiento, consulta Elige el almacenamiento para las cargas de trabajo de agentes de IA.

En el siguiente documento, se usa la StorageClass dynamic-rwo para la selección automática del tipo de disco para aprovisionar discos compatibles con los tipos de máquinas de los nodos en los que se programan los Pods de Agent Sandbox en GKE. Para asegurarte de que GKE aprovisione volúmenes de Hyperdisk Balanced para el almacenamiento de tus agentes, debes programar tus Pods de Agent Sandbox en GKE en los nodos de familias de máquinas compatibles, como N4; de lo contrario, GKE recurre a pd-balanced.

En este documento, se implementa el modo de acceso a los datos Espacio de trabajo aislado privado mediante el acceso ReadWriteOnce (RWO). En este modo, un agente se inicia con un directorio de almacenamiento aislado privado al que solo tiene acceso de lectura y escritura.

A menos que se especifique lo contrario, las implementaciones de referencia de este documento usan la creación directa de zonas de pruebas, que se aplica a los agentes que toleran la latencia de inicio de varios segundos. Para lograr una latencia de inicio de menos de un segundo para los espacios de trabajo con estado o de restauración de un momento determinado, debes usar Agent Sandbox en los grupos de instancias precalentadas de GKE. Para vincular el almacenamiento a un Pod de grupo de instancias precalentadas reclamado, se requieren secuencias de comandos personalizadas y un DaemonSet con privilegios. Para obtener una implementación de referencia, consulta este ejemplo de GitHub.

Modos de acceso alternativos

Para admitir modos de acceso alternativos, puedes modificar las definiciones de volumen y de instantáneas en las configuraciones:

  • Espacio de trabajo colaborativo: cambia accessModes a ReadWriteMany y usa una StorageClass compatible con RWX, como Filestore Multishares (Enterprise) (enterprise-multishare-rwx).
  • Espacio de trabajo de bifurcación de exploración: Activa la carpeta de la plantilla como de solo lectura y proporciona un bloc de notas borrable independiente. Para la plantilla base, debes usar almacenamiento que admita varias conexiones de solo lectura, como Hyperdisk ML con ReadOnlyMany (ROX) modo de acceso o Filestore Multishares con el modo de acceso RWX.

Antes de comenzar

Habilita Agent Sandbox en GKE en tu clúster.

Configura un espacio de trabajo con estado

Usa este patrón para conservar el estado más reciente de los archivos de un agente. Es útil cuando tu agente debe conservar el estado cuando se pausa o finaliza la sesión del agente (se borra Agent Sandbox) y restablecer los datos del estado más reciente cuando se activa la sesión del agente (se vuelve a crear Agent Sandbox).

La implementación de referencia de esta sección usa la creación directa de zonas de pruebas y se aplica a los agentes que toleran la latencia de inicio de varios segundos.

Este enfoque usa recursos estándar de PersistentVolumeClaim (PVC) de GKE para vincular una zona de pruebas a una PVC preexistente que contiene los datos de un usuario.

El patrón de espacio de trabajo con estado sigue esta secuencia de eventos:

  1. Aprovisionamiento: El administrador o el organizador aprovisionan de forma manual una PVC privada para cada sesión del agente con un identificador determinista (por ejemplo, pvc-agent-1).
  2. Referencia: En el recurso de Sandbox, usa el persistentVolumeClaim campo dentro del volumes bloque para especificar el exacto claimName del volumen existente.
  3. Latencia: Cuando se crea la zona de pruebas, GKE debe conectar de forma dinámica el disco de Compute Engine a la VM del nodo, lo que genera una demora estándar de varios segundos.
  4. Persistencia: Cuando finaliza la sesión (se borra la zona de pruebas), GKE desconecta el disco, pero no destruye la PVC, lo que ayuda a garantizar que se conserve el estado más reciente para la próxima sesión.

Para configurar un espacio de trabajo con estado que conserve los datos entre sesiones, completa los pasos de las siguientes subsecciones.

Aprovisiona un espacio de trabajo persistente (PVC)

Crea una PersistentVolumeClaim (PVC) privada que use un identificador determinista, como pvc-agent-1.

  1. Guarda el siguiente manifiesto como 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. Aplica el manifiesto

    kubectl apply -f pvc-agent-1.yaml
    

Debido a que la clase de almacenamiento usa la vinculación de volumen dinámico, el disco aún no está conectado a ningún nodo. Permanece en estado Pending hasta que se programa un Pod que lo solicite.

Implementa Agent Sandbox

Implementa el recurso personalizado de Sandbox, que hace referencia a la PVC determinista.

  1. Guarda el siguiente manifiesto como 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. Aplica el manifiesto

    kubectl apply -f sandbox-agent-1.yaml
    

GKE verifica la capacidad del nodo y conecta el disco, lo que tarda unos segundos. El contenedor se inicializa dentro de un kernel de gVisor del espacio de usuario.

Escribe datos desde el agente

Para simular un agente de IA activo que ejecuta modificaciones de archivos dentro de su espacio de trabajo, escribe un archivo de texto en el disco activado.

# 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

Finaliza la sesión del agente

Para simular la reducción o la finalización de la sesión cuando el agente está inactivo, borra el recurso de Sandbox, pero conserva el almacenamiento subyacente.

kubectl delete sandbox sandbox-agent-1

GKE desactiva y desconecta el disco. La PVC pvc-agent-1 permanece y conserva los datos.

Reactiva la sesión del agente

Para reactivar la sesión, vuelve a implementar un recurso de Sandbox nuevo que haga referencia a la misma PVC.

kubectl apply -f sandbox-agent-1.yaml

El disco se vuelve a conectar (lo que genera la demora de conexión) y se inicia el contenedor.

Verifica la conservación de datos

Inspecciona el contenedor de la zona de pruebas recién creado para verificar que se hayan conservado los datos de la sesión anterior.

# 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

El resultado debería mostrar Workspace State Saved - Agent 1.

Limpia los recursos

Borra Agent Sandbox y la reclamación de volumen persistente asociada:

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

Configura una restauración de un momento determinado y una transferencia de propiedad

Usa este patrón para clonar conjuntos de datos para ejecutar experimentos paralelos, depurar o trabajar de forma independiente. El espacio de trabajo de un agente se inicializa a partir de un conjunto de datos históricos (o estado compartido), y guarda las modificaciones posteriores en una capa borrable privada independiente sin modificar la plantilla base.

La implementación de referencia de esta sección usa la creación directa de zonas de pruebas y se aplica a los agentes que toleran la latencia de inicio de varios segundos. Este enfoque se basa en el organizador para aprovisionar de forma dinámica PersistentVolumeClaims (PVCs) nuevas a partir de VolumeSnapshots históricas antes de iniciar una sesión de zona de pruebas nueva.

Crea la VolumeSnapshotClass

Crea una VolumeSnapshotClass que especifique el controlador CSI y la política de eliminación. Para Hyperdisk, usa el controlador pd.csi.storage.gke.io.

  1. Guarda el siguiente manifiesto como 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. Aplica el manifiesto

    kubectl apply -f 1-snapshot-class.yaml
    

Aprovisiona el espacio de trabajo inicial

Crea un volumen en el que el agente realizará su trabajo inicial.

  1. Guarda el siguiente manifiesto como 2-source-pvc.yaml:

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

    kubectl apply -f 2-source-pvc.yaml
    

Genera datos de estado

Implementa un Pod de zona de pruebas para escribir datos en el volumen.

  1. Guarda el siguiente manifiesto como 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. Aplica el manifiesto

    kubectl apply -f 3-source-sandbox.yaml
    
  3. Espera a que el Pod esté en ejecución y, luego, escribe un archivo de estado:

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

Archiva el estado histórico (VolumeSnapshot de CSI)

Activa una VolumeSnapshot de CSI para inmovilizar el estado actual. Cuando tomes una instantánea, sigue las prácticas recomendadas para las instantáneas de discos.

  1. Guarda el siguiente manifiesto como 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. Aplica el manifiesto

    kubectl apply -f 4-volume-snapshot.yaml
    

Restablece el volumen a partir de la instantánea

Implementa una PVC nueva con su dataSource que apunte a la VolumeSnapshot de CSI.

  1. Guarda el siguiente manifiesto como 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. Aplica el manifiesto

    kubectl apply -f 5-restored-pvc.yaml
    

Inicia la sesión de Agent Sandbox restablecida

Aprovisiona un recurso de Sandbox nuevo que haga referencia a la PVC recién restablecida.

  1. Guarda el siguiente manifiesto como 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. Aplica el manifiesto

    kubectl apply -f 6-restored-sandbox.yaml
    

Verifica la persistencia y el restablecimiento

Verifica que el agente pueda leer los datos históricos.

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

Resultado esperado: Point-in-Time Snapshot - v1

Limpia los recursos

Borra Agent Sandboxes, las PVCs y la 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

Configura un espacio de trabajo efímero

Usa el patrón de espacio de trabajo efímero cuando un agente necesita un volumen de almacenamiento para almacenar archivos temporales mientras está activo. No es necesario conservar datos cuando se borra Agent Sandbox.

Configura con inicio de menos de un segundo

Usa Agent Sandbox en los grupos de instancias precalentadas de GKE para aprovisionar previamente volúmenes vacíos en segundo plano.

Define la SandboxTemplate

Define el almacenamiento efímero de respaldo dentro del bloque volumeClaimTemplate.

  1. Guarda el siguiente manifiesto como 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
    

Inicia el grupo de instancias precalentadas de Sandbox

  1. Guarda el siguiente manifiesto como 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. Aplica ambos manifiestos:

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

Reclama la zona de pruebas

Define una SandboxClaim que se active cuando un usuario inicia una sesión.

  1. Guarda el siguiente manifiesto como 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. Aplica el manifiesto

    kubectl apply -f stateless-sandbox-claim.yaml
    

Verifica la ejecución de menos de un segundo

Captura el nombre del Pod de Agent Sandbox y verifica que el directorio /workspace esté activado y listo para usarse de inmediato:

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

Finaliza la sesión del agente

Para finalizar la sesión del agente y liberar la zona de pruebas reclamada, borra el recurso de SandboxClaim:

kubectl delete sandboxclaim agent-1-claim

Limpia los recursos

Borra el grupo de instancias precalentadas de Sandbox y la plantilla de Sandbox:

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

Configura con inicio de varios segundos

Para implementar un espacio de trabajo efímero que tolere la latencia de varios segundos, usa la creación directa de Agent Sandbox sin un grupo de instancias precalentadas.

Define una Agent Sandbox sin estado

  1. Guarda el siguiente manifiesto como 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
    

Implementa Agent Sandbox

Para aprovisionar el disco de forma dinámica y conectarlo al nodo programado, aplica el manifiesto:

kubectl apply -f sandbox-direct-stateless.yaml

Verifica la latencia de inicio y la ejecución

Supervisa el estado del Pod para observar la demora de conexión antes de que el Pod pase al estado Running:

kubectl get pods -w

Una vez que el Pod esté en ejecución, captura el nombre del Pod y verifica que el directorio /workspace esté disponible:

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

Finaliza la sesión del agente

Borra el recurso de Sandbox para finalizar automáticamente el Pod y destruir su almacenamiento efímero:

kubectl delete sandbox sandbox-direct-stateless

¿Qué sigue?