
🌐 Auch auf: English · Français · Español
😌 Kleine Vorwarnung: Diese Folge ist die Ruhe vor dem Sturm. GitLab und die Seed-VM waren erfrischend unkompliziert – langweilige Infrastruktur, mit voller Absicht langweilig umgesetzt. Ich erwähne das ausdrücklich, weil der nächste Beitrag Kubernetes-Gebiet ist – FluxCD, GitOps-Reconciliation-Loops und all die Arten, wie ein Cluster kerngesund aussehen kann, bis er es ganz plötzlich nicht mehr ist – und dieser Kampf war deutlich härter. Betrachte das hier als tiefes Luftholen vor dem Abtauchen. 🤿 🦊 Jedes Homelab erreicht irgendwann den Punkt, an dem „ich logge mich schnell per SSH ein und tippe den Befehl von Hand“ nicht mehr charmant ist, sondern zum Risiko wird. In diesem Beitrag geht es um den Moment, in dem dieses Lab diese Grenze überschritten hat: GitLab als Single Source of Truth aufsetzen und eine eigene Seed-VM bauen, damit „die Werkzeuge zur Verwaltung der Infrastruktur“ nicht mehr auf irgendeinem Laptop leben, den ich gerade zufällig in der Hand halte. 💻➡️🗄️ Die vorherige Folge zum Nachholen (auf Englisch): Homelab Rebuild 2026: Building the Proxmox Cluster and Provisioning it with Terraform.🦊 GitLab: Von der Bare-Metal-Kiste zur ordentlichen VM
GitLab läuft in diesem Homelab eigentlich schon eine ganze Weile – nur eben nicht richtig. Die ursprüngliche Instanz lief direkt auf dem Bare Metal von HP3 (Debian, kein Hypervisor darunter, keine Snapshots, keine Backups, die den Namen verdienen). Funktionierte, war aber genau die Sorte „Provisorium“, die still und leise zur dauerhaften Infrastruktur wird, von der alle abhängen. 😅 Die Lösung: GitLab ordentlich als VM installieren (HP1-gitlab01, 192.168.10.x, 12 GB RAM, 120 GB Disk) über das Standard-Omnibus-Paket – GitLabs offizielles apt-Repository, ein einziges Paket mit GitLab selbst plus mitgeliefertem PostgreSQL, Redis und NGINX, konfiguriert über eine einzige /etc/gitlab/gitlab.rb. Bewusst der langweilige, ausgetretene Installationspfad: Das ist Infrastruktur, über die ich nicht nachdenken will, kein Wissenschaftsprojekt. Intern läuft sie über schlichtes HTTP, noch ohne TLS davor – für eine reine LAN-Instanz okay, auch wenn mir das später auf die Füße gefallen ist, als sich das Bootstrap von FluxCD weigerte, Zugangsdaten über unverschlüsseltes HTTP zu schicken (eine Geschichte für einen anderen Beitrag 👀). Der wirklich spannende Teil war nicht die frische Installation, sondern die Daten der alten Instanz ohne Verlust der Historie herüberzuholen. Das erledigten GitLabs eigene Backup-/Restore-Werkzeuge: ein vollständiges gitlab-backup create auf der alten Bare-Metal-Kiste, das resultierende Archiv plus die Secrets-Datei der Instanz (gitlab-secrets.json) rüberkopiert, dann gitlab-backup restore auf der neuen VM mit passender GitLab-Version. Projekte, Issues und – ganz entscheidend – jeder Branch jedes Repos kamen unversehrt an, einschließlich des internal-Branches dieses Projekts (der mit den echten Zugangsdaten, der nie auf den öffentlichen GitHub-Mirror gepusht wird). Ich habe Claude die komplette Abfolge Export → Transfer → Import → Prüfung durchgehen lassen und bestätigen lassen, dass die migrierte Instanz wirklich der alten entsprach, bevor HP3 plattgemacht wurde. 🔍✅ Nach der Prüfung wurde die Bare-Metal-Debian-Installation auf HP3 komplett gelöscht und als dritter Proxmox-VE-Node neu aufgebaut – GitLab läuft jetzt also nicht nur auf einer VM, sondern auf einer VM im selben Proxmox-Cluster wie alles andere, mit Snapshots und PBS-Backups wie jeder andere Workload auch. Schluss mit der „hoffentlich stirbt die Bare-Metal-Kiste nicht“-Stimmung. 🙏🌱 Auftritt: die Seed-VM
Nachdem GitLab nun die echte Source of Truth für Terraform und Ansible ist, lag die nächste Lücke auf der Hand: Wo laufenterraform apply und ansible-playbook eigentlich? „Auf dem Rechner, auf dem an dem Tag gerade die Tools installiert sind“ ist keine Antwort, sondern ein Risiko im Trenchcoat. Also: HP1-seed01 (192.168.10.x) – eine kleine, langweilige Ubuntu-VM mit 4 GB / 60 GB, deren einzige Aufgabe es ist, der eine Ort zu sein, von dem aus Änderungen an der Infrastruktur gemacht werden. Komplett von einem Ansible-Playbook gebaut (02_ansible/playbooks/seed01.yml), also in Minuten von Grund auf neu aufsetzbar statt „so, wie ich mich erinnere, es letztes Mal eingerichtet zu haben“. 🌱 Was darauf landet:- 🔧 git – ohne Versions-Pin, kein Grund, da pingelig zu sein
- 🏗️ Terraform, auf eine exakte Version gepinnt (
1.15.8) über das offizielle apt-Repo von HashiCorp – Infrastrukturänderungen sollten nie stillschweigend mitten im Apply ein neues Terraform-Release erwischen - 📜 Ansible selbst, damit die Seed-VM irgendwann Playbooks gegen den Rest der Flotte ausführen kann, sich selbst eingeschlossen
- ☸️ kubectl, gepinnt auf die Minor-Version des RKE2-Clusters (aktuell
v1.36) über das offizielle Kubernetes-apt-Repo - ⎈ Helm, auf ein exaktes Release gepinnt, direkt von
get.helm.shgeholt
kubectl-Binary ab und erklärt sich für fertig – es holt die aktuelle kubeconfig direkt vom ersten Control-Plane-Node des Clusters, ersetzt die Loopback-Adresse durch die echte IP dieses Nodes und installiert sie für die Accounts ubuntu und user3. kubectl get nodes funktioniert in der Sekunde, in der das Playbook fertig ist, ohne dass man eine kubeconfig von Hand herumkopiert. Zweitens bekommt jeder Account einen Alias k für kubectl, inklusive voller Bash-Completion – k get pods vervollständigt sich per Tab also genau wie kubectl get pods. Kleinigkeit, spart für immer Tastenanschläge. ⌨️ Die Versionen selbst stehen an einer einzigen Stelle (group_vars/all.yml) – Zahl hochdrehen, Playbook erneut laufen lassen, und alle Tools ziehen im Gleichschritt mit dem nach, was der Cluster tatsächlich braucht. Keine „Moment, welche kubectl-Minor-Version hab ich eigentlich?“-Momente mehr.



