Infrastruktur
Ein Kubernetes-Cluster für 270 Geräte: Was wirklich drinsteckt
Talos statt normalem Linux, GitOps statt Handbetrieb, Netzwerkregeln statt offenem Vertrauen: die Architektur-Entscheidungen hinter einem Cluster, den wir für einen Kunden mit rund 270 verteilten Geräten betreiben - und warum.
Für einen Kunden mit rund 270 verteilten Geräten im Feld betreiben wir ein Kubernetes-Cluster, das die Daten dieser Geräte einsammelt, verarbeitet und ausliefert. Kein Prestige-Projekt, kein Buzzword-Bingo - jede Entscheidung in diesem Cluster lässt sich auf eine konkrete Frage zurückführen: Was passiert, wenn genau diese eine Komponente ausfällt oder kompromittiert wird? Hier ist die Architektur, so nüchtern wie möglich erklärt.
Der Kunde bleibt anonym, aus Diskretion und weil es für die Architektur ohnehin nicht wichtig ist. Wichtig ist die Größenordnung: Ein System mit hunderten verteilten Endpunkten verzeiht keine Handarbeit mehr. Jede manuelle Änderung, die einmal vergessen wird, jede Konfiguration, die nur im Kopf einer Person existiert, wird bei dieser Größe irgendwann zum Vorfall. Also war die erste Entscheidung keine technische, sondern eine methodische: nichts, was im Betrieb wichtig ist, darf nur an einer Stelle stehen.
Warum Talos als Betriebssystem
Die Server im Cluster laufen nicht auf einem normalen Linux mit SSH-Zugang, sondern auf Talos - einem Betriebssystem, das ausschließlich dafür gebaut ist, Kubernetes zu betreiben. Es hat keine Shell, keinen Paketmanager, keinen interaktiven Login. Konfiguriert wird es deklarativ, über eine API, nicht per Hand auf der Konsole.
Das klingt zunächst nach einer Einschränkung, ist aber die Pointe: Ein Angreifer, der es auf den Host selbst abgesehen hat, findet dort schlicht keine Werkzeuge vor. Kein bash, kein apt install, kein Ort, an dem sich still ein zusätzlicher Prozess einnisten könnte. Und weil niemand - auch wir nicht - sich im Alltag per SSH einloggt und "mal eben" etwas ändert, gibt es auch keine Konfigurationsdrift zwischen den Knoten. Jeder Knoten ist exakt das, was seine deklarierte Konfiguration sagt. Nichts mehr, nichts weniger.
Warum GitOps statt Handbetrieb
Was im Cluster läuft, steht als Beschreibung in Git - nicht als Wissen in einem Kopf. Bei diesem Kunden läuft das über ArgoCD, das kontinuierlich gegen ein Repository in unserer eigenen Gitea-Instanz abgleicht. Weicht der tatsächliche Zustand des Clusters vom Stand in Git ab - weil jemand von Hand etwas geändert hat, oder weil etwas ausgefallen ist -, gleicht ArgoCD automatisch wieder an.
Der praktische Nutzen zeigt sich am deutlichsten im Fehlerfall: Wenn ein Deployment nicht das tut, was es soll, ist der Rollback kein Notfall-Kommando mitten in der Nacht, sondern ein Klick zurück auf den vorherigen Commit. Der alte Zustand ist exakt reproduzierbar, weil er exakt dokumentiert war. Wer wann was geändert hat, steht im Git-Log - nicht im Gedächtnis der Person, die es getan hat.
Wer mit wem reden darf: Netzwerkregeln statt offenem Vertrauen
In einem unkonfigurierten Kubernetes-Cluster kann jeder Dienst mit jedem anderen reden. Das ist praktisch zum Ausprobieren und gefährlich im Betrieb: Wird ein einzelner Dienst kompromittiert, ist er der Startpunkt für einen Weg zu allen anderen. Über Cilium und seine NetworkPolicies gilt bei diesem Kunden das Gegenteil - Grundhaltung: erst mal darf niemand mit niemandem reden. Jede erlaubte Verbindung ist eine bewusste Ausnahme, keine Grundeinstellung.
Ein Web-Dienst erreicht also nur die Datenbank, die er tatsächlich braucht, und sonst nichts. Ein internes Auswertungs-Modul erreicht nicht das Internet, wenn es das nicht muss. Das begrenzt im Ernstfall nicht nur, was ein Angreifer sieht, sondern vor allem, wohin er von einem einzelnen kompromittierten Dienst aus überhaupt weiterkommt.
Geprüft vor dem Start, beobachtet während des Laufs
Zwei Kontrollen liegen vor und während der eigentlichen Ausführung. Vor dem Ausrollen scannt Trivy jedes Container-Image auf bekannte Schwachstellen - ein Image mit kritischen, bekannten Lücken kommt gar nicht erst in den Cluster. Das ist die Prüfung am Werkstor, nicht die Hoffnung, dass schon nichts passiert.
Während der Laufzeit übernimmt Falco die Beobachtung: eine Laufzeit-Erkennung, die verdächtiges Verhalten meldet, während es passiert - zum Beispiel eine Shell, die plötzlich aus einem Web-Prozess heraus gestartet wird. Genau dieses Muster ist der Klassiker eines erfolgreichen Angriffs: Eine Lücke wird ausgenutzt, ein Prozess versucht, Befehle auszuführen, für die er nie gedacht war. Falco sieht das im Moment des Geschehens, nicht erst beim Blick ins Log am nächsten Tag.
Geheimnisse getrennt vom Code
Passwörter, API-Schlüssel und Zertifikate liegen nicht im Code und nicht im Container-Image, sondern in einem eigenen Tresor (Vault) und werden erst zur Laufzeit in den jeweiligen Dienst eingespielt. Ein Image, das irgendwo landet, wo es nicht hingehört, enthält damit keine Zugangsdaten, die man daraus extrahieren könnte. Und ein Geheimnis lässt sich zentral rotieren, ohne dass dafür jedes einzelne Deployment neu gebaut werden muss.
Was das für 270 Geräte konkret bedeutet
Keine dieser Entscheidungen ist für sich genommen exotisch - Talos, GitOps, NetworkPolicies, Image-Scanning, Runtime-Detection und ein zentraler Secrets-Tresor sind alles etablierte Bausteine im Kubernetes-Ökosystem. Der Punkt ist, dass sie hier nicht einzeln, sondern als zusammenhängendes System gedacht sind, gemessen an einer einfachen Frage: Was, wenn eine einzelne Komponente ausfällt oder kompromittiert wird - hält der Rest?
Bei 270 verteilten Geräten, die kontinuierlich Daten an dieses Cluster senden, ist die Alternative zu dieser Sorgfalt kein kleineres Risiko, sondern ein größeres, das nur später sichtbar wird. Genau deshalb ist das hier keine akademische Übung, sondern die Architektur, mit der wir seit geraumer Zeit für diesen Kunden im Alltag arbeiten - inklusive der Härtungs-Baseline, die für jeden Container gilt, den wir betreiben, wie an anderer Stelle beschrieben.
Wie diese Bausteine bei uns im laufenden Betrieb ineinandergreifen, steht unter koetting.io/de/betrieb/haertung.
Wie diese Architektur bei uns im laufenden Betrieb aussieht: Härtung im Betrieb