在 GKE 安裝 Agent Sandbox

本文說明如何在 Google Kubernetes Engine (GKE) 叢集安裝開放原始碼 Agent Sandbox 控制器,以便在專屬 Kubernetes Pod 執行沙箱化工作負載。您也會瞭解如何在叢集上建立沙箱環境,安全地執行不受信任的程式碼。

如要概略瞭解 GKE 的 Agent Sandbox 如何隔離不受信任的 AI 生成程式碼,請參閱「關於 GKE 的 Agent Sandbox」。

選擇以 Pod 為基礎或以執行者為基礎的架構

在 GKE 上安裝 Agent Sandbox 之前,請先確認哪種 GKE 架構適合您的 AI 代理工作負載:

  • GKE 上的 Agent Substrate (以 actor 為基礎):這項架構適用於大多數代理工作負載,尤其是經常暫停和恢復的有狀態代理。活躍的代理會共用一組暖 Pod,而非每個代理都有專屬 Pod,因此您可以在較少的節點上執行更多代理。GKE 上的 Agent Substrate 會自動暫停及恢復閒置的工作負載,並在不到一秒內從儲存空間還原代理。相較之下,GKE 上的 Agent Sandbox 需要手動建立 Pod 快照,而且您必須建構應用程式程式碼,偵測閒置狀態並儲存代理的進度。GKE 上的 Agent Substrate 需要 GKE Standard 叢集。詳情請參閱「關於 GKE 上的 Agent Substrate」。如要改為安裝這個選項,請參閱「在 GKE 上安裝 Agent Substrate」。
  • GKE 上的 Agent Sandbox (Pod 型):如果每個代理程式都需要 GKE Autopilot 或 Standard 叢集上的專屬 Kubernetes Pod,請使用這個架構 (按照本文說明安裝)。如果代理程式持續運作,或工作負載需要下列任一項目,請選擇這個選項:
    • 宣告式 Kubernetes API,例如 Sandbox 和 SandboxClaim 自訂資源
    • 完整的 Kubernetes PodSpec 結構定義,包括自訂 sidecar 和 init 容器
    • 直接存取硬體加速器,例如 GPU 或 TPU
    • GKE Autopilot 叢集

費用

GKE 的 Agent Sandbox 是開放原始碼軟體,無須額外付費即可使用。您建立的資源 (包括 Agent Sandbox 控制器使用的運算資源) 適用 GKE 定價。

為避免產生不必要的費用,請務必在完成本文件後停用 GKE 或刪除專案。

事前準備

  1. 在 Google Cloud 控制台的專案選取器頁面中,選取或建立 Google Cloud 專案。

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需具備特定 IAM 角色,只要您已獲派某個專案的角色,即可選取該專案。
    • 建立專案:如要建立專案,您必須具備專案建立者角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色。

    前往專案選取器

  2. 確認 Google Cloud 專案已啟用計費功能。

  3. 啟用 Google Kubernetes Engine API (如果尚未啟用)。

    啟用 API 所需的角色

    您必須具備 serviceusage.services.enable 權限,才能啟用 API。如果您建立了專案,可能已透過擁有者角色 (roles/owner) 取得這項權限。否則,您可以透過 Service Usage 管理員角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色。

    啟用 API

  4. 在 Google Cloud 控制台啟用 Cloud Shell。

    啟用 Cloud Shell

定義環境變數

為簡化您在本文件中執行的指令,您可以在 Cloud Shell 中設定環境變數。在 Cloud Shell 執行下列指令,定義下列實用的環境變數:

export CLUSTER_NAME="agent-sandbox-cluster"
export LOCATION="us-central1"
export AGENT_SANDBOX_VERSION="v1.0.6"
export NODE_POOL_NAME="agent-sandbox-pool"
export MACHINE_TYPE="e2-standard-2"

