Menerapkan di Kubernetes
Instal server Claude Managed Agents yang di-host sendiri dan sandbox-nya pada klaster Kubernetes dengan dua Helm chart dalam arsip rilis, lalu jalankan sesi pertama di pod sandbox.
Halaman ini membawa “cluster” (klaster) Google Kubernetes Engine (GKE) yang kosong hingga menjadi sesi yang menjalankan alat di pod sandbox. Halaman ini menggunakan dua Helm chart dalam arsip rilis, yang menjalankan seluruh stack pada klaster:
cma-server: Menerapkan skema database dan menjalankan dua server di belakang sebuah Service, di “namespace” (ruang nama)cma-server.cma-sandboxes: Menjalankan sebuah dispatcher dan pod sandbox di namespacecma. Dispatcher melakukan polling ke server untuk mencari pekerjaan dan memberi setiap sesi pod sandbox-nya sendiri, tempat sebuah worker menjalankan alat shell dan file milik agen.
Database PostgreSQL Anda tetap berada di luar keduanya. Pada jenis klaster lain, langkah-langkahnya sama, tetapi prasyarat klaster dan beberapa nilai chart berbeda. Lihat Klaster lain.
Prasyarat
- Sebuah klaster: Kubernetes 1.30 atau lebih baru, dengan:
- Controller Agent Sandbox (di GKE, add-on Agent Sandbox)
- Node yang menjalankan gVisor (di GKE, node pool GKE Sandbox)
- Plugin jaringan yang menerapkan NetworkPolicy (di GKE, Dataplane V2 atau Calico)
- Sebuah database: PostgreSQL 16 atau lebih baru yang dapat dijangkau oleh klaster.
- Sebuah registry: Registry tempat klaster dapat menarik image. Anda membangun image sendiri.
- Sebuah kunci API Claude: Server menggunakannya untuk panggilan model. Untuk menggunakan penyedia lain, lihat Penyedia inferensi.
- Izin: Hak cluster-admin atau yang setara. Instalasi membuat namespace, Role, dan sebuah ClusterRoleBinding.
- Alat di mesin Anda:
helm,kubectl,docker buildx,openssl, dan CLIant. - Arsip rilis: Untuk meminta akses ke unduhan, hubungi tim akun Anthropic Anda. Ekstrak arsip tersebut. Jalankan setiap perintah di halaman ini dari direktori teratasnya.
Menginstal stack
Membangun dan mendorong image
Atur variabel-variabel ini ke nilai milik Anda.
PLATFORMadalah arsitektur node Anda.TAGadalah versi rilis, yang ada di nama arsip setelahv. Kedua chart mengharapkan image yang menggunakan versi ini sebagai tag-nya.REGISTRY=us-docker.pkg.dev/my-project/cma TAG=1.2.3 PLATFORM=linux/amd64Kemudian bangun dan dorong ketiga image tersebut:
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/sandboxMembuat file secrets dan database
Buat sebuah file berisi kata sandi database yang dihasilkan dan placeholder untuk kunci API Claude Anda:
cat > secrets.env <<EOF PG_PASSWORD=$(openssl rand -hex 32) UPSTREAM_KEY=sk-ant-... EOF chmod 600 secrets.envBuka
secrets.envdi editor dan gantisk-ant-...dengan kunci API Claude Anda. Kemudian hubungkan ke server database Anda sebagai administrator, misalnya denganpsql. Jalankan SQL ini, dengan nilaiPG_PASSWORDsebagai pengganti...:CREATE ROLE cma_server LOGIN PASSWORD '...'; GRANT cma_server TO CURRENT_USER; CREATE DATABASE cma_server OWNER cma_server;Membuat namespace dan Secret untuk server
Buat namespace milik server dan Secret-nya:
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"Cetak kunci enkripsi dengan
echo "$ENCRYPTION_KEY", dan simpan salinannya di luar klaster. Server menggunakan kunci ini untuk mengenkripsi kredensial yang disimpannya, dan database yang dipulihkan membutuhkannya. Kemudian hapussecrets.env. Secretcma-server-dbmenyimpan kata sandi database.Membuat namespace dan sertifikat untuk sandbox
Buat namespace untuk sandbox, serta sertifikat yang disajikan oleh dispatcher dan dipercaya oleh sandbox:
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 -Menginstal server
Simpan ini sebagai
cma-server-values.yaml, dengan registry Anda dan alamat database Anda: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: cmaKemudian instal chart tersebut:
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-defaultInstalasi ini membuat environment
defaultdan menyimpan kuncinya di Secretcma-environmentdi namespacecma. Perintah kedua mencetak satu baris yang diawalifilled Secret cma/cma-environment. Jikahelm installpertama gagal, jalankanhelm uninstalluntuk rilis tersebut sebelum Anda menginstal lagi.Menemukan alamat klaster yang akan diblokir
Instalasi ini memungkinkan sandbox menjangkau internet publik. Endpoint API klaster biasanya memiliki alamat publik, sehingga sandbox juga dapat menjangkaunya. Untuk memblokirnya, Anda mencantumkan alamatnya di bawah
egress.clusterCIDRspada langkah berikutnya.Untuk mencetak alamat tersebut, jalankan
gcloud container clusters describe my-cluster --format 'value(endpoint)'dengan nama klaster Anda.Chart itu sendiri memblokir rentang privat
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16, dan100.64.0.0/10. Jika klaster Anda memiliki rentang pod, service, atau node di luar keempat rentang tersebut, cantumkan juga rentang itu.Menginstal sandbox
Simpan ini sebagai
cma-values.yaml, dengan registry Anda dan alamat dari langkah sebelumnya: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.cmaServermembuka jalur ke server Anda. Untuk membandingkanpublicInternetdengan dua mode lainnya, lihat Apa yang dapat dijangkau sandbox.Jika klaster Anda menggunakan salah satu penyiapan DNS ini, tambahkan satu baris ke file tersebut:
- Cloud DNS for GKE, yang digunakan oleh klaster Autopilot:
gke: {dns: cloudDns} - NodeLocal DNSCache:
gke: {dns: nodeLocalCache, kubeDnsUpstreamIP: <address>}. Untuk mencetak alamat tersebut, jalankankubectl -n kube-system get svc kube-dns-upstream -o jsonpath='{.spec.clusterIP}'.
Kemudian instal chart tersebut:
helm install cma kubernetes/chart --namespace cma -f cma-values.yaml --wait- Cloud DNS for GKE, yang digunakan oleh klaster Autopilot:
Menjalankan sesi
Langkah-langkah ini menggunakan nama dari instalasi baru. Jika file values server Anda memiliki earlierNames: true, temukan nama yang harus digunakan sebagai gantinya di Kubernetes: nama objek Anda.
Meneruskan port server
Di satu terminal, teruskan port server ke mesin Anda:
kubectl -n cma-server port-forward svc/cma-server 8400:8400Mengarahkan CLI ke server Anda
Di terminal kedua, arahkan
antCLI ke port yang di-forward dan baca kunci API server dari Secretcma-server-keys: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)Membuat agen dan memintanya menjalankan perintah
Ikuti tiga langkah dari Jalankan sesi pertama Anda di quickstart: Buat agen, Mulai sesi, dan Minta agen menjalankan perintah. Di Mulai sesi, ganti
compose-sandboxdengandefault, nama environment yang dibuat oleh chart.Menemukan pod sandbox
Agen membalas dengan hostname pod yang menjalankan perintah tersebut. Di terminal ketiga,
kubectl -n cma get podsmenampilkan pod dengan nama itu di samping pod milik dispatcher. Secara default, pod tersebut hilang sekitar 5 menit setelah giliran agen berakhir. Jika pod tersebut tidak ada dalam daftar, minta agen menjalankanhostnamelagi.Untuk keluar dari chat, tekan Ctrl+C.
Menempatkan TLS di depan server
Server berbicara HTTP biasa pada port 8400, dan permintaan dari aplikasi Anda membawa kunci API server. Sebelum klien di luar klaster terhubung, tempatkan “load balancer” (penyeimbang beban) atau ingress yang melakukan terminasi TLS di depan Service cma-server. Komponen tersebut harus:
- Meneruskan path permintaan tanpa perubahan.
- Menerima body permintaan hingga 32 MiB.
- Meneruskan respons tanpa buffer.
- Menetapkan batas waktu baca default 2 menit. Untuk permintaan Git, tetapkan batas waktu baca 10 menit untuk path yang cocok dengan
^/cma-[a-z]+/git/. - Mengirim lalu lintas hanya ke server yang siap. Service
cma-serversudah melakukan ini. Load balancer yang menjangkau pod secara langsung harus memeriksa/cma-server/readyzpada setiap pod dan melewati pod yang mengembalikan503. - Tidak pernah mengirim ulang
POSTyang sudah diterima oleh server. - Tidak pernah menyimpan respons dalam cache.
Untuk memeriksanya dari luar klaster, jalankan curl -s https://<host>/cma-server/healthz. Responsnya adalah {"status":"ok"}.
Apa yang dapat dijangkau sandbox
Di cma-values.yaml, egress.mode: publicInternet memungkinkan sandbox menjangkau internet publik.
Tabel ini membandingkannya dengan dua mode lainnya:
egress.mode | Apa yang dapat dijangkau sandbox |
|---|---|
closed, nilai default | Server Anda dan dispatcher, tanpa server DNS |
publicInternet | Server Anda, dispatcher, server DNS, dan internet publik |
gateway | Server Anda, dispatcher, dan, melalui egress gateway, host yang Anda cantumkan. Lihat Aktifkan gateway di Kubernetes. |
Klaster lain
Atur platform di cma-values.yaml ke eks untuk Amazon EKS, ke aks untuk Azure Kubernetes Service (AKS), atau ke generic untuk klaster lain mana pun. Ketiganya memerlukan controller Agent Sandbox upstream beserta ekstensinya, dan plugin jaringan yang menerapkan NetworkPolicy. Semuanya juga memerlukan:
- Amazon EKS: Node group dengan
runscmilik gVisor yang terdaftar sebagai handler containerd bernamarunsc. Beri label pada node dengancma.anthropic.com/sandbox-node=true, dan beri taint dengancma.anthropic.com/sandbox-node=true:NoSchedule. Chart mendaftarkan RuntimeClassgvisorterhadap handler tersebut. - AKS: Node pool dengan Pod Sandboxing, dengan label dan taint yang sama seperti di Amazon EKS. Masukkan nama mesin kebijakan jaringan klaster (
cilium,calico, atauazure) diaks.networkPolicy. Pertahankanegress.mode: publicInternet, satu-satunya mode yang diterima chart di AKS. Ujilah chart ini di klaster Anda sebelum agen melakukan pekerjaan nyata di sana. - Klaster lain mana pun: Sebuah RuntimeClass untuk gVisor atau runtime tersandbox lainnya. Masukkan namanya di
runtimeClass.name.
Folder kubernetes/chart/examples/ di dalam arsip berisi file values lengkap untuk setiap jenis klaster.
Membebaskan volume sesi
Dengan default chart, setiap sesi memiliki volume 10 GiB untuk /workspace. Volume tersebut tetap ada setelah pod sesi hilang, sehingga pesan berikutnya dari sesi tersebut menemukan file-filenya.
| Untuk membebaskan | Lakukan ini |
|---|---|
| Volume satu sesi | Arsipkan sesi setelah gilirannya berakhir. Dispatcher biasanya menghapus volume tersebut dalam sekitar 5 menit. |
| Volume sesi yang tidak diarsipkan oleh siapa pun | Atur dispatcher.retentionDays di cma-values.yaml. Dispatcher kemudian menghapus volume setelah sesinya menganggur selama jumlah hari tersebut, dan pesan berikutnya dari sesi tersebut dimulai dengan /workspace yang kosong. Default chart, 0, menyimpan setiap volume. |
Perintah-perintah di bagian ini ditujukan untuk GKE. Di klaster lain, gunakan sandboxclaims sebagai pengganti sandboxes.
Menghapus sesi tidak membebaskan volumenya. Arsipkan sesi terlebih dahulu. Hapus sesi tersebut hanya setelah kubectl -n cma get sandboxes -l anthropic.com/session-id=<session-id> tidak menampilkan apa pun.
Jika Anda menghapus sesi tanpa mengarsipkannya, bebaskan volumenya sendiri:
-
Temukan ID sesi di log dispatcher. Perintah ini mencetak satu baris untuk setiap sesi yang tampaknya telah dihapus dan masih memiliki volume, dengan ID setelah
session_id:kubectl -n cma logs deployment/cma-dispatcher --since=6m \ | grep "could not check the claim's session" | grep "403 Forbidden"Dispatcher menulis baris-baris ini setiap 5 menit. Jika sesi tersebut tidak tercantum, tunggu 5 menit lalu jalankan perintah itu lagi.
-
Pastikan bahwa sesi tersebut telah dihapus. Dengan port yang di-forward dan
ANTHROPIC_API_KEYyang diatur seperti di Menjalankan sesi, jalankanant --base-url http://127.0.0.1:8400 beta:sessions retrieve --session-id <session-id>. Lanjutkan hanya jika jawabannya adalah404 Not FounddenganSession not found. Jika perintah tersebut mencetak sebuah sesi, berhenti: sesi tersebut belum dihapus. -
Hapus objek Kubernetes yang memiliki volume tersebut. File-file sesi ikut terhapus bersamanya:
kubectl -n cma delete sandboxes -l anthropic.com/session-id=<session-id>
Memperbarui kunci dan sertifikat
Kunci environment berlaku selama 365 hari, dan sertifikat dispatcher berlaku selama 825 hari. Perbarui masing-masing sebelum kedaluwarsa.
Dalam 30 hari terakhir masa berlaku kunci environment, server mencatat peringatan pada setiap permintaan yang menggunakan kunci tersebut. Peringatan tersebut diawali environment key is within 30 days of expiry.
Memperbarui kunci environment yang dibuat oleh chart
Untuk melihat kapan kunci tersebut kedaluwarsa, jalankan kubectl -n cma describe secret cma-environment.
Jalankan dua perintah ini setidaknya sekali dalam 60 hari terakhir masa berlaku kunci, dari direktori teratas arsip rilis yang terinstal:
helm upgrade cma-server kubernetes/server/chart --namespace cma-server -f cma-server-values.yaml --wait
kubectl -n cma rollout restart deployment/cma-dispatcherSetiap kali perintah helm upgrade milik chart server dijalankan, perintah tersebut menyimpan kunci baru di Secret jika kunci kedaluwarsa dalam 60 hari. Tidak ada hal lain yang memperbarui kunci. Perintah kedua memulai ulang dispatcher agar membaca kunci baru.
Memperbarui sertifikat dispatcher
Kembali ke langkah “Membuat namespace dan sertifikat untuk sandbox”. Ulangi perintah openssl-nya dan dua perintah kubectl setelahnya. Lalu mulai ulang dispatcher dengan kubectl -n cma rollout restart deployment/cma-dispatcher.
Mengganti kunci environment untuk worker Anda sendiri
Chart hanya memperbarui kuncinya sendiri. Jika Anda membuat kunci sendiri, seperti di Membuat environment dan kuncinya, ganti kunci tersebut dengan CLI admin. CLI tersebut berada di direktori teratas arsip rilis.
Jalankan perintah-perintah tersebut di terminal kedua dari Menjalankan sesi, tempat ANTHROPIC_API_KEY berisi kunci API server. Biarkan port-forward tetap berjalan di terminal pertama. Jika Anda menjangkau server Anda di alamat lain, berikan alamat tersebut sebagai -base-url, dan Anda tidak memerlukan port-forward.
Membuat kunci baru untuk environment yang sama
Untuk
-env, berikan ID environment:echo "$ANTHROPIC_API_KEY" | ./cma-server-admin mint-key \ -base-url http://127.0.0.1:8400 -env env_01595EKxaaTTGwwY3kyXdtbs -key-file -Perintah ini mencetak kunci baru, dan mencetak ID serta waktu kedaluwarsa kunci pada standard error.
Memindahkan worker Anda ke kunci baru
Atur kunci baru sebagai
ANTHROPIC_ENVIRONMENT_KEYuntuk setiap proses yang melakukan polling, lalu mulai ulang proses tersebut.Mencabut kunci lama
Worker yang masih menggunakan kunci yang telah dicabut akan menerima error
401dan melepaskan sesi yang sedang dilayaninya. Untuk menemukan ID kunci lama, jalankanlist-keysdengan flag-base-url,-env, dan-key-fileyang sama. Ketika tidak ada lagi worker yang menggunakan kunci lama, cabut kunci tersebut berdasarkan ID itu: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 -
Menghapus instalasi stack
Hapus sandbox terlebih dahulu. helm uninstall menghapus kebijakan jaringan yang membatasi sandbox, tetapi sandbox yang dibuat oleh dispatcher untuk sesi tetap berjalan.
Langkah-langkah ini tidak menyentuh database Anda, tetapi menghapus Secret. Untuk menggunakan database lagi, Anda memerlukan salinan kunci enkripsi Anda.
Menghentikan dispatcher dan menghapus sandbox
kubectl -n cma scale deployment/cma-dispatcher --replicas=0 kubectl -n cma delete sandboxwarmpool cma-sandbox kubectl -n cma delete sandboxclaims --allDi GKE, jalankan juga perintah ini:
kubectl -n cma delete sandboxes --allMenunggu hingga sandbox hilang
Ulangi perintah ini hingga sandbox, pod-nya, dan volume-nya hilang:
kubectl -n cma get sandboxes,pods,pvcMenghapus instalasi chart dan menghapus namespace
helm uninstall cma --namespace cma helm uninstall cma-server --namespace cma-server kubectl delete namespace cma cma-server
Langkah selanjutnya
- Meningkatkan: Meningkatkan Claude Managed Agents yang di-host sendiri berisi perintah-perintah
helm upgrade. - Mengubah nilai chart lainnya: Lihat komentar di
kubernetes/server/chart/values.yamluntuk server dankubernetes/chart/values.yamluntuk sandbox. - Memanggil API dari kode Anda: Lihat Memanggil API pada server yang di-host sendiri.
- Bekerja di browser: Lihat Gunakan konsol di server Anda.
Apakah halaman ini membantu?