本文档提供了用于管理智能体沙盒存储的参考实现,这些实现根据智能体的数据生命周期需求量身定制。
根据智能体的数据生命周期需求,选择以下配置之一:
如需详细了解如何选择存储解决方案,请参阅 为 AI 智能体工作负载选择存储。
以下文档使用 dynamic-rwo StorageClass 进行 自动磁盘类型
选择
,以预配与安排 Agent Sandbox
Pod 的节点机器类型兼容的磁盘。为帮助确保 GKE 为智能体的存储预配
Hyperdisk Balanced 卷,您必须
在 兼容机器
系列(例如 N4)的节点上安排 Agent Sandbox;否则,GKE 会回退到 pd-balanced。
本文档通过使用 ReadWriteOnce (RWO) 访问权限实现“专用隔离工作区”数据访问模式。 在此模式下,智能体启动时会使用一个专用隔离存储目录,该目录具有专属的读写权限。
除非另有说明,否则本文档中的参考实现使用 直接沙盒创建,适用于可容忍多秒启动延迟的智能体。如需为有状态或时间点恢复工作区实现亚秒级启动延迟,您必须使用 GKE Agent Sandbox Warm Pools。将存储绑定到已声明的 Warm Pool Pod 需要自定义脚本和具有特权的 DaemonSet。如需查看参考实现,请参阅此 GitHub 示例。
替代访问模式
如需支持替代访问模式,您可以修改配置中的卷和快照定义:
- 协作工作区:将
accessModes更改为ReadWriteMany,并 使用支持 RWX 的 StorageClass,例如 Filestore Multishares (Enterprise) (enterprise-multishare-rwx)。 - 探索分支工作区:将
模板文件夹装载为只读,并提供单独的可写草稿本。
对于基本模板,您必须使用支持多个只读
挂接的存储,例如具有 Hyperdisk ML
ReadOnlyMany(ROX) 访问模式的 Hyperdisk ML 或具有 RWX 访问模式的 Filestore Multishares。
准备工作
配置有状态工作区
使用此模式可保留智能体文件的最新状态。当智能体必须在智能体会话暂停或终止(Agent Sandbox 被删除)时保留状态,并在智能体会话激活(Agent Sandbox 被重新创建)时从最新状态恢复数据时,此模式非常有用。
本部分中的参考实现使用直接沙盒创建,适用于可容忍多秒启动延迟的智能体。
此方法使用标准 GKE PersistentVolumeClaim (PVC) 资源将沙盒链接到包含用户数据的预先存在的 PVC。
有状态工作区模式遵循以下事件序列:
- 预配:管理员或编排器使用确定性标识符(例如
pvc-agent-1)为每个智能体会话手动预配 专用 PVC。 - 引用:在 Sandbox 资源中,您可以使用
persistentVolumeClaim块中的volumes字段来指定现有卷的 确切claimName。 - 延迟时间:创建沙盒时,GKE 必须 将 Compute Engine 磁盘动态挂接到节点虚拟机, 这会产生标准的多秒延迟。
- 持久性:在会话终止(删除沙盒)时, GKE 会分离磁盘,但不会销毁 PVC,这有助于确保 为下一个会话保留最新状态。
如需配置在会话之间保留数据的有状态工作区,请完成以下子部分中的步骤。
预配永久性工作区 (PVC)
创建一个使用确定性标识符(例如 pvc-agent-1)的专用 PersistentVolumeClaim (PVC)。
将以下清单保存为
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应用清单:
kubectl apply -f pvc-agent-1.yaml
由于存储类别使用动态卷绑定,因此磁盘尚未挂接到任何节点。在安排请求该磁盘的 Pod 之前,它将保持 Pending 状态。
部署 Agent Sandbox
部署 Sandbox 自定义资源,引用确定性 PVC。
将以下清单保存为
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应用清单:
kubectl apply -f sandbox-agent-1.yaml
GKE 会验证节点容量并挂接磁盘,这需要几秒钟时间。容器在用户空间 gVisor 内核中初始化。
从智能体写入数据
通过将文本文件写入装载的磁盘,模拟在其工作区内执行文件修改的活跃 AI 智能体。
# 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
结束智能体会话
如需在智能体处于空闲状态时模拟缩减或终止会话,请删除 Sandbox 资源,但保留底层存储。
kubectl delete sandbox sandbox-agent-1
GKE 会卸载并分离磁盘。pvc-agent-1 PVC 仍保留,并保留数据。
重新激活智能体会话
如需重新激活会话,请重新部署引用同一 PVC 的新 Sandbox 资源。
kubectl apply -f sandbox-agent-1.yaml
磁盘会重新挂接(产生挂接延迟),并且容器会启动。
验证数据保留
检查新创建的沙盒容器,以验证是否保留了之前的会话数据。
# 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
输出应显示 Workspace State Saved - Agent 1。
清理资源
删除 Agent Sandbox 和关联的永久性卷声明:
kubectl delete sandbox sandbox-agent-1
kubectl delete pvc pvc-agent-1
配置时间点恢复和所有权转移
使用此模式可克隆数据集,以运行并行实验、调试或独立工作。智能体的工作区从历史数据集(或共享状态)初始化,并将后续修改保存到单独的专用可写层,而无需修改基本模板。
本部分中的参考实现使用直接沙盒创建,适用于可容忍多秒启动延迟的智能体。此方法依赖于编排器在启动新的沙盒会话之前,从历史 VolumeSnapshot 动态预配新的 PersistentVolumeClaim (PVC)。
创建 VolumeSnapshotClass
创建一个指定 CSI 驱动程序和删除政策的 VolumeSnapshotClass。
对于 Hyperdisk,请使用 pd.csi.storage.gke.io 驱动程序。
将以下清单保存为
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应用清单:
kubectl apply -f 1-snapshot-class.yaml
预配初始工作区
创建一个卷,智能体将在其中执行其初始工作。
将以下清单保存为
2-source-pvc.yaml:apiVersion: v1 kind: PersistentVolumeClaim metadata: name: agent-source-pvc spec: accessModes: ["ReadWriteOnce"] storageClassName: dynamic-rwo resources: requests: storage: 10Gi应用清单:
kubectl apply -f 2-source-pvc.yaml
生成状态数据
部署沙盒 Pod 以将数据写入卷。
将以下清单保存为
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应用清单:
kubectl apply -f 3-source-sandbox.yaml等待 Pod 运行,然后写入状态文件:
POD_NAME=agent-session-v1 kubectl exec $POD_NAME -- sh -c "echo 'Point-in-Time Snapshot - v1' > /workspace/state.txt"
归档历史状态 (CSI VolumeSnapshot)
触发 CSI VolumeSnapshot 以冻结当前状态。拍摄快照时,请遵循磁盘快照的最佳实践。
将以下清单保存为
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应用清单:
kubectl apply -f 4-volume-snapshot.yaml
从快照恢复卷
部署一个新 PVC,其 dataSource 指向 CSI VolumeSnapshot。
将以下清单保存为
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应用清单:
kubectl apply -f 5-restored-pvc.yaml
启动恢复的 Agent Sandbox 会话
预配引用新恢复的 PVC 的新 Sandbox 资源。
将以下清单保存为
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应用清单:
kubectl apply -f 6-restored-sandbox.yaml
验证持久性和恢复
验证智能体是否可以读取历史数据。
NEW_POD_NAME=agent-session-v2-restored
kubectl exec $NEW_POD_NAME -- cat /workspace/state.txt
预期输出:Point-in-Time Snapshot - v1
清理资源
删除 Agent Sandbox、PVC 和 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
配置临时工作区
当智能体在活跃期间需要存储卷来存储临时文件时,请使用临时工作区模式。在删除 Agent Sandbox 时,无需保留任何数据。
配置亚秒级启动
使用 Agent Sandbox Warm Pools 在后台预配空卷。
定义 SandboxTemplate
在 volumeClaimTemplate 块中定义临时存储后备。
将以下清单保存为
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
将以下清单保存为
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应用这两个清单:
kubectl apply -f stateless-template.yaml kubectl apply -f stateless-warmpool.yaml
声明沙盒
定义在用户启动会话时触发的 SandboxClaim。
将以下清单保存为
stateless-sandbox-claim.yaml:apiVersion: extensions.agents.x-k8s.io/v1alpha1 kind: SandboxClaim metadata: name: agent-1-claim spec: sandboxTemplateRef: name: stateless-sandbox-template应用清单:
kubectl apply -f stateless-sandbox-claim.yaml
验证亚秒级执行
捕获 Agent Sandbox Pod 名称,并验证是否装载了 /workspace 目录且可供立即使用:
export POD_NAME=$(kubectl get sandboxclaim agent-1-claim -o jsonpath='{.status.sandbox.name}')
kubectl exec $POD_NAME -- ls -la /workspace
终止智能体会话
如需结束智能体会话并释放已声明的沙盒,请删除 SandboxClaim 资源:
kubectl delete sandboxclaim agent-1-claim
清理资源
删除 Sandbox Warm Pool 和 Sandbox 模板:
kubectl delete sandboxwarmpool stateless-warmpool
kubectl delete sandboxtemplate stateless-sandbox-template
配置多秒启动
如需实现可容忍多秒延迟的临时工作区,请使用直接 Agent Sandbox 创建,而无需使用 Warm Pool。
定义无状态 Agent Sandbox
将以下清单保存为
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
如需动态预配磁盘并将其挂接到已安排的节点,请应用清单:
kubectl apply -f sandbox-direct-stateless.yaml
验证启动延迟时间和执行
监控 Pod 状态,以观察 Pod 转换为 Running 状态之前的挂接延迟:
kubectl get pods -w
Pod 运行后,捕获 Pod 名称并验证 /workspace 目录是否可用:
POD_NAME=sandbox-direct-stateless
kubectl exec $POD_NAME -- ls -la /workspace
终止智能体会话
删除 Sandbox 资源以自动终止 Pod 并销毁其临时存储:
kubectl delete sandbox sandbox-direct-stateless
后续步骤
- 详细了解 GKE Agent Sandbox。
- 详细了解如何使用 Agent Sandbox 隔离 AI 代码执行。
- 了解如何使用 Pod 快照保存和恢复 Agent Sandbox 环境。