以下說明這些環境變數:

  • CLUSTER_NAME:GKE 叢集的名稱,例如 agent-sandbox-cluster。
  • LOCATION:建立 GKE 叢集的 Google Cloud 區域或可用區。如果您建立 Autopilot 叢集,請將此值設為區域 (例如 us-central1)。Autopilot 叢集一律為區域叢集。如果您建立的是 Standard 叢集,請將這個值設為可用區 (例如 us-central1-a)。為降低費用,本文件會建立可用區叢集,使用的節點數量少於區域叢集。
  • AGENT_SANDBOX_VERSION:要安裝的開放原始碼 Agent Sandbox 控制器版本。本文使用的是 1.0.6 版。如要查看其他版本,請前往 Agent Sandbox 版本頁面。
  • NODE_POOL_NAME:要執行沙箱化工作負載的節點集區名稱,例如 agent-sandbox-pool。只有在建立 GKE Standard 叢集時,才需要這個變數。
  • MACHINE_TYPE:叢集預設節點集區和 gVisor 節點集區中節點的機器類型,例如 e2-standard-2。如要進一步瞭解不同的機器系列,以及如何選擇不同選項,請參閱「機器家族資源和比較指南」。只有在建立 GKE Standard 叢集時,才需要這個變數。

建立 GKE 叢集

GKE 的 Agent Sandbox 會使用 gVisor 或 microVMs 隔離沙箱工作負載。如未指定沙箱執行階段,沙箱會在沒有核心隔離的情況下執行,因此不建議用於不受信任的程式碼。本文件使用 gVisor。Autopilot 叢集會自動啟用 gVisor。在 Standard 叢集中,您需要建立已啟用 gVisor 的節點集區。如要改用 microVM,請參閱「啟用 microVM 沙箱類型」。建議的安全性政策僅允許 gVisor,因此會拒絕使用 microVM 的沙箱。

Autopilot

如要建立 Autopilot 叢集,請確認 LOCATION 環境變數已設為區域 (例如 us-central1),然後執行下列指令:

gcloud container clusters create-auto ${CLUSTER_NAME} \
    --location=${LOCATION}

標準

如要建立 Standard 叢集,請先建立叢集,然後新增已啟用 gVisor 的節點集區。為降低費用,本文件會建立可用區叢集,每個集區只有一個節點。

  1. 將 LOCATION 環境變數設為可用區,例如 us-central1-a:

    export LOCATION="us-central1-a"
    
  2. 建立叢集:

    gcloud container clusters create ${CLUSTER_NAME} \
        --location=${LOCATION} \
        --machine-type=${MACHINE_TYPE} \
        --num-nodes=1
    
  3. 建立已啟用 gVisor 的獨立節點集區:

    gcloud container node-pools create ${NODE_POOL_NAME} \
        --cluster=${CLUSTER_NAME} \
        --machine-type=${MACHINE_TYPE} \
        --location=${LOCATION} \
        --num-nodes=1 \
        --image-type=cos_containerd \
        --sandbox=type=gvisor
    

    如要使用 microVM 而非 gVisor,請按照「啟用 microVM 沙箱類型」一節的說明建立節點集區。本文其餘部分會使用 gVisor。

如要改用現有的 Standard 叢集,請確認叢集包含已啟用 gVisor 的節點集區。如果叢集沒有這類節點集區,請執行上述 gcloud container node-pools create 指令來建立。

如要啟用 kubectl 指令列工具來連線至叢集,請取得叢集憑證:

gcloud container clusters get-credentials ${CLUSTER_NAME} \
    --location=${LOCATION}

安裝 Agent Sandbox

如要安裝 Agent Sandbox,請套用 Agent Sandbox GitHub 存放區中的版本資訊清單。sandbox-with-extensions.yaml 資訊清單會安裝 Agent Sandbox 控制器,以及 Sandbox 資源和 SandboxTemplate、SandboxClaim 和 SandboxWarmPool 擴充功能資源的 CustomResourceDefinitions。

  1. 套用版本資訊清單:

    kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/sandbox-with-extensions.yaml
    

    資訊清單會建立 agent-sandbox-system 命名空間,並在該命名空間中部署控制器。

  2. 等待控制器準備就緒:

    kubectl rollout status deployment/agent-sandbox-controller \
        --namespace=agent-sandbox-system \
        --timeout=120s
    

您也可以使用 Helm 安裝 Agent Sandbox。如需操作說明,請參閱 Agent Sandbox Helm chart README。

