Flux Bootstrap und Multi-Tenancy
Namespace-scoped Flux und klare Grenzen.
von PlatPrep
Flux hat eine andere Philosophie als ArgoCD. Kein UI, rein deklarativ, Pull-Modell aus dem Cluster heraus. Für manche Teams ist das ein Nachteil. Für andere — besonders solche, die GitOps-Striktheit schätzen und kein zentrales UI-Dashboard wollen — ist es ein Vorzug.
Unter der Haube ist Flux kein Monolith, sondern ein Satz spezialisierter Controller: Der source-controller holt Git-Repos, Helm-Repositories und OCI-Artefakte und stellt sie als versionierte Artefakte bereit; kustomize-controller und helm-controller wenden sie an; der notification-controller verbindet das mit Webhooks und Alerts. Diese Trennung ist mehr als Architektur-Ästhetik — sie ist die Grundlage des Multi-Tenancy-Modells.
flux bootstrap github (bzw. gitlab) legt das Fundament: Flux-Komponenten installieren, ein Repo verknüpfen, und — der entscheidende Teil — Flux managed sich von da an selbst. Die Manifeste der Flux-Controller liegen im Repo; ein Upgrade ist ein Commit, kein manueller Eingriff am Cluster.
Tenants einsperren, ohne sie zu entmündigen
Das Multi-Tenancy-Problem: mehrere Teams, ein Cluster, jedes Team steuert nur die eigene Infrastruktur. Der Mechanismus dafür ist unscheinbar, aber zentral — das Feld serviceAccountName auf der Kustomization:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: team-checkout
namespace: team-checkout
spec:
serviceAccountName: team-checkout-reconciler
interval: 5m
sourceRef:
kind: GitRepository
name: team-checkout
path: ./deploy/production
prune: true
wait: true
timeout: 3m
Der kustomize-controller wendet die Manifeste mit den Rechten dieses ServiceAccounts an — und der hat per RBAC nur Rechte im eigenen Namespace. Ein fehlerhaftes oder böswilliges Manifest im Team-Repo kann damit keine fremden Namespaces anfassen; der Apply schlägt schlicht mit “forbidden” fehl. Der Punkt, der dabei gern übersehen wird: Ohne gesetzten serviceAccountName reconciled der Controller mit seinen eigenen Rechten — und die sind cluster-admin. Eine Multi-Tenancy, die das Feld vergisst, ist keine. Deshalb gehört zur Härtung auch, die Controller mit --default-service-account zu starten und Cross-Namespace-Referenzen auf Sources per --no-cross-namespace-refs zu unterbinden, damit Team A nicht die GitRepository-Source von Team B anzapfen kann.
Die bewährte Repo-Struktur dazu trennt Verantwortung sauber: ein zentrales Fleet-Repo, das dem Platform-Team gehört und Cluster-weite Dinge definiert — Flux selbst, Namespaces, RBAC, und pro Tenant die GitRepository- plus Kustomization-Ressource mit dem eingeschränkten ServiceAccount. Die Team-Repos enthalten nur noch Applikations-Manifeste. Onboarding eines neuen Teams ist ein PR ins Fleet-Repo; was das Team danach in seinem Repo tut, kann die Plattform nicht mehr kompromittieren. Das Review-Bottleneck verschiebt sich dorthin, wo es hingehört: auf die eine Stelle, die Grenzen definiert, statt auf jeden einzelnen Deploy.
Reihenfolge, Health und der Unterschied zu Kustomize
Begriffsfalle am Rande: Die Flux-Kustomization ist nicht dasselbe wie Kustomize. Es ist eine Flux-CRD, die beschreibt, welche Manifeste aus welcher Source angewendet werden — sie kann dabei Kustomize-Overlays rendern, muss aber nicht.
Zwei Felder machen den Unterschied zwischen “funktioniert meistens” und “funktioniert verlässlich”. dependsOn modelliert Reihenfolgen: erst die CRDs und der Ingress-Controller, dann die Anwendungen, die beides voraussetzen. Und wait: true lässt die Kustomization erst dann als ready gelten, wenn die erzeugten Ressourcen ihre Health-Checks bestehen — ohne das meldet Flux “applied” und ein crashender Pod fällt erst im Monitoring auf. In Kombination ergibt das deterministische Cluster-Bootstraps: Ein leerer Cluster zieht sich in der richtigen Reihenfolge komplett selbst hoch.
Ein Feature ohne direktes ArgoCD-Äquivalent ist die Image Automation: image-reflector-controller scannt Registries nach neuen Tags, image-automation-controller schreibt den neuen Tag per Commit zurück ins Git-Repo — Git bleibt die Source of Truth, aber niemand muss für jedes CI-Build manuell einen Versions-Bump committen. Mit Semver-Policies (“nur 1.x, keine Major-Sprünge”) bleibt das kontrolliert. Vorsicht ist trotzdem angebracht: Für Produktionsumgebungen wollen viele Teams den expliziten PR statt des automatischen Commits — beides lässt sich abbilden, indem die Automation auf einen Branch schreibt und ein Mensch merged.
Was bei “kein UI” gern vergessen wird: Sichtbarkeit muss trotzdem irgendwo herkommen. Der notification-controller schickt Reconcile-Fehler nach Slack oder in ein Incident-Tool, und die Controller exportieren Prometheus-Metriken, aus denen sich ein “welche Kustomization ist seit wann nicht ready”-Dashboard bauen lässt. Ohne diese Verkabelung bemerkt das Platform-Team fehlgeschlagene Reconciles erst, wenn ein Team fragt, warum sein Deployment seit zwei Tagen nicht ankommt — und genau diese Erfahrung ist es, die Flux zu Unrecht den Ruf einbringt, intransparent zu sein.
Ob Flux oder ArgoCD — die Frage entscheidet sich am Team-Workflow, nicht an Feature-Tabellen; der direkte Vergleich steht in Argo CD vs. Flux. Wer Flux von Bootstrap bis Image Automation durcharbeiten will, findet den strukturierten Einstieg im Flux-Lernpfad.