Dieser Artikel basiert auf meinem Vortrag bei der Rack&Stack Nürnberg im April 2026. Den hier beschriebenen Kubernetes Blueprint gibt es als Open-Source-Projekt auf GitHub.
Die Prämisse: Langweilig ist gut
Bevor wir in die Technik einsteigen, ein Wort zur Philosophie. Monzo, die britische Neobank, hat vor einigen Jahren stolz ihre Microservices-Architektur präsentiert - inklusive eines Netzwerkdiagramms mit 1.500 Services:
Die Farben zeigten die verantwortlichen Teams. Der Aufschrei war groß: Wie kann man so Software betreiben und dabei noch ruhig schlafen?
Das Problem bei solchen Architekturen: Die Komplexität liegt nicht in den einzelnen Komponenten, sondern in den Lücken dazwischen - in der Netzwerkkommunikation, in der Orchestrierung, in den Abhängigkeiten. Und genau das ist meistens noch viel schwieriger zu debuggen als größere einzelne Dienste.
Mein Ziel im Betrieb von Software is daher:
Langweilig ist gut. Damit wird es vorhersehbar und günstig im Betrieb.
Warum Kubernetes? Und warum selbst gehostet?
Docker-Container packen eine Anwendung mit allen Abhängigkeiten in eine wiederverwendbare Einheit. Dasselbe Image läuft in der lokalen Entwicklung, in der Testumgebung und in Produktion. Das schafft Dev-Prod-Parity und hilft, viele Fehler früh zu erkennen.
Up-Scaling vs. Down-Scaling
Wenn man nach "Container in Produktion" sucht, findet man fast ausschließlich Informationen zu Up-Scaling: Wie verteile ich meine Anwendung auf 5, 50 oder 500 Server? Das ist das Szenario, das Google, Amazon und Co. durch die Gegend treiben, weil sie es selbst brauchen.
Für uns im Mittelstand ist aber ein anderer Aspekt mindestens genauso relevant: Down-Scaling -- also eine hohe Packungsdichte auf wenigenServern. Wir betreiben auf unserem Kubernetes-Cluster mit drei physischen Servern rund 200 Container. Das sind interne Anwendungen, Single Sign-On, Logging, Monitoring und auch diverse Produktivinstanzen unserer Kunden:
Kubernetes als Quasi-Standard
Kubernetes ist de facto der Standard für Container-Orchestrierung. Es ist Open Source, wurde initial von Google gestartet und wird heute von tausenden Contributors in vielen Teilprojekten weiterentwickelt.
Die Power von Kubernetes kommt von seiner Erweiterbarkeit: eigene Module ("Operators") oben drauf bauen, das System erweitern. Der Zoo an Modulen in der CNCF Landscape ist mittlerweile unübersichtlich.
"Für Kubernetes braucht man ein Operations-Team" -- Nope.
Diesen Mythos möchte ich entkräften. Wir sind 35 Leute, wir haben Kubernetes seit sieben Jahren im Einsatz und die aktuelle Plattform seit fünf Jahren. Niemand bei uns ist ausschließlich für Kubernetes zuständig. Etwa 4-5 Personen im Team kennen sich gut damit aus und maintainen es nebenbei.
Natürlich: Man darf und muss sich Inhouse-Expertise aufbauen. Es ist nicht kostenlos. Aber man sollte keine Angst davor haben.
Unsere Ziele und Trade-Offs
Wenn man Kubernetes im KMU-Kontext einsetzt, ist es hilfteich, manche Dinge anders zu denken als im klassischen, elastischen Cloud-Setup:
Langfristige Skalierbarkeit -- ohne extreme Elastizität. Wir wollen einen vierten oder fünften Server dazustellen können, aber nicht automatisiert um 3 Uhr nachts.
Stabilität und Updatefähigkeit. 9 von 10 Updates schaffen wir ohne jede Downtime unserer Workloads, und ohne Workload-Migration auf andere Server.
Flexibilität für viele verschiedene Workloads. Fast alle sprechen HTTP(S) in irgendeiner Form.
Komplexitätsreduktion. Es ist nicht unser Hauptjob, Kubernetes zu betreiben -- daher muss es so einfach wie möglich sein.
Geringe Wartungskosten. Durch Automatisierung und Dokumentation.
Einfache Nutzung (Self-Service). Der Rest des Teams soll nicht Kubernetes-Experte werden müssen, um eine Anwendung zu deployen.
Ein bewusster Trade-Off: Wir pinnen unsere Workloads auf bestimmte Server. Wir wissen damit, welche Anwendung auf welchem Server läuft und wo die Daten liegen. Das reduziert die Elastizität, bringt aber ein massiv einfaches Betriebsmodell.
Der Sandstorm Kubernetes Blueprint
Alles folgende ist als Open-Source-Projekt veröffentlicht:
Ihr könnt das komplett auf eigenen Servern ausprobieren, Teile herausnehmen oder als Diskussionsgrundlage nutzen.
Schritt 1: K3S als Basis
K3S ist eine Kubernetes-Distribution von Rancher (jetzt Teil von SUSE), die sich als Lösung für IoT und Edge-Computing vermarktet. Wir haben festgestellt: K3S läuft hervorragend im Datacenter. Nur weil etwas auch auf einem Raspberry Pi läuft, heißt das nicht, dass es nicht auch auf einem großen Server mit 200 GB RAM exzellent funktioniert.
Das Schöne an K3S:
Kubernetes in einer einzigen Binary. Runterladen, starten, fertig.
Update = Binary austauschen und neustarten. Einfaches Betriebsprinzip.
Updates im laufenden Betrieb ohne Downtime der Container möglich.
Die einzige echte Downtime (ca. 5 Minuten) haben wir bei Kernel-Updates, weil der Server dann wirklich neu booten muss.
K3S bringt bereits Standardmodule mit:
Traefik als Reverse Proxy (Ingress/Gateway)
Local Path Provisioner für persistente Daten - ein bestimmter Ordner auf dem Server enthält alle persistenten Daten. Einfach zu verstehen, einfach zu sichern.
Schritt 2: Server-Setup mit Ansible
Unser Basis-Setup besteht aus:
Load Balancer (idealerweise von unserem Hoster)
Internes Netzwerk
ein oder mehrere Server
Wir demonstrieren den Setup basierend auf Hetzner Cloud, aber es funktioniert genauso auf eigenem Blech, in Proxmox oder bei jedem anderen Provider.
Das interne Netzwerk hinter dem Load Balancer ist wichtig - auch bei nur einer Instanz. Ohne Load Balancer macht man DNS-basiertes Failover, und das hat bekannte Probleme mit Propagierungszeiten. Der Load Balancer gibt Flexibilität im Incident-Fall.
Die Server-Provisionierung machen wir mit Ansible. Wir installieren K3S, ein paar Admin-Tools -- und zusätzlich MariaDB und PostgreSQL direkt auf dem Server (nicht in Kubernetes). Das ist wieder unsere Philosophie: Wir wollen wissen, wo die Daten liegen.
Das Schöne an Ansible und Kubernetes: Ich definiere den Zielzustand, nicht die Schritte. Das System konvergiert immer zu diesem Zielzustand -- auch wenn zwischendurch mal etwas schiefgeht.
Nach der Ausführung ist der Cluster leer und bereit:
Schritt 3: Cilium als Netzwerkschicht
Vom K3S-Standard weichen wir bei der Netzwerkschicht ab und nutzen Cilium, welches Routing und Netzwerk auf eBPF-Basis bereitstellt. Das Hauptfeature für uns: Cilium Hubble - ein "Röntgenblick" in die Netzwerkverbindungen im Cluster.
Dies hilft für folgende Szenarien:
Visualisierung von Traffic-Flüssen im Cluster
sofort sehen, wenn eine Firewall-Regel Traffic blockt (rot markiert in der UI)
Debugging von Ost-West-Traffic zwischen Diensten
Ohne Cilium sehe ich oft nur "meine Verbindung geht nicht" - ohne zu wissen, ob es am Routing, an der Firewall oder an etwas anderem liegt. Cilium lässt sich übrigens auch im laufenden Betrieb updaten, ohne die Konnektivität im Cluster zu beeinträchtigen.
Die Hausbau-Analogie
An diesem Punkt haben wir:
Grundstück gekauft = Server bereitgestellt
Rohbau = Kubernetes (K3S) installiert
Haus steht = Cilium + Netzwerk konfiguriert
Das entspricht ungefähr dem, was man bei einem Cloud-Provider als Managed Kubernetes bekommt sofern man hier keine Elastizität benötigt (EKS, GKE, AKS) -- allerdings für einen Bruchteil der Kosten (Faktor 5-10 günstiger).
Schritt 4: Innenausbau - SSL-Zertifikate & Co.
Den "Innenausbau" muss man bei jedem Kubernetes machen, auch bei Managed-Angeboten. Dazu gehören z.B. automatische SSL-Zertifikate via cert-manager und Let's Encrypt:
Kubernetes direkt zu nutzen bedeutet, für jede Anwendung viele Einzelteile zu konfigurieren: Ingress, Zertifikate, Services, Deployments, Persistent Volumes, Datenbanken... Unsere Entwickler sollen das nicht alles wissen müssen.
Unsere Standard-Anwendungen sind Web-Anwendungen mit einem HTTP-Port, auf dem diese Traffic entgegennehmen. Mehr nicht. Also haben wir das abstrahiert: Ein eigener Kubernetes Operator namens OneContainerOnePort, der aus einer minimalen Konfiguration automatisch alles Nötige erzeugt:
Ingress
TLS-Zertifikat (via Let's Encrypt)
Deployment
Persistent Volume (wenn nötig)
Redis (wenn nötig)
Was ist ein Operator?
Kubernetes funktioniert deklarativ: Ich beschreibe meinen Zielzustand in YAML, und ein Controller (der "Operator") sorgt permanent dafür, dass dieser Zustand hergestellt wird. Wenn etwas gelöscht wird, legt der Operator es automatisch neu an. Das ist die Basis für die hohe Resilienz von Kubernetes.
Mit dem Operator SDK kann man eigene Operators bauen. Dafür gibt es drei Wege:
Der Ansible-Operator: Externe Systeme fernsteuern
Unser Database-Operator ist Ansible-basiert. Ein kurzes YAML reicht, um eine Datenbank für eine Anwendung bereitzustellen:
Er verbindet sich per Ansible zur externen Datenbank
Er legt dort die Datenbank an
Das Mächtige daran: Ich kann über Kubernetes externe Systeme steuern - Datenbanken, DNS-Provider, Cloud-Ressourcen, Keycloak-Tenants - alles, wofür es ein Ansible-Modul gibt. Und ich bekomme zentrale Sichtbarkeit: Ein kubectl get databases --all-namespaces zeigt mir alle Datenbanken im gesamten System.
Dieses Pattern ist aus meiner Sicht ein absoluter Game Changer für Kubernetes in Brownfield-Umgebungen, weil es die Integration mit der externen Welt ermöglicht. Erstaunlicherweise wird wenig darüber gesprochen.
Der Helm-Operator: Standardisierung über Projekte hinweg
Der OneContainerOnePort-Operator ist Helm-basiert. Damit kann ich z.B. Excalidraw (ein webbasiertes Diagramm-Tool) folgendermaßen deployen:
Der große Vorteil gegenüber losen Helm-Charts: Wenn wir am Operator etwas ändern und deployen, werden alle Systeme automatisch auf den neuesten Stand gebracht. Probleme fallen sofort auf - nicht erst ein halbes Jahr später, wenn ein Kunde sein Projekt wieder anfasst.
Praxisbeispiel: Neos CMS deployen
Ein etwas fortgeschritteneres Beispiel mit Datenbank, Redis und persistentem Storage:
Ein kubectl apply später läuft eine vollständige Neos-CMS-Instanz - mit SSL, Datenbank, Cache und persistentem Storage. Und wenn jemand versehentlich ein Gateway oder einen Service löscht? Der Operator stellt es automatisch wieder her. Solange niemand die OneContainerOnePort-Ressource selbst löscht, heilt sich alles von allein.
Das ist ein extrem schönes Modell, weil auch Teammitglieder mit wenig Kubernetes-Erfahrung sehr selbstständig arbeiten können, ohne Angst haben zu müssen, etwas kaputt zu machen.
Bonus: Permissions und Access Management mit Rancher
Wir betreiben nicht nur einen, sondern mehrere Kubernetes-Cluster. Innerhalb eines Clusters gibt es zwar gute Workload-Separierung, aber keine vollständige Garantie, dass eine "noisy" Workload andere nicht beeinträchtigt. Für verschiedene Abteilungen oder Vertrauenszonen können separate Cluster sinnvoll sein.
Für das zentrale Management nutzen wir den Open-Source Rancher Manager:
Zentraler Einstiegspunkt für alle Cluster
SSO-Anbindung via OpenID Connect (Keycloak, Entra ID, ...)
Zentrale Permissions und Audit-Logging -- wer darf was, und wer hat was gemacht?
Projekt-Konzept: Gruppen von Namespaces, auf die ich Rechte vergeben kann
Download der lokalen kubectl-Konfiguration über die Web-UI
Zusammenfassung
K3S als leichtgewichtige, stabile Kubernetes-Distribution -- auch im Datacenter hervorragend
Cilium für Netzwerk-Transparenz und Debugging
Eigene Operators (Ansible- und Helm-basiert) für eine interne Platform as a Service
Bewusste Trade-Offs: Weniger Elastizität, mehr Stabilität und Einfachheit
Der wichtigste Punkt: Kubernetes muss nicht kompliziert sein und es muss nicht immer elastisch sein. Für viele KMU-Workloads ist das "langweilige" Setup - vorhersehbar, günstig, stabil - genau das Richtige. Und wenn man später doch Elastizität braucht, kann man sie gezielt hinzufügen.
FAQs
"Wenn ich Daten auf eine Node pinne, mache ich den Kubernetes-Vorteil kaputt?" Das ist (für uns) ein gezielter Trade-Off zugunsten von Komplexitätsreduktion. Wir haben Backups und können manuell eine neue Instanz auf einem anderen Host erzeugen. Für unsere Workloads brauchen wir diese Elastizität fast nie.
"Warum K3S und nicht Talos oder RKE2?" Historisch gewachsen - als wir starteten, gab es RKE2 noch nicht und Talos auch nicht. Außerdem kennen wir Ubuntu-Server sehr gut, und das ermöglicht uns, Datenbanken co-located neben Kubernetes zu betreiben. Heute würde ich Talos durchaus in Betracht ziehen.
"Warum eigene Operators und nicht Kustomize mit Argo oder Flux?" Argo/Flux arbeiten Push-basiert (Git als Source of Truth wird in den Cluster gepusht). Wir arbeiten Pull-basiert: Unsere Projekte haben ein minimales YAML, das per kubectl apply in den Cluster geschoben wird. Der Operator im Cluster sorgt dann für den Zielzustand. Beides führt zum Ziel - wir bevorzugen aktuell den deklarativen, Pull-basierten Ansatz.
"Was ist mit Black Friday und horizontaler Skalierung?" Für große Konzerne unterstützen wir bei Planung und Betrieb von großen, elastischen Kubernetes-Cluster. Aber: Der Default sollte "nicht elastisch" sein. Elastizität bringt Dynamik und Komplexität, die man nicht will, wenn man stabilen Betrieb höher wichtet. Lieber mit dem einfachen Setup starten und bei Bedarf Elastizität gezielt dazuschalten.
Dieser Artikel basiert auf dem Vortrag "Self Hosted Kubernetes ohne DevOps Team" bei der Rack&Stack Nürnberg am 22. April 2026.