Selbstgehostete Umgebungen befinden sich in der öffentlichen Beta auf Team- und Enterprise-Plänen; ein Inhaber aktiviert sie, indem er Selbstgehostete Umgebungen zulassen auf der Cloud-Umgebungen Admin-Seite einschaltet. Diese Seite ist die Flag- und Metrik-Referenz; siehe den Schnellstart für die Einrichtung und In Produktion bereitstellen für die Fleet-Rezepte.
/workspace und ~/.claude angenommen werden. Führen Sie claude self-hosted-runner --help aus, um die autoritative Liste in Ihrer installierten Version zu erhalten.
Metrische Reihen und einige wenige API-Felder verwenden immer noch pool für das, was diese Seiten eine Umgebung nennen; beide Begriffe bezeichnen dasselbe. Die Umgebungs-ID ist das Feld pool_id mit der Form ccpool_...: Überall dort, wo diese Seiten einen pool-Bezeichner anzeigen, benennt er die Umgebung. CLI-Flags und Umgebungsvariablen schreiben es als environment, wie z. B. --environment-secret-file; die veralteten pool-Schreibweisen funktionieren immer noch, wie die Zeile --environment-secret-file beschreibt.
Runner-CLI-Flags
Die meisten Flags haben eine entsprechende Umgebungsvariable. Wenn beide gesetzt sind, hat das Flag Vorrang. Duration-Flags nehmen Minuten oder Sekunden in der CLI, aber die gepaarte Umgebungsvariable ist immer in Millisekunden, angezeigt durch das Suffix_MS, und die Spalte Standard zeigt die Einheit des Flags: --exit-if-unused-min 10 entspricht SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS=600000, und ein Helm-Wert wie SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS: "15" bedeutet 15 Millisekunden, nicht die 15-Minuten-Standard.
Die meisten Duration-Flags haben ein Maximum, das gewählt wurde, um jeden Timeout unter der 32-Bit-Timer-Obergrenze der Laufzeit von ungefähr 24,85 Tagen zu halten. Die
--*-min Flags sind auf 10080 Minuten, 7 Tage begrenzt; --drain-grace-sec auf 604800 Sekunden, auch 7 Tage; und --drain-wait-sec auf 86400 Sekunden, 24 Stunden. --session-stop-grace-sec und --post-session-hook-timeout-sec sind unbegrenzt. Das Überschreiten einer Obergrenze verhält sich je nach Oberfläche unterschiedlich:
- Flag: Der Start schlägt mit einem Fehler fehl.
- Umgebungsvariable: Der Runner begrenzt den Wert auf die Timer-Obergrenze, anstatt ihn abzulehnen.
Timeout beim Sitzungsstart
Wenn eine Sitzung ihren Slot während eines Turns wie/code-review verloren hat, aktualisieren Sie den Runner und die Binärdatei des Kindprozesses auf v2.1.309 oder später. Von v2.1.299 bis v2.1.308 gab der Runner eine Sitzung, selbst mitten in einem Turn, frei, sobald der Start-Timeout ohne eine user- oder assistant-Nachricht abgelaufen war.
Mit --startup-timeout-min <n> gibt der Runner den Slot einer Sitzung frei, wenn sich ihr Kindprozess nicht innerhalb von <n> Minuten nach dem Klonen initialisiert hat. Während eines Turns, der beginnt, bevor sich der Kindprozess initialisiert, behält die Sitzung ihren Slot, bis <n> Minuten ohne eine Zeile auf dem Activity-Kanal des Kindprozesses vergehen. Sobald sich der Kindprozess initialisiert, setzt der Runner diese Zählung zurück, und --release-idle-session-min steuert die Freigabe. Um eine Sitzung zu begrenzen, deren Kindprozess läuft, aber feststeckt, setzen Sie --kill-session-after-min.
Regellisten des Auto-Modus
Mit--server-auto-mode-lists legen Sie fest, welche Klassifikatorregeln des Auto-Modus von außerhalb des Runners die Sitzungen auf Ihren Runnern erreichen. Die Control Plane von Anthropic kann Regellisten mit einer Sitzung senden und den Runner auffordern, sie anzuwenden. Einige Einträge können Regeln sein, die ein Admin Ihrer Organisation geschrieben hat. Die Listen sind environment, soft_deny und allow:
environment: Ein Eintrag kann den Klassifikator dazu bringen, sowohl mehr als auch weniger zuzulassen.soft_deny: Ein Eintrag blockiert eine Aktion, es sei denn, der Benutzer hat ausdrücklich darum gebeten oder eineallow-Ausnahme greift.allow: Die Ausnahmen zusoft_deny-Einträgen.
no-allow: Der Standard. Wendetenvironmentundsoft_denyan und hältallowzurück. Einenvironment-Eintrag kann den Klassifikator weiterhin dazu bringen, mehr zuzulassen, sodass der Standard nicht jede Lockerung ausschließt.all: Wendet alle drei Listen an.none: Wendet keine davon an. Wählen Sienone, um jede Lockerung durch diese Listen auszuschließen. Dabei entfallen auch die Einschränkungen vonsoft_deny.
--log-level debug. Für jede Sitzung protokolliert der Runner dann eine Zeile, die the server asked this runner to apply enthält, oder eine, die the server did not ask this runner to apply the auto mode lists it sends enthält.
Orchestrator-CLI-Flags
Der Unterbefehlself-hosted-runner orchestrator, der On-Demand-Runner erzeugt, akzeptiert --api-url, --environment-secret-file, --hooks-dir, --health-port und --log-level mit denselben Standardwerten wie der Runner und, wo das Flag des Runners einen hat, dieselbe Umgebungsvariable, außer dass --hooks-dir erforderlich ist und einen spawn-runner Hook enthalten muss. Es nimmt auch seine eigenen Flags:
SCM-Connector-Flags
Der SCM-Connector ist nicht verfügbar, daher lassen Sie die Flags in diesem Abschnitt nicht gesetzt. Wenn Sie--scm-connector-host setzen, wird die Verbindung nicht geöffnet, und der Orchestrator versucht weiterhin, sie zu verbinden. Runner starten weiterhin als Sitzungen in der Warteschlange.
Der Connector ist eine stehende WebSocket-Verbindung vom Orchestrator zur Anthropic-Kontrolleben. Er ist so konzipiert, dass gehostete Pre-Session-Flows, wie der Repository-Picker und der Branch- oder Ref-Resolver, einen GitHub Enterprise Server-Host erreichen können, der nur von innerhalb Ihres Netzwerks erreichbar ist. Siehe Netzwerkanforderungen auf der GitHub Enterprise Server-Seite für das, was diese Flows benötigen.
Bei jedem Verbindungsversuch sendet der Orchestrator sein bestehendes Umgebungsgeheimnis, und er versucht automatisch erneut mit exponentiellem Backoff, begrenzt auf 30 Sekunden plus Jitter.
Nur-Umgebungsvariablen-Einstellungen
Diese Runner-Einstellungen werden nur aus der Umgebung gelesen und decken Verhalten ab, das die meisten Bereitstellungen bei der Standardeinstellung belassen:Telemetrie
Session-Kinder senden operative Telemetrie an Anthropic, es sei denn, Sie schalten sie aus. Kein Code oder Repository-Inhalt wird gesendet. Setzen Sie Telemetrie-Variablen auf dem Runner-Prozess; der Runner bekräftigt sie erneut, nachdem er von der Kontrolleben bereitgestellte Umgebungsvariablen angewendet hat, sodass die Einstellung des Operators immer Vorrang hat. Ein Steuerelement ist spezifisch für selbstgehostete Umgebungen:CLAUDE_CODE_BYOC_ENABLE_DATADOG=1 meldet sich für Datadog-Operationsmetriken an, die in selbstgehosteten Umgebungen standardmäßig aus sind. Die allgemeinen Claude Code-Telemetrie-Steuerelemente, DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_ERROR_REPORTING und CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, gelten für Session-Kinder wie in der Umgebungsvariablen-Referenz dokumentiert. DISABLE_GROWTHBOOK ist verwandt, aber anders: Das Setzen von DISABLE_GROWTHBOOK=1 deaktiviert das Abrufen von Feature-Flags, und die Telemetrie bleibt an, es sei denn, DISABLE_TELEMETRY ist auch gesetzt.
CLAUDE_CODE_ENABLE_TELEMETRY ist nicht verwandt: Es aktiviert OpenTelemetry-Export zu Ihrem eigenen Collector, wie in Überwachung beschrieben, und steuert nicht Anthropics Analytik.
Health-Endpunkt
Der Runner bedientGET /healthz auf dem konfigurierten Health-Port. Die Antwort ist 200 OK, wann immer der Prozess am Leben ist, unabhängig davon, in welchem Zustand sich die Abfrageschleife befindet, sodass ein HTTP-Probe auf diesem Endpunkt nur einen toten Prozess erkennt. Der JSON-Body beschreibt den aktuellen Zustand:
last_poll_age_ms als Lebendigkeitssignal in benutzerdefinierten Proben; ein Wert, der unbegrenzt wächst, zeigt an, dass die Abfrageschleife steckt. Sowohl last_poll_at als auch last_poll_age_ms sind null, bis die erste Abfrage abgeschlossen ist.
Der eigene /healthz-Endpunkt des Orchestrators auf seinem Health-Port gibt immer 200 zurück. Der Body enthält ein Feld connected, das meldet, ob die letzte Abfrage erfolgreich war, sowie Zählungen der Spawn-Queue pro Status in queue_counts. Um zu sehen, warum connected den Wert false hat, lesen Sie das Feld last_error auf oberster Ebene, das bei jeder erfolgreichen Abfrage auf null zurückgesetzt wird. Machen Sie Bereitschaftsprüfungen und Warnungen von connected abhängig statt vom Statuscode.
Wenn der SCM-Connector konfiguriert ist, trägt der Body des /healthz des Orchestrators auch scm_connector_connected und ein Objekt scm_connector mit connected, last_connected_at, last_error, reconnects und requests_forwarded. Beide Felder sind null, wenn --scm-connector-host nicht gesetzt ist.
Prometheus-Metriken
Jeder Runner stellt Prometheus-Metriken unterGET /metrics auf demselben Port wie /healthz bereit. Wichtige Serien:
Der Orchestrator stellt seine eigenen Serien unter
GET /metrics auf demselben Port wie sein /healthz bereit:
Wählen Sie für das Autoscaling die Serie, die zu Ihrer Skalierungsart passt, und filtern Sie sie, bevor sie in den Scaler eingespeist wird:
- Skalierung nach Warteschlangentiefe: Speisen Sie
claude_code_self_hosted_orchestrator_pool_pending_sessionsin Ihren HPA- oder KEDA-Scaler ein, nichtqueue_pending_sessions. - Skalierung nach Kapazität: Skalieren Sie anhand des Verhältnisses von
active_sessionszucapacitydes Runners. - Filtern nach
connected: Filtern Sie die Abfrage pro Instanz mitclaude_code_self_hosted_orchestrator_connected == 1, damit der veraltete Wert eines getrennten Replikats nicht in den Scaler gelangt.
ignoreNullValues: "true" jedoch als null und skaliert herunter; setzen Sie ignoreNullValues: "false" im ScaledObject, optional mit einer fallback-Untergrenze für Replikate.
Der folgende PodMonitor für den Prometheus Operator deckt beide Prozesse ab. Er wählt Pods anhand des Labels app.kubernetes.io/part-of: claude-code-self-hosted-runner und des benannten Ports health aus, die das Kubernetes-Rezept festlegt; passen Sie die Namespaces an Ihr Deployment an:
Beispiel-Alarmregeln
Diese Beispiel-Alarmregeln sind ein Ausgangspunkt; passen Sie die Schwellenwerte an die Größe Ihrer Flotte an:Bei verlorenen Runnern und wartenden Sitzungen alarmieren
Laden Sie bei einer festen FlotteClaudeRunnersBelowFloor. Laden Sie bei On-Demand-Runnern stattdessen ClaudeOrchestratorSessionsWaiting und ClaudeOrchestratorQueueWaitHigh.
Alarmieren, wenn eine feste Flotte Runner verliert
ClaudeRunnersBelowFloor wird ausgelöst, wenn 10 Minuten lang weniger registrierte und gescrapte Runner als die Untergrenze übrig sind:
- Untergrenze: Setzen Sie die
2inexprauf etwa die Hälfte Ihrer Replikatanzahl, aufgerundet. Behalten Sie bei drei Replikaten2bei; der Alarm wird dann ausgelöst, wenn nur noch ein Runner oder keiner übrig ist. - Namespace: Ersetzen Sie
claude-runnersim Matcher und inlabels, und kopieren Sie den Alarm für jeden weiteren Namespace. Wenn Ihre Ziele keinnamespace-Label haben, entfernen Sie den Matcher und das Label, da der Alarm sonst 0 liest und ausgelöst wird. ClaudeRunnerPollStaleundClaudeRunnerPollErrors: Lassen Sie diese aus den Beispiel-Alarmregeln geladen, daClaudeRunnersBelowFlooreinen Runner, der nicht pollen kann, weiterhin mitzählt
Alarmieren, wenn Sitzungen auf On-Demand-Runner warten
ClaudeOrchestratorSessionsWaiting wird ausgelöst, wenn die Anzahl der Sitzungen, die auf einen Runner warten, 10 Minuten lang über 0 bleibt. ClaudeOrchestratorQueueWaitHigh wird ausgelöst, wenn mehr als 1 % der Wartezeiten in der Warteschlange in den letzten 10 Minuten 160 Sekunden überschritten haben und dies 5 Minuten lang anhält:
- Schwellenwert: Wenn ständig irgendeine Sitzung wartet, erhöhen Sie das
> 0inClaudeOrchestratorSessionsWaitingüber die Anzahl, die Sie üblicherweise sehen ClaudeOrchestratorDisconnected: Lassen Sie diesen Alarm aus den Beispiel-Alarmregeln geladen, daClaudeOrchestratorSessionsWaitingetwa 2 Minuten, nachdem der letzte Orchestrator im Namespace die Verbindung verloren hat, nicht mehr ausgelöst wird
Metriken der Sitzungs-Kindprozesse durchreichen
Jede Sitzung läuft in ihrem eigenen Kindprozess mit eigenen OpenTelemetry-Metriken; bei einem--capacity-Wert über eins schreibt der Runner um, wie diese Metriken der Kindprozesse bereitgestellt werden. Wenn Sie OTEL_METRICS_EXPORTER=prometheus auf dem Runner-Host und CLAUDE_CODE_ENABLE_TELEMETRY=1 in der Umgebung der Sitzung setzen, zum Beispiel über Ihr Wrapper-Skript oder die eigene Umgebung des Runners, die Sitzungen erben, werden die Counter- und Gauge-Instrumente jedes Kindprozesses zusätzlich auf dem eigenen /metrics-Endpunkt des Runners neben den Serien des Runners bereitgestellt. Der Runner schreibt den Exporter des Kindprozesses so um, dass er per OTLP an einen nur über Loopback erreichbaren Empfänger auf dem Health-Port sendet, versieht jede Serie mit den Labels session_id und client_platform und entfernt die Serien einer Sitzung, wenn diese Sitzung endet. Histogramme werden nicht durchgereicht, und eine Metrik des Kindprozesses, deren Name mit dem eigenen Präfix des Runners kollidieren würde, wird verworfen.
Beim Standardwert --capacity 1 greift diese Umschreibung nicht: Der Kindprozess der Sitzung bindet wie gewohnt seinen eigenen Prometheus-Endpunkt an Port 9464.
Metriken einer Sitzung mit denen des Runners verknüpfen
Um zu sehen, was inaktive Sitzungen gekostet haben, verknüpfen Sieclaude_code_self_hosted_runner_session_idle_seconds des Runners über ccr_session_id mit der Kostenmetrik von Claude Code. Die Metrik des Runners trägt dieses Label nicht; fügen Sie es daher wie in dieser Abfrage mit label_replace hinzu:
claude_code_cost_usage_total in der Abfrage. Die Abfrage funktioniert bei jedem --capacity-Wert.
session_id: Auf Port 9464 enthält dieses Label bei Claude Code-Metriken die eigenesession.idvon Claude Code, die zu keiner Serie des Runners passt. Eine Verknüpfung darüber liefert nichts; verknüpfen Sie daher überccr_session_id.- Claude Code-Metriken haben kein
ccr_session_id: Prüfen Sie, dassOTEL_METRICS_INCLUDE_SESSION_IDnicht auffalsegesetzt ist
Semantik der Zähler für den Sitzungslebenszyklus
Die Zählersessions_started_total, sessions_completed_total, sessions_failed_total und sessions_interrupted_total klassifizieren jede Sitzung danach, wie sie beendet wurde. Jeder gestartete Kindprozess einer Sitzung erhöht sessions_started_total beim Start, und genau einer der anderen drei Zähler wird beim Beenden erhöht; sessions_started_total minus der Summe der anderen drei entspricht also der Anzahl der aktuell laufenden Kindprozesse von Sitzungen.
completed: Die Sitzung wurde sauber beendet. Dazu gehört, dass der Kindprozess sich selbst mit Code0beendet, dass die Sitzung archiviert oder gelöscht wird, während der Kindprozess noch verbunden war, und dass der Runner den Slot sauber zurückgibt: durch Freigabe der Sitzung beim Inaktivitäts-Timeout, zum Ausmusterungszeitpunkt oder beim Limit--kill-session-after-min; durch einen Start-Timeout; oder durch eine serverseitige Aufhebung der Zuweisung, die die Poll-Schleife bemerkt hat, bevor der Kindprozess beendet wurde. Erhöhtsessions_completed_total.failed: Der Kindprozess hat sich selbst mit einem Code ungleich null beendet, entweder durch einen Absturz oder einen Einrichtungsfehler nach dem Start. Erhöhtsessions_failed_total.interrupted: Der Runner hat den Kindprozess aus einem betrieblichen Grund beendet, der weder ein Erfolg der Sitzung noch ein Fehler des Runners ist, etwa ein Drain oder das Beenden einer Sitzung, die sich noch auf dem Runner befand, als das KulanzfensterSELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MSnach ihrem Limit--kill-session-after-minendete. Ein rollierender Kubernetes-Neustart, derSIGTERMsendet, ist ein Beispiel für einen Drain. Erhöhtsessions_interrupted_total.
--kill-session-after-min erreichte, und zählte sie in sessions_interrupted_total.
Die Variable CLAUDE_RUNNER_EXIT_REASON des post-session-Hooks klassifiziert saubere Übergaben anders. Der Hook meldet diese als interrupted, weil der Runner den Kindprozess gestoppt hat: eine Freigabe, einen Start-Timeout, eine serverseitige Aufhebung der Zuweisung sowie ein Archivieren oder Löschen, das der Poll zuerst bemerkt hat. Diese Zähler erfassen dieselben Ereignisse als completed, weil der Slot sauber zurückgegeben wurde.
Wenn Sie Hook-Empfangsbestätigungen direkt mit sessions_completed_total abgleichen, zählen Sie zu wenige abgeschlossene Sitzungen. Verwenden Sie den Hook für Garantien pro Sitzung und die Zähler für aggregierte Raten.
In einer One-Shot-Umgebung, also --capacity 1 mit dem Standardwert --drain-grace-sec 0, wird jeder Runner-Prozess kurz nach dem Ende seiner einen Sitzung beendet. sessions_completed_total, sessions_failed_total und sessions_interrupted_total werden erst am Sitzungsende erhöht, unmittelbar vor diesem Beenden; ein Prometheus-Scrape alle 15 bis 60 Sekunden erfasst die Erhöhung daher selten, bevor die Serie des Runners verschwindet. Diese drei Zähler für das Sitzungsende sind die Endzähler, auf die sich der Rest dieses Abschnitts bezieht. sessions_started_total wird beim Start erhöht und bleibt während der gesamten Lebensdauer der Sitzung sichtbar, sodass er zuverlässig erscheint; in einer One-Shot-Umgebung entspricht er jedoch eher „aktuell laufenden Sitzungen“ als einer kumulierten Zählung.
Verwenden Sie für das jeweilige Ziel die Serien in dieser Tabelle statt der Endzähler:
Die
orchestrator_*-Zeilen gibt es nur in Umgebungen, in denen der On-Demand-Orchestrator läuft. Verwenden Sie bei einer festen Flotte, deren Runner ihre Sitzungen mit einem --drain-grace-sec-Wert über 0 überdauern, sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m])) für den Durchsatz; bei einer One-Shot-Flotte hat diese Serie dasselbe Problem mit dem Scrape-Fenster wie die Endzähler, verlassen Sie sich daher stattdessen auf die Anzahl der wartenden Sitzungen. Prüfen Sie den Rückstau im Tab Activity der Umgebung auf der Admin-Seite Cloud environments: Die Runner exportieren keine Serie für die Warteschlangentiefe.
Verwenden Sie für die Berichterstattung über Ergebnisse pro Sitzung stattdessen den post-session-Hook: Er wird bei jedem Sitzungsende ausgelöst, bei dem ein Kindprozess gestartet wurde, abgesehen von einem abrupten Beenden des Runners wie einer VM-Preemption, gemäß dem eigenen Vertrag des Hooks.
Nächste Schritte
- Selbstgehostete Umgebungen: die Umgebung, den Runner und das Session-Modell; der Schnellstart und In die Produktion bereitstellen enthalten Einrichtung und Betrieb
- Passen Sie Sitzungen an: Wrapper-Skripte, Lifecycle-Hooks und On-Demand-Runner
- Überprüfen Sie die Session-Identität: das Session-Token, seine Ansprüche und wie man es überprüft