Zum Inhalt springen
Deutsch

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:8558

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

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);
EndpunktImmer an?Zweck
GET /healthLiveness — 200 wenn jeder Liveness-Check besteht.
GET /readyReadiness — 200 wenn Cluster up + jeder Readiness-Check besteht.
GET /cluster/membersWenn cluster gesetztMembership-JSON.
GET /cluster/leaderWenn cluster gesetztLeader-Adresse.
GET /cluster/shards?type=<name>Wenn cluster gesetztShard-Verteilung für einen sharded Typ.
POST /cluster/leaveOpt-in (enableLeaveEndpoint)Graceful Cluster-Leave auslösen.
POST /cluster/downOpt-in (enableDownEndpoint)Peer per Adresse force-downen.
GET /metricsOpt-in (enableMetricsEndpoint)Prometheus-Textformat.

Siehe HTTP-Endpunkte für die volle Oberfläche + Response-Shapes.

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.

# In deinem Pod-Spec:
readinessProbe:
httpGet:
path: /ready
port: 8558
initialDelaySeconds: 5
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 8558
initialDelaySeconds: 30
periodSeconds: 10

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

App-Port (8080): öffentlich, hinter einem Load Balancer
Management (8558): nur intern, intern firewall'd

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

Für mehr Zugriffskontrolle:

# In deinem Service-/Ingress-Config:
# - 8080 → öffentlich
# - 8558 → nicht öffentlich exponiert; mTLS intern

Manche 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).

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:

  1. Du hast schon einen HTTP-Server und möchtest Management inline.
  2. Single-Node-App ohne Cluster — Health-Checks allein rechtfertigen den Extra-Port vielleicht nicht; verdrahte /health in 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.)