Claude Platform Docs
Managed AgentsSelbst gehostetes Managed Agents

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 Namespace cma-server.
  • cma-sandboxes: Führt einen Dispatcher und die Sandbox-Pods im Namespace cma aus. 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, openssl und die ant CLI.
  • 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

  1. Die Images bauen und pushen

    Setze diese Variablen auf deine eigenen Werte. PLATFORM ist die Architektur deiner Nodes. TAG ist die Version des Releases, die im Namen des Archivs nach dem v steht. Beide Charts erwarten Images, die diese Version als Tag haben.

    REGISTRY=us-docker.pkg.dev/my-project/cma
    TAG=1.2.3
    PLATFORM=linux/amd64

    Baue 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/sandbox
  2. Eine 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.env in einem Editor und ersetze sk-ant-... durch deinen Claude API-Key. Verbinde dich dann als Administrator mit deinem Datenbankserver, zum Beispiel mit psql. Führe dieses SQL aus, mit dem Wert von PG_PASSWORD anstelle von ...:

    CREATE ROLE cma_server LOGIN PASSWORD '...';
    GRANT cma_server TO CURRENT_USER;
    CREATE DATABASE cma_server OWNER cma_server;
  3. 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 dann secrets.env. Das Datenbankpasswort bleibt im Secret cma-server-db erhalten.

  4. 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 -
  5. 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: cma

    Installiere 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-default

    Die Installation erstellt die Umgebung default und speichert ihren Schlüssel im Secret cma-environment im Namespace cma. Der zweite Befehl gibt eine Zeile aus, die mit filled Secret cma/cma-environment beginnt. Wenn ein erstes helm install fehlschlägt, führe helm uninstall für dieses Release aus, bevor du erneut installierst.

  6. 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.clusterCIDRs auf.

    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/16 und 100.64.0.0/10. Wenn dein Cluster einen Pod-, Service- oder Node-Bereich außerhalb dieser vier hat, liste auch diesen Bereich auf.

  7. 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: 8400

    egress.cmaServer öffnet den Weg zu deinen Servern. Um publicInternet mit 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ühre kubectl -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

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.

  1. 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:8400
  2. Die CLI auf deinen Server ausrichten

    Richte in einem zweiten Terminal die ant CLI auf den weitergeleiteten Port aus und lies den Server-API-Key aus dem Secret cma-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)
  3. 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-sandbox durch default, den Namen der Umgebung, die die Charts erstellen.

  4. 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 pods einen 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, hostname erneut 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-server tut das bereits. Ein Load Balancer, der die Pods direkt erreicht, muss /cma-server/readyz auf jedem Pod prüfen und einen Pod überspringen, der 503 zurückgibt.
  • Niemals einen POST erneut 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.modeWas Sandboxes erreichen können
closed, der StandardwertDeine Server und den Dispatcher, und keinen DNS-Server
publicInternetDeine Server, den Dispatcher, einen DNS-Server und das öffentliche Internet
gatewayDeine 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 runsc als containerd-Handler mit dem Namen runsc registriert ist. Versieh die Nodes mit dem Label cma.anthropic.com/sandbox-node=true und dem Taint cma.anthropic.com/sandbox-node=true:NoSchedule. Das Chart registriert die RuntimeClass gvisor fü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, calico oder azure) in aks.networkPolicy ein. Behalte egress.mode: publicInternet bei, 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.name ein.

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 vonTu Folgendes
Dem Volume einer SitzungArchiviere die Sitzung, nachdem ihr Zug endet. Der Dispatcher löscht das Volume normalerweise innerhalb von etwa 5 Minuten.
Den Volumes von Sitzungen, die niemand archiviertSetze 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:

  1. 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.

  2. Bestätige, dass die Sitzung gelöscht ist. Führe mit weitergeleitetem Port und gesetztem ANTHROPIC_API_KEY wie in Eine Sitzung ausführen ant --base-url http://127.0.0.1:8400 beta:sessions retrieve --session-id <session-id> aus. Fahre nur fort, wenn die Antwort 404 Not Found mit Session not found lautet. Wenn der Befehl eine Sitzung ausgibt, hör auf: Diese Sitzung ist nicht gelöscht.

  3. 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-dispatcher

Jedes 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.

  1. Einen neuen Schlüssel für dieselbe Umgebung erstellen

    Übergib für -env die 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.

  2. Deine Worker auf den neuen Schlüssel umstellen

    Setze den neuen Schlüssel als ANTHROPIC_ENVIRONMENT_KEY für jeden Prozess, der abfragt, und starte ihn neu.

  3. 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ühre list-keys mit denselben Flags -base-url, -env und -key-file aus. 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.

  1. 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 --all

    Führe auf GKE außerdem diesen Befehl aus:

    kubectl -n cma delete sandboxes --all
  2. Warten, bis die Sandboxes entfernt sind

    Wiederhole diesen Befehl, bis die Sandboxes, ihre Pods und ihre Volumes entfernt sind:

    kubectl -n cma get sandboxes,pods,pvc
  3. Die 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

War diese Seite hilfreich?