Aufbau eines RKE2-Clusters

·

Seit 2023 betreibe ich eine eigene RKE2-basierte Kubernetes-Plattform. Das Projekt läuft als privates Vorhaben mit niedriger Priorität, knappen Zeitfenstern und begrenztem Hardwarebudget. Trotz dieser einschränkenden Herausforderungen war das Ziel, einen möglichst professionellen Cluster aufzubauen und zu administrieren.

Der Cluster besteht aus drei virtuellen RKE2-Server-Nodes mit Control Plane und etcd, läuft auf Debian-basierten VMs unter KVM/libvirt und trägt zentrale Plattformdienste wie GitLab EE, GitLab Runner, Registry, Pages, KAS, Longhorn, MetalLB, cert-manager, MinIO, pgbouncer, Prometheus, Alertmanager, OpenProject sowie Elasticsearch/Kibana.

Der Wert des Projekts liegt im Zusammenspiel dieser Bausteine. Es gibt eine Terraform-Schicht, eine Kubernetes-Schicht, eine Anwendungsschicht, eine Delivery-Schicht und eine Host-/Service-Automatisierung rund um den Cluster. Diese Schichten sind bewusst getrennt und über Git-Repositories nachvollziehbar gemacht.

Architekturprinzipien

Die Plattform folgt fünf einfachen Prinzipien.

Erstens: Standardnahe Komponenten. RKE2, Helm, Helmfile, Longhorn, MetalLB, cert-manager, Prometheus und GitLab sind weit verbreitete Werkzeuge mit gut verständlichen Betriebsmodellen. Das macht Entscheidungen überprüfbar und Wissen übertragbar.

Zweitens: Klare Zuständigkeiten pro Schicht. Terraform beschreibt virtuelle Maschinen und Infrastrukturidentitäten. Ansible stellt mit RKE2 die Kubernetes-Basis. Helmfile beschreibt den Anwendungszustand. GitLab übernimmt Code, CI/CD, Registry, Runner, Pages und Agent-Integration.

Drittens: Repräsentative Workloads. GitLab ist der zentrale Anker-Workload, weil es gleichzeitig Webanwendung, CI/CD-System, Registry, SSH-Service, Pages-Host, Kubernetes-Integrationspunkt und zustandsbehaftete Plattformsoftware ist. Ein Cluster, der GitLab sauber trägt, muss Netzwerk, TLS, Storage, Object Storage, Datenbankverbindungen, Redis, Runner und Upgrades beherrschen.

Viertens: Prüfbarkeit über Git. Chart-Versionen, Values, Infrastrukturdefinitionen, CI-Logik und Automatisierung liegen in Repositories. Änderungen entstehen als Diffs und können mit bekannten Werkzeugen validiert, reviewed und nachvollzogen werden.

Fünftens: Betriebssicherheit als Designziel. Bei knappen Zeitfenstern priorisiert die Plattform stabile Wiederholbarkeit, klare Recovery-Pfade und reduziert damit unangenehme Überraschungen.

RKE2 als Kubernetes-Basis

RKE2 ist die passende Kubernetes-Distribution für dieses Setup, weil sie eine gehärtete, produktionsorientierte Basis mit einem überschaubaren Betriebsmodell kombiniert. Sie bringt ein klares Server-/Agent-Konzept, embedded etcd, containerd und standardnahe Kubernetes-APIs mit. Genau diese Eigenschaften passen zu einem selbst betriebenen Cluster, der professionelles Verhalten zeigen soll und trotzdem auf kleiner Infrastruktur lauffähig bleibt.

Die drei Server-Nodes übernehmen Control Plane und etcd. Diese Struktur ergibt ein sinnvolles Quorum, unterstützt Wartungsfenster auf Node-Ebene und hält die Architektur klein genug für die vorhandenen Ressourcen. Die Entscheidung für drei virtuelle im Gegensatz zu bare-metal Server-Nodes ist ein bewusster Kompromiss an die zur Verfügung stehende Hardware und zugleich architektonisch sauber: Die Plattform bildet Hochverfügbarkeit innerhalb der verfügbaren Virtualisierungsschicht ab, hält Rollen und Verantwortlichkeiten klar und erlaubt realistische Tests für Neustarts, Upgrades und Node-bezogene Wartung.

Terraform und die VM-Schicht