驗證安裝

  1. 確認已安裝 Agent Sandbox CustomResourceDefinitions:

    kubectl get crd \
        sandboxes.agents.x-k8s.io \
        sandboxtemplates.extensions.agents.x-k8s.io \
        sandboxclaims.extensions.agents.x-k8s.io \
        sandboxwarmpools.extensions.agents.x-k8s.io
    

    輸出內容會列出四個 CustomResourceDefinition。

  2. 確認控制器正在運作:

    kubectl get deployment agent-sandbox-controller \
        --namespace=agent-sandbox-system
    

    控制器執行時,READY 欄會顯示 1/1。

套用建議的安全性政策

根據預設,GKE 的 Agent Sandbox 不會限制執行沙箱的 Pod 設定。如要強制執行沙箱的隔離設定,請套用 Agent Sandbox GitHub 存放區中建議的 secure-sandbox-policy ValidatingAdmissionPolicy。這項政策會拒絕任何不符合 GKE Agent Sandbox 部署規定的 Sandbox 資源。

  1. 套用政策:

    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/examples/policy/vap/secure-sandbox-policy.yaml
    
  2. 套用政策繫結。繫結會在所有命名空間強制執行政策,但系統命名空間除外,例如 kube-system:

    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/examples/policy/vap/secure-sandbox-binding.yaml
    

這項政策會驗證 Sandbox 項資源。建立 SandboxWarmPool 資源或 SandboxClaim 資源時,控制器會從 SandboxTemplate 資源建立 Sandbox 資源。如果範本不符合規定,政策會拒絕 Sandbox 資源,且控制器記錄中會顯示錯誤。如要查看記錄,請執行下列指令:

kubectl logs deployment/agent-sandbox-controller \
    --namespace=agent-sandbox-system

這項政策由您管理,您可以視工作負載需求進行修改。詳情請參閱「沙箱安全性政策」。

GKE 部署作業的 Agent Sandbox 需求

如果套用建議的安全政策,工作負載資訊清單 (例如 Sandbox 或 SandboxTemplate 資源) 必須包含特定的安全性和設定。如果 Sandbox 資源不符合這些規定,准入控制器會拒絕該資源。容器需求條件適用於 Pod 中的所有容器,包括 init 容器和臨時容器。

必要設定

部署資訊清單必須包含下列設定:

  • runtimeClassName: gvisor:確保 Pod 在 gVisor 沙箱中執行。這項政策會拒絕使用任何其他執行階段 (包括 microVM) 的沙箱。
  • automountServiceAccountToken: false:防止 Pod 自動掛接預設服務帳戶權杖。
  • securityContext.runAsNonRoot: true:確保容器不會以超級使用者身分執行。
  • securityContext.capabilities.drop: ["ALL"]:從容器中捨棄所有 Linux 功能。
  • resources.limits:您必須指定 CPU 和記憶體限制,以免發生阻斷攻擊 (DoS) 的情況。
  • nodeSelector:必須指定 sandbox.gke.io/runtime: gvisor。
  • tolerations:必須包含 sandbox.gke.io/runtime=gvisor:NoSchedule 污點的容忍。

禁止設定

部署資訊清單不得包含下列任何項目:

  • hostNetwork: true、hostPID: true 或 hostIPC: true。
  • 容器安全性內容中的 privileged: true。
  • 容器安全性內容中的 procMount: Unmasked。
  • HostPath 個磁碟區。
  • 新增功能 (capabilities.add)。
  • hostPort 設定。
  • 自訂 sysctl。
  • 服務帳戶權杖或憑證的預計磁碟區。

部署沙箱路由器 (選用)

Sandbox Router 是 HTTP Proxy,可將用戶端 (例如 Agent Sandbox Python 用戶端) 的要求轉送至執行沙箱的 Pod。如果您打算使用 Python 用戶端 (例如「在 GKE 上使用 Agent Sandbox 隔離 AI 執行程式碼作業」一文所述),請部署路由器。

