在 Kubernetes 上部署
使用版本封存檔中的兩個 Helm chart,在 Kubernetes 叢集上安裝自行託管的 Claude Managed Agents 伺服器及其沙箱,然後在沙箱 pod 中執行第一個工作階段。
本頁面將帶您從一個空的 Google Kubernetes Engine (GKE) 叢集開始,一路到在沙箱 pod 中執行工具的工作階段。它使用「release archive」(版本封存檔)中的兩個 Helm chart,可在叢集上執行整個堆疊:
cma-server: 套用資料庫結構描述,並在命名空間cma-server中,於一個 Service 後方執行兩個伺服器。cma-sandboxes: 在命名空間cma中,執行一個 dispatcher 與沙箱 pod。dispatcher 會向伺服器輪詢工作,並為每個工作階段提供專屬的沙箱 pod,由 worker 在其中執行代理的 shell 與檔案工具。
您的 PostgreSQL 資料庫位於這兩者之外。在其他類型的叢集上,步驟相同,但叢集先決條件和部分 chart 值有所不同。請參閱其他叢集。
先決條件
- 叢集: Kubernetes 1.30 或更新版本,需具備:
- Agent Sandbox 控制器(在 GKE 上,即為 Agent Sandbox 附加元件)
- 執行 gVisor 的節點(在 GKE 上,即為 GKE Sandbox 節點集區)
- 會強制執行 NetworkPolicy 的網路外掛程式(在 GKE 上,即為 Dataplane V2 或 Calico)
- 資料庫: 叢集可連線的 PostgreSQL 16 或更新版本。
- 登錄庫: 叢集可從中提取映像的登錄庫。映像需由您自行建置。
- Claude API 金鑰: 伺服器會使用它進行模型呼叫。若要使用其他提供者,請參閱推論提供者。
- 權限: Cluster-admin 權限或同等權限。安裝過程會建立命名空間、Roles 和一個 ClusterRoleBinding。
- 您機器上的工具:
helm、kubectl、docker buildx、openssl,以及antCLI。 - 版本封存檔: 若要申請下載權限,請聯絡您的 Anthropic 客戶團隊。解壓縮封存檔。本頁面上的每個指令都請從其頂層目錄執行。
安裝堆疊
建置並推送映像
將這些變數設定為您自己的值。
PLATFORM是您節點的架構。TAG是該版本的版本號,位於封存檔名稱中的v之後。兩個 chart 都預期映像以此版本號作為標籤。REGISTRY=us-docker.pkg.dev/my-project/cma TAG=1.2.3 PLATFORM=linux/amd64接著建置並推送這三個映像:
docker buildx build --platform "$PLATFORM" -f kubernetes/server/Dockerfile -t "$REGISTRY/cma-server-image:$TAG" --push . docker buildx build --platform "$PLATFORM" -f kubernetes/dispatcher/Dockerfile -t "$REGISTRY/cma-dispatcher:$TAG" --push . docker buildx build --platform "$PLATFORM" -t "$REGISTRY/cma-sandbox:$TAG" --push kubernetes/sandbox建立密鑰檔案和資料庫
建立一個檔案,其中包含產生的資料庫密碼,以及您的 Claude API 金鑰的預留位置:
cat > secrets.env <<EOF PG_PASSWORD=$(openssl rand -hex 32) UPSTREAM_KEY=sk-ant-... EOF chmod 600 secrets.env請在編輯器中開啟
secrets.env,並將sk-ant-...替換為您的 Claude API 金鑰。接著以管理員身分連線至您的資料庫伺服器,例如使用psql。執行此 SQL,並以PG_PASSWORD的值取代...:CREATE ROLE cma_server LOGIN PASSWORD '...'; GRANT cma_server TO CURRENT_USER; CREATE DATABASE cma_server OWNER cma_server;建立伺服器的命名空間和 Secrets
建立伺服器的命名空間及其 Secrets:
source secrets.env ENCRYPTION_KEY=$(openssl rand -base64 32) kubectl create namespace cma-server kubectl label namespace cma-server pod-security.kubernetes.io/enforce=restricted pod-security.kubernetes.io/enforce-version=latest kubectl -n cma-server create secret generic cma-server-db \ --from-literal=PGPASSWORD="$PG_PASSWORD" kubectl -n cma-server create secret generic cma-server-keys \ --from-literal=CMA_SERVER__API_KEY="$(openssl rand -hex 32)" \ --from-literal=CMA_STORE__CREDENTIALS_ENCRYPTION_KEY="$ENCRYPTION_KEY" kubectl -n cma-server create secret generic cma-server-upstream \ --from-literal=ANTHROPIC_API_KEY="$UPSTREAM_KEY"使用
echo "$ENCRYPTION_KEY"印出加密金鑰,並在叢集之外保留一份副本。伺服器會使用此金鑰來加密其所儲存的憑證,而還原的資料庫也需要它。接著刪除secrets.env。cma-server-dbSecret 會保存資料庫密碼。建立沙箱的命名空間和憑證
建立沙箱的命名空間,以及一個由 dispatcher 提供、並由沙箱信任的憑證:
kubectl create namespace cma kubectl label namespace cma pod-security.kubernetes.io/enforce=restricted pod-security.kubernetes.io/enforce-version=latest openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -days 825 \ -subj "/CN=cma-dispatcher.cma.svc" \ -addext "subjectAltName=DNS:cma-dispatcher.cma.svc,DNS:cma-dispatcher.cma.svc.cluster.local" \ -keyout tls.key -out tls.crt kubectl -n cma create secret tls cma-dispatcher-tls --cert=tls.crt --key=tls.key --dry-run=client -o yaml | kubectl apply -f - kubectl -n cma create configmap cma-dispatcher-ca --from-file=ca.crt=tls.crt --dry-run=client -o yaml | kubectl apply -f -安裝伺服器
將以下內容儲存為
cma-server-values.yaml,並填入您的登錄庫和資料庫位址:earlierNames: false # a new install image: registry: us-docker.pkg.dev/my-project/cma # REGISTRY in the build commands database: url: host=10.20.0.5 port=5432 user=cma_server dbname=cma_server sslmode=require # your database's address environments: - name: default namespace: cma接著安裝 chart:
helm install cma-server kubernetes/server/chart --namespace cma-server -f cma-server-values.yaml --wait kubectl -n cma-server logs job/cma-server-environment-default安裝過程會建立環境
default,並將其金鑰儲存在命名空間cma中的 Secretcma-environment。第二個指令會印出一行以filled Secret cma/cma-environment開頭的內容。如果第一次helm install失敗,請在重新安裝之前,先對該 Helm release 執行helm uninstall。找出要封鎖的叢集位址
此安裝會讓沙箱能連線至公用網際網路。叢集的 API 端點通常具有公用位址,因此沙箱也可能連線至該端點。若要封鎖它,請在下一個步驟中將其位址列於
egress.clusterCIDRs之下。若要印出該位址,請以您叢集的名稱執行
gcloud container clusters describe my-cluster --format 'value(endpoint)'。chart 本身會封鎖私人範圍
10.0.0.0/8、172.16.0.0/12、192.168.0.0/16和100.64.0.0/10。如果您的叢集有位於這四個範圍之外的 pod、服務或節點範圍,也請列出該範圍。安裝沙箱
將以下內容儲存為
cma-values.yaml,並填入您的登錄庫和上一個步驟中的位址:platform: gke image: registry: us-docker.pkg.dev/my-project/cma # REGISTRY in the build commands egress: mode: publicInternet clusterCIDRs: - 203.0.113.10/32 # the cluster's API endpoint cmaServer: pods: namespace: cma-server matchLabels: anthropic.com/role: server port: 8400egress.cmaServer會開放通往您伺服器的路徑。若要將publicInternet與另外兩種模式進行比較,請參閱沙箱可連線的位置。如果您的叢集使用下列其中一種 DNS 設定,請在檔案中加入一行:
- Cloud DNS for GKE(Autopilot 叢集即使用此功能):
gke: {dns: cloudDns} - NodeLocal DNSCache:
gke: {dns: nodeLocalCache, kubeDnsUpstreamIP: <address>}。若要印出該位址,請執行kubectl -n kube-system get svc kube-dns-upstream -o jsonpath='{.spec.clusterIP}'。
接著安裝 chart:
helm install cma kubernetes/chart --namespace cma -f cma-values.yaml --wait- Cloud DNS for GKE(Autopilot 叢集即使用此功能):
執行工作階段
這些步驟使用新安裝的名稱。如果您的伺服器 values 檔案包含 earlierNames: true,請在Kubernetes:您的物件名稱中找出應改用的名稱。
轉送伺服器的連接埠
在一個終端機中,將伺服器的連接埠轉送到您的電腦:
kubectl -n cma-server port-forward svc/cma-server 8400:8400將 CLI 指向您的伺服器
在第二個終端機中,將
antCLI 指向轉送的連接埠,並從cma-server-keysSecret 讀取伺服器 API 金鑰:export ANTHROPIC_BASE_URL=http://127.0.0.1:8400 export ANTHROPIC_API_KEY=$(kubectl -n cma-server get secret cma-server-keys -o jsonpath='{.data.CMA_SERVER__API_KEY}' | base64 -d)建立代理並要求它執行指令
依照快速入門中執行您的第一個工作階段的三個步驟操作:建立代理、啟動工作階段,以及要求代理執行指令。在「啟動工作階段」中,請將
compose-sandbox替換為default,也就是 chart 所建立之環境的名稱。找出沙箱 pod
代理會回覆執行該指令之 pod 的主機名稱。在第三個終端機中,
kubectl -n cma get pods會在 dispatcher 的 pod 旁列出該名稱的 pod。根據預設,該 pod 會在代理的回合結束後約 5 分鐘消失。如果清單中沒有它,請要求代理再次執行hostname。若要離開聊天,請按 Ctrl+C。
在伺服器前方加上 TLS
伺服器在連接埠 8400 上使用純 HTTP,而來自您應用程式的請求會攜帶伺服器 API 金鑰。在叢集外的用戶端連線之前,請在 cma-server Service 前方加上一個終止 TLS 的負載平衡器或 ingress。它必須:
- 原封不動地傳遞請求路徑。
- 接受最大 32 MiB 的請求主體。
- 以不緩衝的方式傳遞回應。
- 設定預設 2 分鐘的讀取逾時。對於 Git 請求,請為符合
^/cma-[a-z]+/git/的路徑設定 10 分鐘的讀取逾時。 - 僅將流量傳送至已就緒的伺服器。
cma-serverService 已經會這樣做。直接連線至 pod 的負載平衡器必須在每個 pod 上探測/cma-server/readyz,並略過回傳503的 pod。 - 絕不重新傳送伺服器已接受的
POST。 - 絕不快取回應。
若要從叢集外檢查,請執行 curl -s https://<host>/cma-server/healthz。回應為 {"status":"ok"}。
沙箱可連線的位置
在 cma-values.yaml 中,egress.mode: publicInternet 可讓沙箱連線至公用網際網路。
此表格將它與另外兩種模式進行比較:
egress.mode | 沙箱可連線的位置 |
|---|---|
closed,預設值 | 您的伺服器和 dispatcher,且無法連線至任何 DNS 伺服器 |
publicInternet | 您的伺服器、dispatcher、DNS 伺服器,以及公用網際網路 |
gateway | 您的伺服器、dispatcher,以及透過「egress gateway」(輸出閘道)連線的您所列出的主機。請參閱在 Kubernetes 上開啟閘道。 |
其他叢集
在 cma-values.yaml 中,將 platform 設定為 eks(適用於 Amazon EKS)、aks(適用於 Azure Kubernetes Service (AKS))或 generic(適用於任何其他叢集)。三者都需要上游的 Agent Sandbox 控制器及其擴充功能,以及強制執行 NetworkPolicy 的網路外掛程式。它們還需要:
- Amazon EKS: 一個已將 gVisor 的
runsc註冊為名為runsc之 containerd 處理常式的節點群組。為節點加上標籤cma.anthropic.com/sandbox-node=true,並加上 taintcma.anthropic.com/sandbox-node=true:NoSchedule。chart 會針對該處理常式註冊gvisorRuntimeClass。 - AKS: 一個啟用 Pod Sandboxing 的節點集區,其標籤和 taint 與 Amazon EKS 上相同。將叢集網路政策引擎的名稱(
cilium、calico或azure)填入aks.networkPolicy。請保留egress.mode: publicInternet,這是 chart 在 AKS 上唯一接受的模式。在代理於其上執行實際工作之前,請先在您的叢集上測試此 chart。 - 任何其他叢集: 適用於 gVisor 或其他沙箱化執行環境的 RuntimeClass。將其名稱填入
runtimeClass.name。
封存檔中的資料夾 kubernetes/chart/examples/ 為每種叢集提供了完整的 values 檔案。
釋放工作階段的磁碟區
根據 chart 的預設值,每個工作階段都有一個用於 /workspace 的 10 GiB 磁碟區。工作階段的 pod 消失後,該磁碟區仍會保留,因此工作階段的下一則訊息可以找到其檔案。
| 要釋放的對象 | 執行的操作 |
|---|---|
| 單一工作階段的磁碟區 | 在工作階段的回合結束後將其封存。dispatcher 通常會在約 5 分鐘內刪除該磁碟區。 |
| 無人封存之工作階段的磁碟區 | 在 cma-values.yaml 中設定 dispatcher.retentionDays。之後,當工作階段閒置達該天數時,dispatcher 會刪除其磁碟區,而該工作階段的下一則訊息會以空的 /workspace 開始。chart 的預設值 0 會保留所有磁碟區。 |
本節中的指令適用於 GKE。在其他叢集上,請使用 sandboxclaims 取代 sandboxes。
刪除工作階段並不會釋放其磁碟區。請先封存工作階段。只有在 kubectl -n cma get sandboxes -l anthropic.com/session-id=<session-id> 未列出任何項目之後,才刪除它。
如果您在未封存的情況下刪除了工作階段,請自行釋放其磁碟區:
-
在 dispatcher 的記錄中找出工作階段的 ID。此指令會為每個看似已刪除但仍有磁碟區的工作階段印出一行,其 ID 位於
session_id之後:kubectl -n cma logs deployment/cma-dispatcher --since=6m \ | grep "could not check the claim's session" | grep "403 Forbidden"dispatcher 每 5 分鐘寫入一次這些行。如果未列出該工作階段,請等待 5 分鐘後再次執行指令。
-
確認工作階段已刪除。在依照執行工作階段轉送連接埠並設定
ANTHROPIC_API_KEY的情況下,執行ant --base-url http://127.0.0.1:8400 beta:sessions retrieve --session-id <session-id>。只有在回應為404 Not Found且帶有Session not found時,才繼續進行。如果指令印出了工作階段,請停止:該工作階段尚未刪除。 -
刪除擁有該磁碟區的 Kubernetes 物件。工作階段的檔案會隨之刪除:
kubectl -n cma delete sandboxes -l anthropic.com/session-id=<session-id>
更新金鑰和憑證
環境金鑰的有效期為 365 天,dispatcher 的憑證有效期為 825 天。請在各自到期之前進行更新。
在環境金鑰的最後 30 天內,伺服器會在每個使用該金鑰的請求上記錄一則警告。該警告以 environment key is within 30 days of expiry 開頭。
更新 chart 所建立的環境金鑰
若要查看金鑰的到期時間,請執行 kubectl -n cma describe secret cma-environment。
請在金鑰的最後 60 天內,從目前已安裝版本之封存檔的頂層目錄,至少執行一次這兩個指令:
helm upgrade cma-server kubernetes/server/chart --namespace cma-server -f cma-server-values.yaml --wait
kubectl -n cma rollout restart deployment/cma-dispatcher每次執行伺服器 chart 的 helm upgrade 指令時,如果金鑰將在 60 天內到期,它都會將新的金鑰儲存在 Secret 中。除此之外,沒有其他任何機制會更新金鑰。第二個指令會重新啟動 dispatcher,使其讀取新的金鑰。
更新 dispatcher 的憑證
請回到「建立沙箱的命名空間和憑證」步驟。再次執行其中的 openssl 指令及其後的兩個 kubectl 指令。然後使用 kubectl -n cma rollout restart deployment/cma-dispatcher 重新啟動 dispatcher。
為您自己的 worker 替換環境金鑰
chart 只會更新自己的金鑰。如果您自行建立了金鑰(如建立環境及其金鑰中所述),請使用管理 CLI 替換它。該 CLI 位於版本封存檔的頂層。
請在執行工作階段中的第二個終端機執行這些指令,其中 ANTHROPIC_API_KEY 存放著伺服器 API 金鑰。請讓連接埠轉送在第一個終端機中持續執行。如果您透過其他位址連線到您的伺服器,請將該位址作為 -base-url 傳入,此時就不需要連接埠轉送。
為相同環境建立新金鑰
對於
-env,請傳入環境的 ID:echo "$ANTHROPIC_API_KEY" | ./cma-server-admin mint-key \ -base-url http://127.0.0.1:8400 -env env_01595EKxaaTTGwwY3kyXdtbs -key-file -此指令會印出新金鑰,並在標準錯誤輸出上印出金鑰的 ID 和到期時間。
將您的 worker 移至新金鑰
為每個進行輪詢的處理程序將新金鑰設定為
ANTHROPIC_ENVIRONMENT_KEY,並重新啟動該處理程序。撤銷舊金鑰
仍使用已撤銷金鑰的 worker 會收到
401錯誤,並放棄其正在服務的工作階段。若要找出舊金鑰的 ID,請使用相同的-base-url、-env和-key-file旗標執行list-keys。當不再有任何 worker 使用舊金鑰時,請依該 ID 撤銷它:echo "$ANTHROPIC_API_KEY" | ./cma-server-admin revoke-key \ -base-url http://127.0.0.1:8400 -env env_01595EKxaaTTGwwY3kyXdtbs \ -key-id etok_01AbCdEfGhIjKlMnOpQrStUv -key-file -
解除安裝堆疊
請先刪除沙箱。helm uninstall 會刪除限制沙箱的網路政策,但 dispatcher 為工作階段建立的沙箱會持續執行。
這些步驟不會影響您的資料庫,但會刪除 Secrets。若要再次使用該資料庫,您需要您保留的加密金鑰副本。
停止 dispatcher 並刪除沙箱
kubectl -n cma scale deployment/cma-dispatcher --replicas=0 kubectl -n cma delete sandboxwarmpool cma-sandbox kubectl -n cma delete sandboxclaims --all在 GKE 上,也請執行此指令:
kubectl -n cma delete sandboxes --all等待沙箱消失
重複執行此指令,直到沙箱、其 pod 和其磁碟區都消失為止:
kubectl -n cma get sandboxes,pods,pvc解除安裝 chart 並刪除命名空間
helm uninstall cma --namespace cma helm uninstall cma-server --namespace cma-server kubectl delete namespace cma cma-server
後續步驟
- 升級: 升級自行託管的 Claude Managed Agents提供了
helm upgrade指令。 - 變更其他 chart 值: 請參閱伺服器的
kubernetes/server/chart/values.yaml和沙箱的kubernetes/chart/values.yaml中的註解。 - 從您的程式碼呼叫 API: 請參閱在自行託管的伺服器上呼叫 API。
- 在瀏覽器中工作: 請參閱在您的伺服器上使用主控台。
這個頁面有幫助嗎?