Die RKE2-Nodes werden als virtuelle Maschinen auf KVM/libvirt betrieben. Terraform beschreibt diese Ebene, weil VMs, Netzprofile, Storage-Profile, Hostnamen, SSH-Zugriff und cloud-init vor dem Kubernetes-Cluster existieren und einen eigenen Lifecycle besitzen.

Im Infrastruktur-Repository sind die RKE2-Server als wiedererkennbare Rollen modelliert. Sie verwenden cloud-init-Profile, dedizierte Netzwerkprofile, headless Platform-Profile und ein 150-GB-Root-Storage-Profil. Diese Größe passt zur Rolle eines Kubernetes-Nodes: Container Runtime, Images, Logs, lokale Zustände und Recovery-Arbeit benötigen Reserven.

NetBox ergänzt diese Schicht als Source of Truth für Infrastrukturidentitäten. IP-Adressen, MAC-Adressen, DNS-Namen und VM-Zuordnungen werden dadurch als Datenmodell behandelt. Die Pipeline im Infrastruktur-Repository exportiert und validiert NetBox-Daten, bevor Terraform- und Ansible-Schritte sie verwenden. Das verbindet klassisches Infrastrukturmanagement mit Git-basierten Arbeitsabläufen.

Bootstrap und frühe Helm-Phase

Der Cluster wurde zunächst direkt aufgebaut. Terraform stellte die VMs bereit, RKE2 wurde auf den Nodes in einer kontrollierten Anfangsphase eingerichtet. Diese Phase war wichtig, um die operativen Details sichtbar zu machen: Initialisierung des ersten Servers, Beitritt weiterer Server-Nodes, etcd-Verhalten, kubeconfig, Zertifikate, Neustartverhalten und grundlegende Fehlerbilder.

Die ersten Anwendungen wurden ebenfalls direkt mit Helm installiert. Das war der passende Einstieg, weil Helm-Charts ihre betrieblichen Verträge sehr konkret zeigen: PVCs, Secrets, Ingresses, Services, Ressourcengrenzen, Upgrade-Pfade und Abhängigkeiten zu Datenbanken oder Object Storage.

Zu den frühen und später ausgebauten Komponenten gehören:

  • cert-manager für Zertifikate und ClusterIssuer
  • Longhorn als persistenter Storage
  • MetalLB für LoadBalancer-Adressen im LAN
  • der RKE2 nginx ingress controller als zentraler HTTP(S)-Einstieg
  • GitLab mit Webservice, Sidekiq, Gitaly, Shell, Registry, Pages, Runner und KAS
  • MinIO als S3-kompatibler Object Storage
  • pgbouncer vor PostgreSQL-gestützten Anwendungen
  • OpenProject
  • Prometheus, Alertmanager, kube-state-metrics und node-exporter
  • Elasticsearch und Kibana

Diese direkte Arbeit mit Helm hat die späteren Values-Dateien geprägt. Viele Entscheidungen in Helmfile sind dadurch aus realem Chart-Verhalten entstanden: Welche Komponente braucht persistente Daten? Welche Services brauchen feste Ports? Welche Ingresses und Zertifikate gehören zusammen? Welche Ressourcenlimits passen zum verfügbaren Cluster?

Helmfile als beschriebener Anwendungszustand

Mit zunehmender Zahl an Komponenten wurde Helmfile zur zentralen Beschreibung des Clusterzustands. Das Cluster-Management-Repository enthält ein Root-helmfile.yaml, das die Anwendungen einbindet. Darunter liegen pro Anwendung eigene Helmfiles, Values und bei Bedarf kleine lokale Charts.

Der Root-Helmfile setzt atomic: true und wait: true. Diese Defaults passen zum Betriebsmodell: Deployments sollen wartbar, prüfbar und mit klarer Rückmeldung ablaufen. Releases werden als zusammenhängender Zustand betrachtet, und der Apply-Pfad soll Fehler sichtbar machen.

Die Anwendungsschicht umfasst aktuell unter anderem:

  • cert-manager
  • cert-manager-csi-driver
  • cert-manager-webhook-he
  • minio
  • pgbouncer
  • gitlab
  • gitlab-kubernetes-agent
  • longhorn
  • metallb
  • rke2-ingress-nginx-config
  • elasticsearch
  • openproject
  • prometheus
  • prometheus-adapter

