本文說明如何在 Google Kubernetes Engine (GKE) 叢集的獨立沙箱中,執行 AI 生成的程式碼。您可以在叢集上建立沙箱範本和現成沙箱集區。接著,您會執行 Python 指令碼,從集區要求沙箱,並在沙箱中執行指令。指令碼會使用 Agent Sandbox Python 用戶端,這個程式庫可用於建立及管理沙箱。
在沙箱中執行不受信任的程式碼,有助於保護系統免受 AI 生成程式碼中的潛在安全漏洞影響、加快開發速度,並提升部署作業的安全性。如要概略瞭解 GKE 的 Agent Sandbox 如何隔離不受信任的 AI 生成程式碼,請參閱「關於 GKE 的 Agent Sandbox」。
費用
GKE 的 Agent Sandbox 是開放原始碼軟體,無須額外付費即可使用。您建立的資源 (包括 Agent Sandbox 控制器使用的運算資源) 適用 GKE 定價。
事前準備
-
在 Google Cloud 控制台的專案選取器頁面中,選取或建立 Google Cloud 專案。
選取或建立專案所需的角色
- 選取專案:選取專案時,不需具備特定 IAM 角色,只要您已獲派某個專案的角色,即可選取該專案。
-
建立專案:如要建立專案,您必須具備專案建立者角色 (
roles/resourcemanager.projectCreator),其中包含resourcemanager.projects.create權限。瞭解如何授予角色。
啟用 Kubernetes Engine API (如果尚未啟用)。
啟用 API 所需的角色
您必須具備
serviceusage.services.enable權限,才能啟用 API。如果您建立了專案,可能已透過擁有者角色 (roles/owner) 取得這項權限。否則,您可以透過 Service Usage 管理員角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色。-
在 Google Cloud 控制台啟用 Cloud Shell。
- 確認您具備所需的權限,可完成本文件中的操作。
- 請確認 GKE 叢集已安裝 Agent Sandbox 控制器,並部署 Sandbox Router。如果沒有,請僅完成「在 GKE 上安裝 Agent Sandbox」的下列部分,然後返回本文件:
您不需要完成該文件的其他部分,例如「部署沙箱環境」。
在本文件的後續部分,您將建立自己的
SandboxTemplate和SandboxWarmPool資源。
必要的角色
如要取得建立及管理沙箱所需的權限,請要求管理員授予您專案的 Kubernetes Engine 管理員 (roles/container.admin) IAM 角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。
定義環境變數
為簡化您在本文件中執行的指令,您可以在 Cloud Shell 中設定環境變數。在 Cloud Shell 執行下列指令,定義下列實用的環境變數:
export CLUSTER_NAME="agent-sandbox-cluster"
export LOCATION="us-central1"
以下說明這些環境變數:
CLUSTER_NAME:GKE 叢集的名稱,例如agent-sandbox-cluster。LOCATION:GKE 叢集所在的 Google Cloud 區域或可用區。如果您使用 Autopilot 叢集,請將此值設為區域 (例如us-central1)。如果您使用 Standard 叢集,請將此值設為可用區 (例如us-central1-a)。
部署沙箱環境
本節說明如何建立沙箱藍圖 (SandboxTemplate 資源)、驗證網路路由器,以及安裝用於與沙箱互動的 Python 用戶端。
建議使用 Agentic Sandbox Python 用戶端建立沙箱並與其互動。這個用戶端提供介面,可簡化沙箱的整個生命週期,從建立到清理都涵蓋在內。這是一個 Python 程式庫,可用於透過程式輔助方式建立、使用及刪除沙箱。
用戶端會使用沙箱路由器做為所有流量的中央進入點。在本文件所述的範例中,用戶端會使用 kubectl port-forward 指令建立連至這個路由器的通道,因此您不必公開任何公開 IP 位址。請注意,使用 kubectl port-forward 並非安全的解決方案,應僅限於開發環境使用。
建立 SandboxTemplate 和 SandboxWarmPool 資源
現在,請建立 SandboxTemplate 資源和 SandboxWarmPool 資源,定義沙箱設定。SandboxTemplate 資源可做為可重複使用的藍圖,Agent Sandbox 控制器會使用該藍圖建立一致、預先設定的沙箱環境。SandboxWarmPool 資源可確保指定數量的預熱 Pod 隨時都在運作,並可供宣告。預熱沙箱是已初始化的執行中 Pod。這項預先初始化作業可讓系統在一秒內建立新的沙箱,並避免啟動一般沙箱時的啟動延遲:
在 Cloud Shell 中,建立名為
sandbox-template-and-pool.yaml的檔案,並加入下列內容:apiVersion: extensions.agents.x-k8s.io/v1beta1 kind: SandboxTemplate metadata: name: python-sandbox-template namespace: default spec: podTemplate: metadata: labels: sandbox: python-sandbox-example spec: runtimeClassName: gvisor automountServiceAccountToken: false # Required securityContext: runAsNonRoot: true # Required nodeSelector: sandbox.gke.io/runtime: gvisor # Required tolerations: - key: "sandbox.gke.io/runtime" value: "gvisor" effect: "NoSchedule" # Required containers: - name: python-runtime image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0 ports: - containerPort: 8888 readinessProbe: httpGet: path: "/" port: 8888 initialDelaySeconds: 0 periodSeconds: 1 resources: requests: cpu: "250m" memory: "512Mi" limits: cpu: "500m" memory: "1Gi" # Required securityContext: capabilities: drop: ["ALL"] # Required restartPolicy: "OnFailure" --- apiVersion: extensions.agents.x-k8s.io/v1beta1 kind: SandboxWarmPool metadata: name: python-sandbox-warmpool namespace: default spec: replicas: 2 sandboxTemplateRef: name: python-sandbox-template套用
SandboxTemplate和SandboxWarmPool資訊清單:kubectl apply -f sandbox-template-and-pool.yaml等待暖集區的沙箱準備就緒:
kubectl wait sandboxwarmpool python-sandbox-warmpool \ --for=jsonpath='{.status.readyReplicas}'=2 \ --timeout=600s在本文件後續部分,Python 用戶端會建立
SandboxClaim資源。如果用戶端在集區的沙箱準備就緒前建立宣告,控制器可能會為宣告建立新的沙箱,而不是從集區指派沙箱。在 Autopilot 叢集中,沙箱可能需要幾分鐘才能準備就緒,因為 GKE 可能需要為沙箱建立節點。
驗證沙箱路由器
您將使用 Python 用戶端建立沙箱環境並與之互動,該用戶端會使用名為 Sandbox Router 的元件與沙箱通訊。
在本範例中,您將使用用戶端的開發人員模式進行測試。這個模式適用於本機開發,並使用 kubectl port-forward 指令,從本機電腦建立直接通道,連至叢集中執行的 Sandbox Router 服務。這種通道方法可避免需要公開 IP 位址或複雜的輸入設定,並簡化與本機環境沙箱的互動。
確認 Sandbox Router 是否在 agent-sandbox-system 命名空間中執行:
kubectl get deployment sandbox-router --namespace=agent-sandbox-system
路由器執行時,READY 欄會顯示所有副本都已就緒,例如 2/2。如果指令傳回 NotFound 錯誤,請按照「部署沙箱路由器」中的步驟部署路由器。
安裝 Python 用戶端
現在已部署 Sandbox Router 等叢集內元件,最後一項準備步驟是在本機電腦上安裝 Agentic Sandbox Python 用戶端。這個用戶端是 Python 程式庫,可讓您透過程式建立、使用及刪除沙箱。您會在下一節使用這個指令來測試環境:
建立並啟用 Python 虛擬環境:
python3 -m venv .venv source .venv/bin/activate安裝用戶端套件。使用與 Agent Sandbox 控制器相同的版本:
pip install k8s-agent-sandbox==1.0.6
測試沙箱
完成所有設定元件後,您現在可以使用 Agentic Sandbox Python 用戶端建立沙箱並與其互動。
建立名為
test_sandbox.py的 Python 指令碼,並加入下列內容:from k8s_agent_sandbox import SandboxClient from k8s_agent_sandbox.models import SandboxLocalTunnelConnectionConfig # Tunnels to svc/sandbox-router-svc in the agent-sandbox-system namespace. # cleanup=True deletes the sandbox when the script exits. client = SandboxClient( connection_config=SandboxLocalTunnelConnectionConfig(), cleanup=True, ) sandbox = client.create_sandbox(warmpool="python-sandbox-warmpool", namespace="default") try: print(sandbox.commands.run("echo 'Hello from the sandboxed environment!'").stdout) except Exception as e: print(f"An error occurred: {e}")在終端機 (虛擬環境仍處於啟用狀態) 執行測試指令碼:
python3 test_sandbox.py
您應該會看到沙箱輸出的訊息「Hello from the sandboxed environment!」。
恭喜!您已成功在安全沙箱中執行殼層指令。使用 sandbox.commands.run() 方法,您可以執行任何殼層指令,而 GKE 上的 Agent Sandbox 會在安全屏障內執行指令,保護叢集的節點和其他工作負載,不受不受信任的程式碼影響。這可讓 AI 代理或任何自動化工作流程,以安全可靠的方式執行工作。
執行指令碼時,SandboxClient 會為您處理所有步驟。它會建立 SandboxClaim 資源來啟動沙箱,等待沙箱準備就緒,然後使用 sandbox.commands.run() 方法在安全容器中執行 Bash 殼層指令。接著,用戶端會擷取並輸出該指令的 stdout。由於指令碼將 cleanup 參數設為 True,用戶端會在程式結束時刪除沙箱。
建立 SandboxClaim 資源後,系統會從暖集區指派可用的沙箱給要求,並將要求標示為就緒。SandboxWarmPool 資源會自動補充,維持設定的副本數量。
如要確認特定沙箱是否已有人認領或可供使用,請查看 Sandbox 資源中繼資料中的 ownerReferences。如果 kind 欄位的值為 SandboxClaim,表示沙箱正在使用中。如果 kind 欄位的值為 SandboxWarmPool,表示沙箱處於閒置狀態,等待認領。
在正式環境中執行沙箱
在本文件中,您將使用 Cloud Shell,從叢集外部與沙箱互動。Python 用戶端會使用您的使用者憑證向叢集驗證身分,並管理沙箱資源,以及使用 kubectl port-forward 指令與沙箱建立連線。這些步驟適用於開發情境。
在正式環境中,控制器應用程式 (例如 AI 協調器) 負責建立及管理沙箱資源。如要在正式環境中使用 GKE 上的 Agent Sandbox,請考量下列事項:
驗證:控制器應用程式必須向叢集 API 伺服器驗證,才能執行沙箱。驗證機制的設定方式取決於控制器應用程式的執行位置,如下所示:
- 如果控制器應用程式在同一個叢集中以 Pod 的形式執行,請使用 Kubernetes RBAC 或 Workload Identity Federation for GKE搭配 IAM 政策,將必要權限授予 Pod 的 Kubernetes ServiceAccount,以便監控沙箱或探索網路端點。
- 如果控制器應用程式在叢集外執行,請使用 Workload Identity Federation 或 IAM 服務帳戶,為應用程式提供可在允許政策中參照的身分。
轉送:控制器應用程式中 Python 用戶端的要求,必須傳送至叢集中的沙箱路由器。在正式環境中,請使用下列其中一種方法建立網路連線:
- 如果控制器應用程式在同一個叢集中執行,請使用
SandboxDirectConnectionConfig函式,指定 Sandbox Router 服務使用的網址和通訊埠。 - 如果控制器應用程式在叢集外執行,請使用 GKE Gateway API 建立內部或外部負載平衡器。在用戶端程式碼中,使用
SandboxGatewayConnectionConfig函式參照閘道。
如要進一步瞭解這些轉送方法,請參閱 GitHub 上的使用範例和路由器的閘道部署步驟。
- 如果控制器應用程式在同一個叢集中執行,請使用
沙箱存取 Google Cloud 資源:如果沙箱程式碼需要傳送要求至 Google Cloud API (例如 Cloud Storage),請使用 IAM 政策搭配 Workload Identity Federation for GKE,將沙箱 Pod 使用的 Kubernetes ServiceAccount 授予該存取權所需的權限。由於預設網路政策會封鎖對 Google Cloud 中繼資料伺服器 (
169.254.169.254) 的存取,因此您必須自訂網路政策,允許這類流量。網路政策限制:根據預設,GKE 上的 Agent Sandbox 會強制執行嚴格的預設安全網路防護機制 (
networkPolicyManagement: Managed)。在此防護機制下,適用下列限制:- 系統會封鎖來自所有來源的輸入,但指定的沙箱路由器 (
agent-sandbox-system命名空間中具有app: sandbox-router標籤的 Pod) 除外。 - 輸出:允許輸出至公開網際網路,但明確禁止輸出至私人區域網路範圍 (RFC 1918)、內部叢集 DNS (CoreDNS) 和雲端服務供應商中繼資料伺服器 (
169.254.0.0/16)。
如要使用 Workload Identity Federation for GKE 或存取其他私人資源,您必須在
SandboxTemplate資源中定義自訂網路政策。如需詳細設定資訊和可自訂的範本 (例如實體隔離沙箱或 Workload Identity Federation for GKE 整合),請參閱「Agent Sandbox 網路政策管理」。- 系統會封鎖來自所有來源的輸入,但指定的沙箱路由器 (
沙箱安全性政策
根據預設,GKE 的 Agent Sandbox 不會對沙箱套用安全性政策。為強制執行沙箱的隔離設定,請從 Agent Sandbox GitHub 存放區套用建議的 secure-sandbox-policy Kubernetes 驗證許可政策 (VAP)。如需操作說明,請參閱「套用建議的安全性政策」。
這項政策會強制執行隔離規定,例如要求使用 gVisor、停用 hostNetwork,以及封鎖 hostPath 磁碟區。這項政策也會強制執行強化要求,例如捨棄所有功能、防止新增功能,以及要求容器以非根使用者的身分執行,並設定資源限制。如需完整規定清單,請參閱「GKE 上的 Agent Sandbox 部署規定」。
修改或移除政策限制
由於政策是由您自行套用,因此可以根據工作負載進行調整。如果工作負載需要豁免部分規則,您可以修改政策,移除特定限制或完全刪除政策繫結。移除限制會降低政策提供的隔離程度,因此請務必只移除工作負載所需的限制。
如要修改政策並移除特定限制 (例如允許容器以 root 身分執行,或省略資源限制),請編輯 ValidatingAdmissionPolicy 資源:
kubectl edit validatingadmissionpolicy secure-sandbox-policy
在開啟的文字編輯器中,找出 validations 區段,然後移除或修改會封鎖工作負載的限制運算式。
或者,如要停止在叢集中強制執行政策,請刪除政策繫結:
kubectl delete validatingadmissionpolicybinding secure-sandbox-binding
已知問題
本節說明在 GKE 使用 Agent Sandbox 的已知問題,以及解決或規避方法。
使用服務網格時,安全性政策會封鎖功能
如果您套用建議的安全政策,並嘗試部署與服務網格 sidecar (例如 Envoy 或 Istio) 整合的沙箱,政策可能會封鎖沙箱建立作業,並顯示類似下列的錯誤:
sandbox create error: sandboxes.agents.x-k8s.io "claude-cli-claim-managed" is forbidden:
ValidatingAdmissionPolicy 'secure-sandbox-policy' with binding 'secure-sandbox-binding'
denied request: Security Violation: Capabilities.add must be empty. You cannot add capabilities.
- 原因:服務網格 sidecar 通常會使用 init 容器,例如
istio-init或proxy-init。這些 init 容器需要NET_ADMIN或NET_RAW等功能,才能設定iptables規則,以進行透明輸出路由。secure-sandbox-policyValidatingAdmissionPolicy 會封鎖所有容器類型中的所有功能新增作業。 - 解決方法:由於您在叢集中管理這項政策,因此可以修改
ValidatingAdmissionPolicy,允許特定受信任的 init 容器要求NET_ADMIN和NET_RAW功能。如要瞭解如何修改或移除政策限制,請參閱「修改或移除政策限制」。舉例來說,您可以更新政策的驗證運算式或變數,將信任的容器名稱排除在功能規則之外。
透過 IPv6 連線至 Google API 時,輸出延遲或逾時
沙箱內的工作負載嘗試連線至外部資源或 Google API (例如 Vertex AI 或 Cloud Storage) 時,可能會發生連線逾時或高延遲 (最長可達兩分鐘)。
- 原因:如果 GKE 叢集啟用雙重堆疊 IPv6,Google API 的 DNS 解析會同時傳回 IPv4 (A) 和 IPv6 (AAAA) 位址。執行階段引擎 (例如 Node.js) 中的某些演算法會先嘗試透過 IPv6 連線。如果 GKE 虛擬私有雲沒有有效的 IPv6 egress 路由,例如 Cloud NAT 或 IPv6 網際網路閘道,TCP 連線會停止回應,直到 TCP SYN 逾時。接著,TCP 連線會改用 IPv4。
解決方法:如要解決這個問題,請按照下列其中一種做法進行:
- 設定 IPv6 輸出:如要允許傳出 IPv6 流量返回叢集,請在虛擬私有雲網路中設定有效的 IPv6 Cloud NAT 或網際網路閘道。
在工作負載中優先使用 IPv4:如要優先使用 IPv4 DNS 解析,請設定工作負載的執行階段。舉例來說,在 Node.js 應用程式中,您可以在
SandboxTemplate定義中設定下列環境變數:env: - name: NODE_OPTIONS value: "--dns-result-order=ipv4first --no-network-family-autoselection"
清除所用資源
如要避免系統向您的 Google Cloud 帳戶收費,請刪除您建立的 GKE 叢集:
gcloud container clusters delete ${CLUSTER_NAME} \
--location=${LOCATION} \
--quiet
後續步驟
- 瞭解如何使用 Pod 快照,在 GKE 環境中儲存及還原 Agent Sandbox。
- 如要進一步瞭解 Agent Sandbox 開放原始碼專案,請前往 GitHub。
- 瞭解如何在 GKE 上搭配使用開放原始碼 Kata Containers 和 Agent Sandbox。Kata Containers 不是 Google Cloud 產品,如果您安裝並使用這類軟體,就必須自行管理及排解問題。Google 的支援和服務水準協議不適用於 Kata Containers。
- 如要瞭解為工作負載提供安全隔離的基礎技術,請參閱「GKE Sandbox」。
- 如要進一步瞭解如何強化叢集和工作負載的安全性,請參閱「GKE 安全性總覽」。