Derzeit im Test: Der GitHub-Code wird nach Abschluss veröffentlicht.

Ticketing-Server-Bereitstellung

Umgebung
Shell
Modus
bash
Beispiel für Client-Verbindung
rust
Schnelltest mit nc
bash

Umgebungsvariablen

Die Serverkonfiguration erfolgt ausschließlich über Umgebungsvariablen. Schlüssel sind groß-/kleinschreibungsunabhängig, ein leerer Wert gilt als nicht gesetzt, und Flag-artige Werte sind nur bei 1/true/yes/on wahr. Das Docker-Image basiert auf scratch, daher wird die Konfiguration rein über Umgebungsvariablen ohne Konfigurationsdatei injiziert.

UmgebungsvariableStandardBeschreibung
PORT5225Lauschport im Single-Modus. Wird im Cluster-Modus ignoriert, wo stattdessen der Port aus CLUSTER_SELF verwendet wird
SOCKET_BIND0.0.0.0Lauschadresse
CLIENT_TOKENS(keine)Kommagetrennte Liste der Client-Auth-Tokens. Falls nicht gesetzt, ist ein leeres Token erlaubt
CLUSTER_SELF(keine)Die beworbene Adresse dieses Knotens, host:port. Ihre Anwesenheit aktiviert den Cluster-Modus
CLUSTER_PEERS(keine)Kommagetrennte Liste der beworbenen Adressen aller Knoten. Genau 3 oder 5, dieselbe Reihenfolge auf jedem Knoten, muss self enthalten
CLUSTER_TOKENS(keine)Kommagetrennte Liste der Peer-zu-Peer-Auth-Tokens
TLS_CERT / TLS_KEY(keine)Pfade zu den Zertifikat-/Privatschlüssel-PEM-Dateien — setze beide gemeinsam, um TLS zu aktivieren
TLS_CA(keine)CA zur Verifikation von Peer-Zertifikaten — fällt auf den System-Vertrauensspeicher zurück, falls nicht gesetzt
TLS_SKIP_VERIFYfalseVerifikation des Peer-Zertifikats überspringen — nur für Tests
DOCKERfalseFixiert die internen Lauschports im Cluster-Modus auf 5225/6225 — im offiziellen Image standardmäßig gesetzt
DEBUGBuild-abhängig1/true aktiviert Debug-Logging

Die vollständigen Regeln (Portableitung, beworbene Adressen, Token-Rotation ohne Ausfallzeit usw.) findest du unter Konfiguration (Umgebungsvariablen).

Single vs. Cluster

  • Single (1 Knoten): Ohne CLUSTER_* läuft der Knoten eigenständig. Am schnellsten, aber es gibt einen kurzen Ausfall beim Neustart, und der Zustand ist In-Memory, geht also beim Neustart verloren (lease ist das Sicherheitsnetz).
  • Cluster (unterbrechungsfrei): 3 oder 5 Knoten. Die Knoten teilen sich einen einzigen Sperrenzustand per Raft-Konsens — nur der Leader bearbeitet Anfragen, und jede Zustandsänderung wird erst finalisiert, nachdem eine Mehrheit committet hat. Stirbt der Leader, wird innerhalb von 0,5–1 Sekunde ein neuer gewählt, und solange eine Mehrheit am Leben bleibt, laufen Sperrenzustand und Dienst weiter. Die vollständige Erklärung findest du unter Funktionsweise und Protokoll (Cluster).
  • Jeder Cluster-Knoten lauscht auf dem Client-Port plus einem Raft-Port (Client-Port + 1000) — öffne beide Ports in deiner Firewall.

Kubernetes-Cluster-Bereitstellungen verwenden ein StatefulSet + headless Service. Gib jedem Pod einen stabilen DNS-Namen (ticketing-0.ticketing…, ticketing-1.ticketing…), trage diese Namen in CLUSTER_PEERS ein, und injiziere CLUSTER_SELF für jeden Pod automatisch über die Downward API (metadata.name).

Unterbrechungsfreier Neustart (Rolling)

Es gibt eine zentrale Regel — eine Mehrheit muss immer am Leben bleiben (bei 3 Knoten höchstens 1 gleichzeitig herunterfahren).

  1. Starte zuerst Follower neu, einen nach dem anderen. Sobald ein neu gestarteter Knoten per Replikation oder Snapshot aufgeholt hat, geh zum nächsten über.
  2. Fahre zuletzt den Leader herunter — innerhalb von 0,5–1 Sekunde wird ein neuer gewählt, und Clients wechseln transparent um.
  3. Wird ein heruntergefahrener Knoten wieder hochgefahren, tritt er als Follower bei.

Die detaillierten Schritte findest du unter Unterbrechungsfreies Neustartverfahren (Rolling Restart).

Referenz