您在 agent-sandbox-system 命名空間中部署路由器。根據預設,GKE 上的 Agent Sandbox 為每個 SandboxTemplate 資源建立的網路政策,只允許來自這個命名空間中路由器 Pod 的傳入流量進入沙箱。

  1. 建立路由器的服務帳戶和 RBAC 權限,讓路由器查詢沙箱 Pod:

    kubectl apply \
        -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/sandbox-router/deploy/serviceaccount.yaml \
        -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/sandbox-router/deploy/rbac.yaml
    
  2. 部署路由器。下列指令會將路由器映像檔設為與控制器相同的版本:

    curl -sSL https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/sandbox-router/deploy/deployment.yaml \
        | sed "s|sandbox-router-go:latest|sandbox-router-go:${AGENT_SANDBOX_VERSION}|" \
        | kubectl apply -f -
    
  3. 建立路由器的 Service:

    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/sandbox-router/deploy/service.yaml
    
  4. 等待路由器準備就緒:

    kubectl rollout status deployment/sandbox-router \
        --namespace=agent-sandbox-system \
        --timeout=120s
    

這個路由器設定適用於開發和測試。如需正式環境設定 (例如 TLS、副本數量和路由器的網路政策),請參閱沙箱路由器部署作業 README。

部署沙箱環境

建議您定義 SandboxTemplate 資源來部署沙箱環境,並使用 SandboxWarmPool 資源預先準備好預熱執行個體。接著,您可以使用 SandboxClaim 資源,從這個暖集區要求執行個體。或者,您也可以直接建立 Sandbox 資源,但這種方法不支援暖集區。

SandboxTemplate、SandboxWarmPool、SandboxClaim 和 Sandbox 是 Kubernetes 自訂資源。

SandboxTemplate 資源可做為可重複使用的藍圖。SandboxWarmPool 資源可確保指定數量的預熱沙箱隨時都在運作,並可供認領。使用這項自訂資源可盡量縮短啟動延遲時間。

如要建立 SandboxTemplate 和 SandboxWarmPool 資源來部署沙箱環境,請完成下列步驟:

  1. 在 Cloud Shell 中建立名為 sandbox-template.yaml 的檔案,並加入下列內容:

    apiVersion: extensions.agents.x-k8s.io/v1beta1
    kind: SandboxTemplate
    metadata:
      name: python-runtime-template
      namespace: default
    spec:
      podTemplate:
        metadata:
          labels:
            sandbox-type: python-runtime
        spec:
          runtimeClassName: gvisor # Required
          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: runtime
            image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0
            ports:
            - containerPort: 8888
            resources:
              requests:
                cpu: "250m"
                memory: "512Mi"
              limits:
                cpu: "500m"
                memory: "1Gi" # Required
            securityContext:
              capabilities:
                drop: ["ALL"] # Required
          restartPolicy: OnFailure
    
  2. 套用 SandboxTemplate 資訊清單:

    kubectl apply -f sandbox-template.yaml
    
  3. 建立名為 sandbox-warmpool.yaml 的檔案,並在其中加入下列內容:

    apiVersion: extensions.agents.x-k8s.io/v1beta1
    kind: SandboxWarmPool
    metadata:
      name: python-runtime-warmpool
      namespace: default
      labels:
        app: python-runtime-warmpool
    spec:
      replicas: 2
      sandboxTemplateRef:
        # This must match the name of the SandboxTemplate.
        name: python-runtime-template
    
  4. 套用 SandboxWarmPool 資訊清單:

    kubectl apply -f sandbox-warmpool.yaml
    
  5. 等待暖集區的沙箱準備就緒:

    kubectl wait sandboxwarmpool python-runtime-warmpool \
        --for=jsonpath='{.status.readyReplicas}'=2 \
        --timeout=600s
    

    如果您在集區的沙箱準備就緒前建立 SandboxClaim 資源,控制器可能會為要求建立新的沙箱,而不是從集區指派沙箱。在 Autopilot 叢集中,沙箱可能需要幾分鐘才能準備就緒,因為 GKE 可能需要為沙箱建立節點。

建立 SandboxClaim 資源

SandboxClaim 資源要求會向暖集區要求沙箱。由於您已建立暖集區,控制器會從集區中指派執行中的沙箱給宣告,而不是建立新的沙箱。

