Management — Überblick
managementRoutes(...) baut einen Route-Baum betrieblicher
Endpunkte. Du bindest ihn auf einem eigenen Port (8558 per
Konvention), getrennt vom Haupt-HTTP-Server deiner App, und
exponierst:
- Health-Probes — Liveness + Readiness für K8s.
- Cluster-Info — Mitglieder, Leader, Sharding-Regionen.
- Metriken — Prometheus-Exposition (optional).
- Admin-Endpunkte — Leave / Down (optional, standardmäßig aus).
import { managementRoutes } from 'actor-ts';
// Build the routes (cluster is optional — pass null to skip /cluster/*),// then bind them on a dedicated port.const { routes, health } = managementRoutes(system, cluster, { enableMetricsEndpoint: true,});
const binding = await system.http(8558, { host: '0.0.0.0' }).bind(routes);// management endpoints now serve on http://0.0.0.0:8558managementRoutes gibt { routes, health } zurück: routes ist
der Route-Baum, den du bindest, und health
ist die
HealthCheckRegistry,
auf der du Liveness- / Readiness-Checks registrierst.
Konfiguration
Abschnitt betitelt „Konfiguration“Das dritte Argument ist ManagementRoutesOptions —
Endpunkt-Schalter und optionale Middleware. Port und Host sind
keine Settings: sie gehen an system.http(port, { host }), und
der cluster ist das zweite positionale Argument.
type ManagementRoutesOptionsType = { enableLeaveEndpoint?: boolean; // POST /cluster/leave (default false) enableDownEndpoint?: boolean; // POST /cluster/down (default false) enableMetricsEndpoint?: boolean; // GET /metrics (default false) auth?: Middleware; // guards /cluster/* (+ /metrics) ipAllowlist?: Middleware; // guards EVERY endpoint, incl. /health + /ready authProtectHealth?: boolean; // also require `auth` on /health + /ready (default false)};Eine typische Produktions-Verdrahtung:
const { routes, health } = managementRoutes(system, cluster, { enableMetricsEndpoint: true, // for Prometheus enableLeaveEndpoint: false, // admin-only; gate behind auth enableDownEndpoint: false,});await system.http(8558).bind(routes);Die Endpunkte
Abschnitt betitelt „Die Endpunkte“| Endpunkt | Immer an? | Zweck |
|---|---|---|
GET /health | ✓ | Liveness — 200 wenn jeder Liveness-Check besteht. |
GET /ready | ✓ | Readiness — 200 wenn Cluster up + jeder Readiness-Check besteht. |
GET /cluster/members | Wenn cluster gesetzt | Membership-JSON. |
GET /cluster/leader | Wenn cluster gesetzt | Leader-Adresse. |
GET /cluster/shards?type=<name> | Wenn cluster gesetzt | Shard-Verteilung für einen sharded Typ. |
POST /cluster/leave | Opt-in (enableLeaveEndpoint) | Graceful Cluster-Leave auslösen. |
POST /cluster/down | Opt-in (enableDownEndpoint) | Peer per Adresse force-downen. |
GET /metrics | Opt-in (enableMetricsEndpoint) | Prometheus-Textformat. |
Siehe HTTP-Endpunkte für die volle Oberfläche + Response-Shapes.
Health Checks
Abschnitt betitelt „Health Checks“const { routes, health } = managementRoutes(system, cluster);
// Readiness — gates traffic; return { name, status, detail? }.health.addReadiness(async () => { const ok = await db.ping(); return { name: 'database', status: ok, detail: ok ? undefined : 'db unreachable' };});
await system.http(8558).bind(routes);Checks hängen sich in /health (Liveness) und /ready
(Readiness). Ein fehlschlagender Check lässt diesen Endpunkt 503
zurückgeben. Siehe
Health Checks.
K8s-Integration
Abschnitt betitelt „K8s-Integration“# In deinem Pod-Spec:readinessProbe: httpGet: path: /ready port: 8558 initialDelaySeconds: 5 periodSeconds: 5
livenessProbe: httpGet: path: /health port: 8558 initialDelaySeconds: 30 periodSeconds: 10K8s pollt diese Endpunkte, um zu entscheiden, ob der Pod Traffic bekommen soll (ready) oder neu gestartet werden soll (live). Siehe Kubernetes-Deployment für das vollständige Deployment-Rezept.
Warum ein separater Port
Abschnitt betitelt „Warum ein separater Port“App-Port (8080): öffentlich, hinter einem Load BalancerManagement (8558): nur intern, intern firewall'dDie Management-Endpunkte legen internen Zustand offen — Cluster-Mitgliederadressen, Metrikwerte usw. Sie öffentlich zu exponieren ist ein Sicherheitsrisiko. Binde sie auf einem separaten Port und firewall ihn intern.
In K8s ist das per-Pod — Probes treffen :8558 vom Kubelet
(gleicher Node), aber kein Service exponiert es extern.
Hinter einem Auth-Proxy
Abschnitt betitelt „Hinter einem Auth-Proxy“Für mehr Zugriffskontrolle:
# In deinem Service-/Ingress-Config:# - 8080 → öffentlich# - 8558 → nicht öffentlich exponiert; mTLS internManche Produktivsysteme exponieren Management hinter einem
Side-Car-Proxy, der Auth handhabt (Envoy + JWT, Linkerd + mTLS).
Alternativ hängst du die eingebaute auth- / ipAllowlist-
Middleware über die Settings an (siehe
HTTP-Endpunkte).
In einen bestehenden Server mounten
Abschnitt betitelt „In einen bestehenden Server mounten“managementRoutes gibt schlichte Routen zurück, du brauchst also
gar keinen eigenen Port — concat sie in die bestehenden
HTTP-Routen deiner App:
import { managementRoutes, concat } from 'actor-ts';
const { routes: mgmt } = managementRoutes(system, cluster);await system.http(8080).bind(concat(appRoutes, mgmt));Zwei Gründe, das statt eines separaten Ports zu tun:
- Du hast schon einen HTTP-Server und möchtest Management inline.
- Single-Node-App ohne Cluster — Health-Checks allein
rechtfertigen den Extra-Port vielleicht nicht; verdrahte
/healthin deinen bestehenden Server.
(Management auf dem öffentlichen Port zu mounten exponiert
internen Zustand erneut — gate es mit den auth- /
ipAllowlist-Settings, wenn du das tust.)
Wo es weitergeht
Abschnitt betitelt „Wo es weitergeht“- Health Checks —
Custom-Checks durch
/healthund/readydurchgereicht. - HTTP-Endpunkte — die volle Endpunkt-Referenz.
- Kubernetes-Deployment — das K8s-Rezept, das diese Probes nutzt.
- Prometheus-Exporter — der Metrik-Endpunkt, den dies exponiert.
