Auf Kubernetes bereitstellen
Installiere den Server von selbst gehostetem Claude Managed Agents und seine Sandboxes mit den beiden Helm-Charts aus dem Release-Archiv auf einem Kubernetes-Cluster und führe dann eine erste Sitzung in einem Sandbox-Pod aus.
Diese Seite führt dich von einem leeren Google Kubernetes Engine (GKE)-Cluster bis zu einer Sitzung, die ein Tool in einem Sandbox-Pod ausführt. Sie verwendet die beiden Helm-Charts im Release-Archiv, die den gesamten Stack auf dem Cluster ausführen:
cma-server: Wendet das Datenbankschema an und führt zwei Server hinter einem Service aus, im Namespacecma-server.cma-sandboxes: Führt einen Dispatcher und die Sandbox-Pods im Namespacecmaaus. Der Dispatcher fragt beim Server nach Arbeit ab und gibt jeder Sitzung ihren eigenen Sandbox-Pod, in dem ein Worker die Shell- und Datei-Tools des Agenten ausführt.
Deine PostgreSQL-Datenbank bleibt außerhalb von beiden. Auf einer anderen Art von Cluster sind die Schritte dieselben, aber die Cluster-Voraussetzungen und einige Chart-Werte unterscheiden sich. Siehe Andere Cluster.
Voraussetzungen
- Ein Cluster: Kubernetes 1.30 oder höher, mit:
- Dem Agent-Sandbox-Controller (auf GKE das Agent-Sandbox-Add-on)
- Nodes, die gVisor ausführen (auf GKE ein GKE-Sandbox-Node-Pool)
- Einem Netzwerk-Plugin, das NetworkPolicy durchsetzt (auf GKE Dataplane V2 oder Calico)
- Eine Datenbank: PostgreSQL 16 oder höher, die der Cluster erreichen kann.
- Eine Registry: Eine, aus der der Cluster pullen kann. Die Images baust du selbst.
- Ein Claude API-Key: Der Server verwendet ihn für Modellaufrufe. Um einen anderen Anbieter zu verwenden, siehe Inferenzanbieter.
- Berechtigungen: Cluster-Admin-Rechte oder Gleichwertiges. Die Installation erstellt Namespaces, Roles und ein ClusterRoleBinding.
- Tools auf deinem Rechner:
helm,kubectl,docker buildx,opensslund dieantCLI. - Das Release-Archiv: Um Zugriff auf den Download anzufordern, wende dich an dein Anthropic-Account-Team. Entpacke das Archiv. Führe jeden Befehl auf dieser Seite aus dessen oberstem Verzeichnis aus.
Den Stack installieren
Die Images bauen und pushen
Setze diese Variablen auf deine eigenen Werte.
PLATFORMist die Architektur deiner Nodes.TAGist die Version des Releases, die im Namen des Archivs nach demvsteht. Beide Charts erwarten Images, die diese Version als Tag haben.REGISTRY=us-docker.pkg.dev/my-project/cma TAG=1.2.3 PLATFORM=linux/amd64Baue und pushe dann die drei Images:
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/sandboxEine Secrets-Datei und die Datenbank erstellen
Erstelle eine Datei mit einem generierten Datenbankpasswort und einem Platzhalter für deinen Claude API-Key:
cat > secrets.env <<EOF PG_PASSWORD=$(openssl rand -hex 32) UPSTREAM_KEY=sk-ant-... EOF chmod 600 secrets.envÖffne
secrets.envin einem Editor und ersetzesk-ant-...durch deinen Claude API-Key. Verbinde dich dann als Administrator mit deinem Datenbankserver, zum Beispiel mitpsql. Führe dieses SQL aus, mit dem Wert vonPG_PASSWORDanstelle von...:CREATE ROLE cma_server LOGIN PASSWORD '...'; GRANT cma_server TO CURRENT_USER; CREATE DATABASE cma_server OWNER cma_server;Den Namespace und die Secrets des Servers erstellen
Erstelle den Namespace des Servers und seine 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"Gib den Verschlüsselungsschlüssel mit
echo "$ENCRYPTION_KEY"aus und bewahre eine Kopie außerhalb des Clusters auf. Der Server verwendet diesen Schlüssel, um die Anmeldedaten zu verschlüsseln, die er speichert, und eine wiederhergestellte Datenbank benötigt ihn. Lösche dannsecrets.env. Das Datenbankpasswort bleibt im Secretcma-server-dberhalten.Den Namespace und das Zertifikat der Sandboxes erstellen
Erstelle den Namespace der Sandboxes und ein Zertifikat, das der Dispatcher bereitstellt und dem die Sandboxes vertrauen:
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 -Den Server installieren
Speichere dies als
cma-server-values.yaml, mit deiner Registry und der Adresse deiner Datenbank: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: cmaInstalliere dann das 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-defaultDie Installation erstellt die Umgebung
defaultund speichert ihren Schlüssel im Secretcma-environmentim Namespacecma. Der zweite Befehl gibt eine Zeile aus, die mitfilled Secret cma/cma-environmentbeginnt. Wenn ein ersteshelm installfehlschlägt, führehelm uninstallfür dieses Release aus, bevor du erneut installierst.Die zu sperrenden Cluster-Adressen finden
Diese Installation ermöglicht Sandboxes den Zugriff auf das öffentliche Internet. Der API-Endpunkt eines Clusters hat meist eine öffentliche Adresse, sodass Sandboxes ihn ebenfalls erreichen könnten. Um ihn zu sperren, listest du seine Adresse im nächsten Schritt unter
egress.clusterCIDRsauf.Um die Adresse auszugeben, führe
gcloud container clusters describe my-cluster --format 'value(endpoint)'mit dem Namen deines Clusters aus.Das Chart selbst sperrt die privaten Bereiche
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16und100.64.0.0/10. Wenn dein Cluster einen Pod-, Service- oder Node-Bereich außerhalb dieser vier hat, liste auch diesen Bereich auf.Die Sandboxes installieren
Speichere dies als
cma-values.yaml, mit deiner Registry und den Adressen aus dem vorherigen Schritt: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öffnet den Weg zu deinen Servern. UmpublicInternetmit den beiden anderen Modi zu vergleichen, siehe Was Sandboxes erreichen können.Wenn dein Cluster eine dieser DNS-Konfigurationen verwendet, füge der Datei eine Zeile hinzu:
- Cloud DNS for GKE, das Autopilot-Cluster verwenden:
gke: {dns: cloudDns} - NodeLocal DNSCache:
gke: {dns: nodeLocalCache, kubeDnsUpstreamIP: <address>}. Um die Adresse auszugeben, führekubectl -n kube-system get svc kube-dns-upstream -o jsonpath='{.spec.clusterIP}'aus.
Installiere dann das Chart:
helm install cma kubernetes/chart --namespace cma -f cma-values.yaml --wait- Cloud DNS for GKE, das Autopilot-Cluster verwenden:
Eine Sitzung ausführen
Diese Schritte verwenden die Namen einer neuen Installation. Wenn deine Server-Values-Datei earlierNames: true enthält, findest du die stattdessen zu verwendenden Namen unter Kubernetes: die Namen deiner Objekte.
Den Port des Servers weiterleiten
Leite in einem Terminal den Port des Servers an deinen Rechner weiter:
kubectl -n cma-server port-forward svc/cma-server 8400:8400Die CLI auf deinen Server ausrichten
Richte in einem zweiten Terminal die
antCLI auf den weitergeleiteten Port aus und lies den Server-API-Key aus dem 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)Einen Agenten erstellen und ihn bitten, einen Befehl auszuführen
Folge drei Schritten aus dem Abschnitt Deine erste Sitzung ausführen des Schnellstarts: Einen Agenten erstellen, Eine Sitzung starten und Den Agenten bitten, einen Befehl auszuführen. Ersetze in Eine Sitzung starten
compose-sandboxdurchdefault, den Namen der Umgebung, die die Charts erstellen.Den Sandbox-Pod finden
Der Agent antwortet mit dem Hostnamen des Pods, der den Befehl ausgeführt hat. In einem dritten Terminal listet
kubectl -n cma get podseinen Pod dieses Namens neben dem des Dispatchers auf. Standardmäßig verschwindet der Pod etwa 5 Minuten, nachdem der Zug des Agenten endet. Wenn er nicht in der Liste steht, bitte den Agenten,hostnameerneut auszuführen.Um den Chat zu verlassen, drücke Strg+C.
TLS vor den Server schalten
Der Server spricht reines HTTP auf Port 8400, und Anfragen deiner Anwendungen enthalten den Server-API-Key. Bevor sich Clients von außerhalb des Clusters verbinden, schalte einen Load Balancer oder Ingress, der TLS terminiert, vor den Service cma-server. Er muss:
- Anfragepfade unverändert durchreichen.
- Anfrage-Bodys bis zu 32 MiB akzeptieren.
- Antworten ungepuffert durchreichen.
- Ein Standard-Lese-Timeout von 2 Minuten setzen. Für Git-Anfragen ein Lese-Timeout von 10 Minuten für Pfade setzen, die
^/cma-[a-z]+/git/entsprechen. - Traffic nur an Server senden, die bereit sind. Der Service
cma-servertut das bereits. Ein Load Balancer, der die Pods direkt erreicht, muss/cma-server/readyzauf jedem Pod prüfen und einen Pod überspringen, der503zurückgibt. - Niemals einen
POSTerneut senden, den ein Server bereits angenommen hat. - Niemals eine Antwort cachen.
Um dies von außerhalb des Clusters zu prüfen, führe curl -s https://<host>/cma-server/healthz aus. Die Antwort lautet {"status":"ok"}.
Was Sandboxes erreichen können
In cma-values.yaml ermöglicht egress.mode: publicInternet Sandboxes den Zugriff auf das öffentliche Internet.
Diese Tabelle vergleicht diesen Modus mit den beiden anderen Modi:
egress.mode | Was Sandboxes erreichen können |
|---|---|
closed, der Standardwert | Deine Server und den Dispatcher, und keinen DNS-Server |
publicInternet | Deine Server, den Dispatcher, einen DNS-Server und das öffentliche Internet |
gateway | Deine Server, den Dispatcher und, über das Egress-Gateway, die Hosts, die du auflistest. Siehe Das Gateway auf Kubernetes einschalten. |
Andere Cluster
Setze platform in cma-values.yaml auf eks für Amazon EKS, auf aks für Azure Kubernetes Service (AKS) oder auf generic für jeden anderen Cluster. Alle drei benötigen den Upstream-Agent-Sandbox-Controller mit seinen Erweiterungen und ein Netzwerk-Plugin, das NetworkPolicy durchsetzt. Außerdem benötigen sie:
- Amazon EKS: Eine Node-Gruppe, in der gVisors
runscals containerd-Handler mit dem Namenrunscregistriert ist. Versieh die Nodes mit dem Labelcma.anthropic.com/sandbox-node=trueund dem Taintcma.anthropic.com/sandbox-node=true:NoSchedule. Das Chart registriert die RuntimeClassgvisorfür diesen Handler. - AKS: Ein Node-Pool mit Pod Sandboxing, mit demselben Label und Taint wie bei Amazon EKS. Trage den Namen der Network-Policy-Engine des Clusters (
cilium,calicooderazure) inaks.networkPolicyein. Behalteegress.mode: publicInternetbei, den einzigen Modus, den das Chart auf AKS akzeptiert. Teste das Chart auf deinem Cluster, bevor Agenten dort echte Arbeit erledigen. - Jeder andere Cluster: Eine RuntimeClass für gVisor oder eine andere Sandbox-Runtime. Trage ihren Namen in
runtimeClass.nameein.
Der Ordner kubernetes/chart/examples/ im Archiv enthält für jede Art von Cluster eine vollständige Values-Datei.
Das Volume einer Sitzung freigeben
Mit den Standardwerten des Charts hat jede Sitzung ein 10 GiB großes Volume für /workspace. Das Volume bleibt bestehen, nachdem der Pod der Sitzung verschwunden ist, sodass die nächste Nachricht der Sitzung ihre Dateien vorfindet.
| Zum Freigeben von | Tu Folgendes |
|---|---|
| Dem Volume einer Sitzung | Archiviere die Sitzung, nachdem ihr Zug endet. Der Dispatcher löscht das Volume normalerweise innerhalb von etwa 5 Minuten. |
| Den Volumes von Sitzungen, die niemand archiviert | Setze dispatcher.retentionDays in cma-values.yaml. Der Dispatcher löscht dann ein Volume, sobald seine Sitzung so viele Tage inaktiv war, und die nächste Nachricht der Sitzung beginnt mit einem leeren /workspace. Der Standardwert des Charts, 0, behält jedes Volume. |
Die Befehle in diesem Abschnitt gelten für GKE. Verwende auf einem anderen Cluster sandboxclaims anstelle von sandboxes.
Das Löschen einer Sitzung gibt ihr Volume nicht frei. Archiviere die Sitzung zuerst. Lösche sie erst, wenn kubectl -n cma get sandboxes -l anthropic.com/session-id=<session-id> nichts auflistet.
Wenn du eine Sitzung gelöscht hast, ohne sie zu archivieren, gib ihr Volume selbst frei:
-
Finde die ID der Sitzung im Log des Dispatchers. Dieser Befehl gibt für jede Sitzung, die gelöscht zu sein scheint und noch ein Volume hat, eine Zeile aus, mit der ID nach
session_id:kubectl -n cma logs deployment/cma-dispatcher --since=6m \ | grep "could not check the claim's session" | grep "403 Forbidden"Der Dispatcher schreibt diese Zeilen alle 5 Minuten. Wenn die Sitzung nicht aufgeführt ist, warte 5 Minuten und führe den Befehl erneut aus.
-
Bestätige, dass die Sitzung gelöscht ist. Führe mit weitergeleitetem Port und gesetztem
ANTHROPIC_API_KEYwie in Eine Sitzung ausführenant --base-url http://127.0.0.1:8400 beta:sessions retrieve --session-id <session-id>aus. Fahre nur fort, wenn die Antwort404 Not FoundmitSession not foundlautet. Wenn der Befehl eine Sitzung ausgibt, hör auf: Diese Sitzung ist nicht gelöscht. -
Lösche das Kubernetes-Objekt, dem das Volume gehört. Die Dateien der Sitzung werden mit ihm gelöscht:
kubectl -n cma delete sandboxes -l anthropic.com/session-id=<session-id>
Schlüssel und Zertifikate erneuern
Ein Umgebungsschlüssel ist 365 Tage gültig, und das Zertifikat des Dispatchers ist 825 Tage gültig. Erneuere beide, bevor sie ablaufen.
In den letzten 30 Tagen eines Umgebungsschlüssels protokolliert der Server bei jeder Anfrage, die den Schlüssel verwendet, eine Warnung. Die Warnung beginnt mit environment key is within 30 days of expiry.
Den Umgebungsschlüssel erneuern, den die Charts erstellt haben
Um zu sehen, wann der Schlüssel abläuft, führe kubectl -n cma describe secret cma-environment aus.
Führe diese beiden Befehle mindestens einmal in den letzten 60 Tagen des Schlüssels aus, aus dem obersten Verzeichnis des Archivs des installierten Releases:
helm upgrade cma-server kubernetes/server/chart --namespace cma-server -f cma-server-values.yaml --wait
kubectl -n cma rollout restart deployment/cma-dispatcherJedes Mal, wenn der Befehl helm upgrade des Server-Charts ausgeführt wird, speichert er einen neuen Schlüssel im Secret, wenn der Schlüssel innerhalb von 60 Tagen abläuft. Nichts anderes erneuert den Schlüssel. Der zweite Befehl startet den Dispatcher neu, damit er den neuen Schlüssel liest.
Das Zertifikat des Dispatchers erneuern
Geh zurück zum Schritt „Den Namespace und das Zertifikat der Sandboxes erstellen“. Wiederhole dessen openssl-Befehl und die beiden kubectl-Befehle danach. Starte dann den Dispatcher mit kubectl -n cma rollout restart deployment/cma-dispatcher neu.
Einen Umgebungsschlüssel für deine eigenen Worker ersetzen
Die Charts erneuern nur ihren eigenen Schlüssel. Wenn du selbst einen Schlüssel erstellt hast, wie in Eine Umgebung und ihren Schlüssel erstellen, ersetze ihn mit der Admin-CLI. Die CLI liegt im obersten Verzeichnis des Release-Archivs.
Führe die Befehle im zweiten Terminal aus Eine Sitzung ausführen aus, in dem ANTHROPIC_API_KEY den Server-API-Key enthält. Lass die Portweiterleitung im ersten Terminal weiterlaufen. Wenn du deinen Server unter einer anderen Adresse erreichst, übergib diese Adresse als -base-url, dann brauchst du keine Portweiterleitung.
Einen neuen Schlüssel für dieselbe Umgebung erstellen
Übergib für
-envdie ID der Umgebung:echo "$ANTHROPIC_API_KEY" | ./cma-server-admin mint-key \ -base-url http://127.0.0.1:8400 -env env_01595EKxaaTTGwwY3kyXdtbs -key-file -Der Befehl gibt den neuen Schlüssel aus, und die ID und das Ablaufdatum des Schlüssels gibt er auf der Standardfehlerausgabe aus.
Deine Worker auf den neuen Schlüssel umstellen
Setze den neuen Schlüssel als
ANTHROPIC_ENVIRONMENT_KEYfür jeden Prozess, der abfragt, und starte ihn neu.Den alten Schlüssel widerrufen
Ein Worker, der noch einen widerrufenen Schlüssel verwendet, erhält einen
401-Fehler und gibt die Sitzung auf, die er bedient hat. Um die ID des alten Schlüssels zu finden, führelist-keysmit denselben Flags-base-url,-envund-key-fileaus. Wenn kein Worker den alten Schlüssel mehr verwendet, widerrufe ihn über diese 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 -
Den Stack deinstallieren
Lösche zuerst die Sandboxes. helm uninstall löscht die Netzwerkrichtlinien, die Sandboxes einschränken, aber die Sandboxes, die der Dispatcher für Sitzungen erstellt hat, laufen weiter.
Diese Schritte berühren deine Datenbank nicht, löschen aber die Secrets. Um die Datenbank erneut zu verwenden, benötigst du deine Kopie des Verschlüsselungsschlüssels.
Den Dispatcher stoppen und die Sandboxes löschen
kubectl -n cma scale deployment/cma-dispatcher --replicas=0 kubectl -n cma delete sandboxwarmpool cma-sandbox kubectl -n cma delete sandboxclaims --allFühre auf GKE außerdem diesen Befehl aus:
kubectl -n cma delete sandboxes --allWarten, bis die Sandboxes entfernt sind
Wiederhole diesen Befehl, bis die Sandboxes, ihre Pods und ihre Volumes entfernt sind:
kubectl -n cma get sandboxes,pods,pvcDie Charts deinstallieren und die Namespaces löschen
helm uninstall cma --namespace cma helm uninstall cma-server --namespace cma-server kubectl delete namespace cma cma-server
Nächste Schritte
- Aktualisieren: Selbst gehostetes Claude Managed Agents aktualisieren enthält die
helm upgrade-Befehle. - Andere Chart-Werte ändern: Siehe die Kommentare in
kubernetes/server/chart/values.yamlfür den Server undkubernetes/chart/values.yamlfür die Sandboxes. - Die API aus deinem Code aufrufen: Siehe Die API auf einem selbst gehosteten Server aufrufen.
- In einem Browser arbeiten: Siehe Die Konsole auf deinem Server verwenden.
War diese Seite hilfreich?