Die konkreten Release-Stände zeigen den operativen Charakter der Plattform: GitLab läuft über den Chart 10.0.0 mit App-Version 19.0.0, der GitLab Kubernetes Agent über 2.27.0, Longhorn über 1.11.2, MetalLB über 0.16.0 und Prometheus über den Chart 29.8.0. Solche Versionen sind Teil des Betriebszustands und gehören in Review- und Upgrade-Prozesse.

Helmfile passt zu diesem Projekt, weil es Git-zentrierten Betrieb mit lokaler Ausführbarkeit verbindet. Änderungen liegen als Diffs vor, Values sind versioniert, und Deployments laufen über einen bekannten Pfad. Für eine Plattform, die GitLab selbst als Workload betreibt, ist diese direkte Ausführbarkeit ein wichtiger Recovery-Baustein.

GitLab als Plattformanker

GitLab ist der zentrale Workload des Clusters und zugleich das Werkzeug, über das große Teile der Plattformarbeit laufen. Die Installation umfasst GitLab EE, Webservice, Sidekiq, Gitaly, Shell, Registry, toolbox, migrations, Pages, Runner, KAS und den GitLab Kubernetes Agent.

Der GitLab Shell SSH-Zugang wird über den dedizierten TCP-Port 32222 bereitgestellt. Registry, Pages, KAS und Webservice besitzen eigene Ingress- und TLS-Pfade. Runner laufen im Kubernetes Executor im gitlab-Namespace. KAS und der GitLab Agent verbinden GitLab mit dem Clusterbetrieb.

Mehrere Zuständigkeiten sind bewusst ausgelagert oder getrennt:

  • PostgreSQL wird über pgbouncer angebunden.
  • Redis läuft als eigenes kleines Chart mit Redis 7.2-alpine.
  • Object Storage liegt in MinIO.
  • Gitaly besitzt eigenen persistenten Longhorn-Storage.
  • Runner, Registry, Pages und KAS sind als eigene Plattformfunktionen sichtbar.

Diese Aufteilung macht den GitLab-Betrieb explizit. Datenbankverbindungen, Redis, Object Storage, Registry, SSH, TLS und Runner-Verhalten werden als Plattformentscheidungen behandelt. Dadurch bleibt die Installation nachvollziehbar und anpassbar.

Besonders deutlich ist das beim Object Storage. GitLab nutzt getrennte Buckets für LFS, Artifacts, Uploads, Packages, Merge-Request-Diffs, Terraform State, CI Secure Files, Dependency Proxy, Backups, Pages und Registry. Diese Trennung macht Datenklassen sichtbar und unterstützt spätere Migrationen, Quotas, Backups und gezielte Fehlersuche.

Netzwerk, Ingress und TLS

Die Netzwerkschicht ist auf klare Eintrittspunkte ausgelegt. MetalLB stellt LoadBalancer-Adressen aus dem reservierten LAN-Bereich 192.168.2.201-192.168.2.223 bereit. Der RKE2 nginx ingress controller nutzt fest 192.168.2.202, läuft mit zwei Replikas und verwendet externalTrafficPolicy: Local. Der GitLab SSH-Port 32222 wird als TCP-Mapping über den Ingress-Controller auf gitlab-shell geführt.

Damit sind Webservice, Registry, Pages, KAS und Git-over-SSH über definierte Pfade erreichbar. Die Struktur passt zu GitLab als Entwicklungsplattform: Browserzugriff, Git-Zugriff, Container-Pushes, Agent-Verbindungen und Pages-Veröffentlichungen haben jeweils eigene Protokolle und betriebliche Erwartungen.

TLS wird über cert-manager und mehrere ClusterIssuer, darunter LetsEncrypt, abgebildet, inklusive Staging- und Produktionspfaden. Im Cluster existieren saubere LetsEncrypt-Zertifikate für GitLab, KAS, Pages, Registry, Longhorn, MinIO, OpenProject, Prometheus, Alertmanager, Elasticsearch und Kibana. Zertifikatsmanagement ist dadurch Teil des Plattformzustands und folgt demselben Git-basierten Betriebsmodell wie andere Komponenten.

Storage, Datenklassen und Datenbankzugriff