如要建立 SandboxClaim 資源,從暖集區要求沙箱,請完成下列步驟:

  1. 建立名為 sandbox-claim.yaml 的檔案,並在其中加入下列內容:

    apiVersion: extensions.agents.x-k8s.io/v1beta1
    kind: SandboxClaim
    metadata:
      name: sandbox-claim
      namespace: default
    spec:
      warmPoolRef:
        # This must match the name of the SandboxWarmPool.
        name: python-runtime-warmpool
    
  2. 套用 SandboxClaim 資訊清單:

    kubectl apply -f sandbox-claim.yaml
    
  3. 確認沙箱、宣告和暖集區已準備就緒:

    kubectl get sandboxwarmpool,sandboxclaim,sandbox,pod
    

替代方案:直接建立 Sandbox 資源

如果不需要暖集區提供的快速啟動時間,可以直接部署 Sandbox 資源,不使用範本。

如要直接建立 Sandbox 資源來部署沙箱環境,請完成下列步驟:

  1. 建立名為 sandbox.yaml 的檔案,並在其中加入下列內容:

    apiVersion: agents.x-k8s.io/v1beta1
    kind: Sandbox
    metadata:
      name: sandbox-example-2
    spec:
      podTemplate:
        metadata:
          labels:
            sandbox: sandbox-example
        spec:
          runtimeClassName: gvisor
          restartPolicy: OnFailure
          automountServiceAccountToken: false # Required
          securityContext:
            runAsNonRoot: true # Required
            runAsUser: 1000 # Required if image defaults to root (for example, busybox)
          nodeSelector:
            sandbox.gke.io/runtime: gvisor
          tolerations:
          - key: "sandbox.gke.io/runtime"
            value: "gvisor"
            effect: "NoSchedule" # Required
          containers:
          - name: my-container
            image: busybox
            command: ["/bin/sh", "-c"]
            args: ["sleep 3600000; echo 'Container finished successfully'; exit 0"]
            securityContext:
              capabilities:
                drop: ["ALL"] # Required
              allowPrivilegeEscalation: false
            resources:
              limits:
                cpu: "100m"
                memory: "128Mi" # Required
    
  2. 套用 Sandbox 資訊清單:

    kubectl apply -f sandbox.yaml
    
  3. 確認沙箱正在執行:

    kubectl get sandbox
    

升級 Agent Sandbox

如要升級 Agent Sandbox,請套用新版本的發布資訊清單:

export AGENT_SANDBOX_VERSION="NEW_VERSION"
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/sandbox-with-extensions.yaml

將 NEW_VERSION 替換為要安裝的版本,例如 Agent Sandbox 版本頁面列出的版本。

升級前,請先查看新版本的版本資訊。如果叢集執行的 Agent Sandbox 版本早於 1.0.0,您必須先將資源遷移至 v1beta1 API 再升級,因為 1.0.0 版已移除 v1alpha1 API。如需操作說明,請參閱 API 遷移指南。

如果您已部署沙箱路由器或套用建議的安全性政策,請針對新版本重複執行這些步驟。

解除安裝 Agent Sandbox

  1. 檢查是否有 Agent Sandbox 資源仍在使用中:

    kubectl get sandboxes,sandboxclaims,sandboxwarmpools,sandboxtemplates \
        --all-namespaces
    
  2. 如果您已套用建議的安全性政策,請刪除政策繫結和政策:

    kubectl delete validatingadmissionpolicybinding secure-sandbox-binding
    kubectl delete validatingadmissionpolicy secure-sandbox-policy
    
  3. 如果您部署了 Sandbox Router,請刪除其叢集層級 RBAC 資源:

    kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/${AGENT_SANDBOX_VERSION}/sandbox-router/deploy/rbac.yaml
    

    路由器的其他資源位於 agent-sandbox-system 命名空間,會在下一個步驟中刪除。

  4. 如要刪除 Agent Sandbox 控制器、其命名空間和 CustomResourceDefinitions,請刪除已安裝版本的發布資訊清單:

    kubectl delete -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/sandbox-with-extensions.yaml
    

清除所用資源

如要避免系統向您的 Google Cloud 帳戶收費,請刪除您建立的 GKE 叢集。

gcloud container clusters delete ${CLUSTER_NAME} \
    --location=${LOCATION} \
    --quiet

如果您建立的是 Autopilot 叢集,位置就是區域 (例如 us-central1)。如果您建立的是 Standard 叢集,位置就是可用區 (例如 us-central1-a)。

後續步驟