本文件提供參考實作,說明如何根據代理的資料生命週期需求,管理 GKE Agent Sandbox 的儲存空間。
視代理程式的資料生命週期需求而定,選擇下列其中一種設定:
如要進一步瞭解如何選擇儲存空間解決方案,請參閱「選擇 AI 代理工作負載的儲存空間」。
下列文件使用 dynamic-rwo StorageClass 進行自動磁碟類型選取,以佈建與節點機型相容的磁碟,而節點機型是 Agent Sandbox on GKE Pod 的排程位置。為確保 GKE 為代理的儲存空間佈建 Hyperdisk Balanced 磁碟區,您必須在相容機器家族 (例如 N4) 節點上的 GKE Pod 排定 Agent Sandbox,否則 GKE 會改用 pd-balanced。
本文會使用 ReadWriteOnce (RWO) 存取權,實作「私人隔離 Workspace」資料存取模式。在這個模式下,代理程式會啟動專屬的獨立儲存目錄,並擁有該目錄的讀取和寫入權限。
除非另有指定,否則本文件中的參考實作會使用直接建立沙箱,適用於可容忍多秒啟動延遲時間的代理。如要讓有狀態或時間點還原的工作區達到次秒級的啟動延遲,您必須使用 GKE Warm Pools 上的 Agent Sandbox。如要將儲存空間繫結至已認領的暖集區 Pod,必須使用自訂指令碼和具備特殊權限的 DaemonSet。如需實作參考,請參閱這個 GitHub 範例。
其他存取模式
如要支援替代存取模式,您可以修改設定中的磁碟區和快照定義:
- 協作工作區:將
accessModes變更為ReadWriteMany,並使用支援 RWX 的 StorageClass,例如 Filestore Multishares (Enterprise) (enterprise-multishare-rwx)。 - 探索分支工作區:以唯讀模式掛接範本資料夾,並提供獨立的可寫入暫存區。如要使用基礎範本,您必須使用支援多個唯讀附件的儲存空間,例如存取模式為
ReadOnlyMany(ROX) 的 Hyperdisk ML,或是存取模式為 RWX 的 Filestore Multishares。
事前準備
設定有狀態工作區
使用這個模式可保留代理程式檔案的最新狀態。當代理程式工作階段暫停或終止 (代理程式沙箱已刪除) 時,代理程式必須保留狀態,並在代理程式工作階段啟動 (代理程式沙箱已重新建立) 時,從最新狀態還原資料,這時這項功能就派上用場。
本節的參考實作會直接建立沙箱,適用於可容忍數秒啟動延遲時間的代理。
這種方法會使用標準 GKE PersistentVolumeClaim (PVC) 資源,將沙箱連結至含有使用者資料的現有 PVC。
有狀態的工作區模式會依序發生下列事件:
- 佈建:管理員或自動調度管理工具使用確定性 ID (例如
pvc-agent-1),手動為每個代理工作階段佈建私人 PVC。 - 參照:在 Sandbox 資源中,您可以使用
volumes區塊中的persistentVolumeClaim欄位,指定現有磁碟區的確切claimName。 - 延遲:建立沙箱時,GKE 必須將 Compute Engine 磁碟動態連接至節點 VM,這會導致標準的數秒延遲。
- 持續性:工作階段終止 (刪除沙箱) 時,GKE 會卸載磁碟,但不會刪除 PVC,確保下一個工作階段能保留最新狀態。
如要設定有狀態工作區,在工作階段之間保留資料,請完成下列子節中的步驟。
佈建永久工作區 (PVC)
建立使用確定性 ID 的私有 PersistentVolumeClaim (PVC),例如 pvc-agent-1。
將下列資訊清單儲存為
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
建立 VolumeSnapshotClass,指定 CSI 驅動程式和刪除政策。如果是 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
清除所用資源
刪除代理沙箱、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 時,不需要保留任何資料。
設定啟動時間少於一秒
在 GKE Warm Pool 上使用 Agent Sandbox,預先在背景佈建空白磁碟區。
定義 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
啟動沙箱暖集區
將下列資訊清單儲存為
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
清除所用資源
刪除沙箱暖集區和沙箱範本:
kubectl delete sandboxwarmpool stateless-warmpool
kubectl delete sandboxtemplate stateless-sandbox-template
設定多秒啟動
如要實作可容忍數秒延遲的臨時工作區,請直接建立代理沙箱,不要使用暖集區。
定義無狀態 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。
- 進一步瞭解如何在 GKE 上使用 Agent Sandbox 隔離 AI 執行程式碼作業。
- 瞭解如何使用 Pod 快照,在 GKE 環境中儲存及還原 Agent Sandbox。