Longhorn ist die Standard-Storage-Klasse des Clusters. Die Default-Replikation ist auf zwei Replikas ausgelegt und passt damit zum Drei-Node-Setup. Dieses Verhältnis gibt Redundanz für Node-Wartung und bleibt gleichzeitig realistisch in Bezug auf den Ressourcenverbrauch.

Die Plattform behandelt Datenklassen unterschiedlich. Repository-Daten, Object Storage, Datenbankzustand, temporäre Daten und Suchindizes haben verschiedene Lebenszyklen und Wiederherstellungswege. Entsprechend gibt es neben dem Default-Storage auch spezialisierte Storage-Klassen, etwa für Elasticsearch oder temporäre OpenProject-Daten.

Bei GitLab ist die Datenarchitektur besonders sichtbar:

  • Gitaly hält Repository-Daten auf persistentem Longhorn-Storage, aktuell mit einem 50-GiB-PVC.
  • MinIO übernimmt S3-kompatiblen Object Storage für GitLab-Datenklassen.
  • PostgreSQL wird über pgbouncer als externer DB-Server angebunden.
  • Redis ist als separater Dienst mit eigenem persistentem Volume definiert.
  • Backups sind als eigene Datenklasse in Object Storage vorgesehen.

pgbouncer schützt den externen PostgreSQL-Server vor unkontrolliertem Verbindungswachstum. GitLab nutzt Transaction Pooling mit begrenztem Verbindungsbudget, OpenProject nutzt Session Pooling. Die Konfiguration spiegelt die Anforderungen der jeweiligen Anwendung wider und hält Datenbankzugriffe planbar.

Observability und Betrieb

Prometheus, Alertmanager, kube-state-metrics und node-exporter geben der Plattform operative Sichtbarkeit. Prometheus läuft mit persistenter Speicherung und einer Retention von zehn Tagen. Das passt zur Größe des Systems und erlaubt die Analyse von Ressourcenverlauf, Upgrade-Folgen, Node-Verhalten und zentralen Kubernetes-Zuständen.

Elasticsearch und Kibana ergänzen die Umgebung für Suche und Analyse. Zusammen mit Prometheus ergibt sich ein praktischer Blick auf Workloads, Nodes, Zertifikate, Ingresses und zentrale Anwendungen.

Die Betriebsentscheidungen zeigen sich in kleinen Details: atomic und wait in Helmfile, feste Ingress-Pfade, getrennte Buckets, persistente Volumes, Ressourcengrenzen für GitLab-Komponenten und pgbouncer vor PostgreSQL. Diese Details reduzieren Überraschungen im laufenden Betrieb und machen Änderungen besser planbar.

Ansible und Codex-gestützte Automatisierung

Helmfile beschreibt die Kubernetes-Anwendungen. Die Umgebung um den Cluster herum besitzt eigene Aufgaben: DNS, DHCP, NetBox, FreeIPA, PostgreSQL-Hosts, Firewall- und Netzwerkvalidierung, Updates, Secrets, Reporting und operative Checks. Dafür kam Ansible hinzu.

Der Ansible-Teil entstand stark mit Unterstützung durch Codex. Der produktive Ablauf war bewusst kontrolliert:

1. Ist-Zustand auf dem Zielsystem prüfen. 2. Gewünschten Zielzustand konkret formulieren. 3. Einzelne Kommandos oder Abfragen direkt testen. 4. Funktionierende Schritte in Ansible-Tasks überführen. 5. Check-Mode, Diffs und Logs prüfen. 6. Änderungen klein halten und versionieren.

Codex war dabei besonders hilfreich, um bekannte manuelle Abläufe in konsistente Rollen, Tasks und Validierungen zu übersetzen. Die operative Prüfung blieb der entscheidende Teil: Ein Playbook zählt erst, wenn es auf dem Zielsystem den gewünschten Zustand erzeugt und wiederholbar läuft.

Ansible ergänzt damit Terraform und Helmfile. Terraform besitzt die VM-Schicht. Helmfile besitzt die Kubernetes-Anwendungsschicht. Ansible besitzt die Host- und Service-Konfiguration rund um den Cluster.

Renovate als laufender Update-Prozess

Das Prüfen auf Aktualisierungen der verwendeten Helm-Charts macht bei einem solchen Cluster durchaus Arbeit. Die lässt sich aber gewaltig reduzieren, wenn man Renovate von einem Pipeline-Schedule laufen lässt. Es prüft die Helm-Chart-Versionen im Cluster-Management-Repository und erstellt saubere Merge Requests für verfügbare Updates. Jeder Merge Request enthält die konkrete Versionsänderung, kann sauber reviewed werden und dann gezielt freigegeben werden. Nach der Freigabe übernimmt die Pipeline den Rollout über den bestehenden Helmfile-Pfad.

Der Pay-off ist im Alltag erheblich: Regelmäßige Chart-Updates werden von Such- und Vergleichsarbeit zu einem reinen Review-Prozess. Der manuelle Aufwand sinkt bei Routine-Updates fast auf null, während die Entscheidung explizit und nachvollziehbar bleibt. Für die Administration eines Clusters mit GitLab, Longhorn, MetalLB, Prometheus und weiteren Charts ist das einer der stärksten Hebel für kontinuierliche Wartbarkeit.

Geplante nächste Schritte

Die nächsten Schritte folgen demselben Muster: vorhandene Plattformfunktionen stärker operationalisieren, dokumentieren und überprüfbar machen.

Geplant sind regelmäßige Restore-Übungen für GitLab, Gitaly, MinIO, PostgreSQL und Longhorn-Volumes. Dazu gehören dokumentierte RTO-/RPO-Annahmen, klare Ablaufnotizen und wiederholbare Tests. Backup-Konfiguration ist erst dann vollständig belastbar, wenn Restore-Pfade praktisch geübt und dokumentiert sind.

Ein weiterer Schwerpunkt ist Security-Härtung. Dazu gehören NetworkPolicies, Pod Security Standards, RBAC-Review, Secret-Management, Image-Scanning, Admission Policies und CIS-orientierte Checks. Die Plattform nutzt bereits eine gehärtete Kubernetes-Basis; die nächste Ausbaustufe bringt diese Haltung stärker in Workloads, Namespaces und Pipelines.

Auch Observability soll konkreter werden. Prometheus und Alertmanager bilden die Grundlage, als nächstes folgen bessere Alerts, Runbooks und klare Failure-Szenarien. Ziel ist ein Betriebsmodell, bei dem ein Alarm direkt zu einer sinnvollen Diagnose- und Handlungsroutine führt.

Für Upgrades ist als nächste Ausbaustufe ein stärker dokumentierter Betriebsrahmen geplant: konsequente Helmfile-Diffs, Test-Upgrades, dokumentierte Rollback-Pfade und ein klarer Rhythmus für Plattformwartung. Gerade GitLab, Longhorn, RKE2 und Prometheus profitieren von einem wiederholbaren Upgrade-Prozess.

Zusätzlich soll der Bootstrap-/Recovery-Pfad weiter dokumentiert werden. GitLab ist Workload und Werkzeug zugleich; deshalb ist ein klarer lokaler Pfad für Helmfile, Kubernetes-Zugriff, Secrets und Restore-Abläufe ein zentraler Bestandteil der Plattform.

Fazit

Die Plattform ist über drei Jahre in begrenzten Zeitfenstern gewachsen. Aus dieser Ressourcenlage entstand eine Architektur, die bewusst klein, standardnah und nachvollziehbar bleibt, dennoch aber professionellen Standards genügt. RKE2 liefert die Kubernetes-Basis, Terraform beschreibt die VMs, Helmfile verwaltet den Clusterzustand, GitLab bildet den Delivery-Kern, Longhorn/MinIO/Postgres/cert-manager tragen die zustandsbehafteten Plattformfunktionen, Prometheus macht den Betrieb sichtbar und Ansible schließt die Umgebung um den Cluster.

Für mich ist dieses Projekt eine praktische Übung in End-to-End-Systemarbeit: Anforderungen aus einem realen Umfeld ableiten, Entscheidungen technisch begründen, Komponenten integrieren, Betriebspfade schaffen und die Plattform Schritt für Schritt unter Anwendung von AI-Agenten belastbarer machen.

[print-me]

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

This website stores cookies on your computer. These cookies are used to provide a more personalized experience and to track your whereabouts around our website in compliance with the European General Data Protection Regulation. If you decide to to opt-out of any future tracking, a cookie will be setup in your browser to remember this choice for one year.

Accept or Deny