Mandantenfähigkeit mit Flux einrichten
Gib jedem Team einen eigenen Namespace und ein eigenes Repository und setze die Isolation mit Kubernetes RBAC durch.
Wenn sich mehrere Teams einen Cluster teilen, soll jedes seine eigenen Anwendungen deployen können, ohne die der anderen anzufassen. Flux baut das auf Kubernetes-Primitiven auf: Jeder Mandant bekommt einen Namespace, einen Service Account und ein Role Binding, und Flux wendet die Manifeste des Mandanten an, während es diesen Service Account impersoniert. Die Isolation wird durch Kubernetes RBAC durchgesetzt, eine separate Policy-Engine ist nicht nötig. Diese Anleitung richtet einen Mandanten namens dev-team ein.
Die zwei Rollen
- Plattform-Admins besitzen den Cluster und die Flux-Installation. Sie erstellen Mandanten und entscheiden, worauf jeder zugreifen darf.
- Mandanten besitzen ihre Anwendungen. Sie committen Manifeste in ihr eigenes Repository, und Flux wendet sie nur im Namespace des Mandanten an.
Den Mandanten erstellen
Die CLI erzeugt Namespace, Service Account und RBAC für dich. Führe sie in einem Clone des Plattform-Repositorys aus:
mkdir -p tenants/base/dev-team
flux create tenant dev-team \
--with-namespace=apps \
--export > tenants/base/dev-team/rbac.yaml
Das erzeugte YAML enthält einen Namespace namens apps, einen ServiceAccount namens dev-team und ein RoleBinding, das diesem Service Account die Rolle cluster-admin nur innerhalb des Namespaces apps gewährt. Außerhalb davon kann er nichts tun.
Das Repository des Mandanten anbinden
Erstelle eine Source und eine Kustomization für das eigene Repository des Mandanten, im Namespace des Mandanten:
flux create source git dev-team \
--namespace=apps \
--url=https://github.com/your-org/dev-team-apps \
--branch=main \
--export > tenants/base/dev-team/sync.yaml
flux create kustomization dev-team \
--namespace=apps \
--service-account=dev-team \
--source=GitRepository/dev-team \
--path="./" \
--prune=true --interval=5m \
--export >> tenants/base/dev-team/sync.yaml
Die wichtige Zeile ist serviceAccountName: dev-team an der Kustomization. Sie bringt den kustomize-controller dazu, die Manifeste des Mandanten als dieser Service Account anzuwenden, sodass jeder Versuch, Ressourcen außerhalb von apps oder clusterweite Ressourcen wie eine ClusterRole zu erstellen, von der Kubernetes-API abgelehnt wird. Dasselbe Feld gibt es bei HelmRelease.
Füge in tenants/base/dev-team/ eine kustomization.yaml hinzu, die rbac.yaml und sync.yaml auflistet, und referenziere den Mandanten aus dem Ordner des Clusters, zum Beispiel über eine Flux-Kustomization in clusters/production/tenants.yaml mit path: ./tenants/production. Committe und pushe. Flux erstellt den Namespace, das RBAC und die Synchronisierung des Mandanten, und das eigene Repository des Teams übernimmt von dort.
Für ein privates Mandanten-Repository erstelle die Zugangsdaten im Namespace des Mandanten, sodass nur Objekte dieses Mandanten darauf verweisen:
flux create secret git dev-team-auth \
--namespace=apps \
--url=https://github.com/your-org/dev-team-apps \
--username=git --password=<token>
Füge dann der Source --secret-ref=dev-team-auth hinzu.
Die Controller absichern
Service Accounts helfen nur, wenn Mandanten sie nicht umgehen können. Konfiguriere die Controller so, dass sie die Regeln durchsetzen, indem du die Flux-Installation in clusters/<env>/flux-system/kustomization.yaml patchst:
patches:
- patch: |
- op: add
path: /spec/template/spec/containers/0/args/-
value: --no-cross-namespace-refs=true
- op: add
path: /spec/template/spec/containers/0/args/-
value: --default-service-account=default
target:
kind: Deployment
name: "(kustomize-controller|helm-controller)"
- patch: |
- op: add
path: /spec/template/spec/containers/0/args/-
value: --no-cross-namespace-refs=true
target:
kind: Deployment
name: "(notification-controller|image-reflector-controller|image-automation-controller)"
Was diese Flags bewirken:
--no-cross-namespace-refs=trueverhindert, dass die Kustomization eines Mandanten eine Source in einem anderen Namespace referenziert, sodass Mandanten weder die Repositories noch die Zugangsdaten der anderen nutzen können.--default-service-account=defaultlässt Controller den Service Accountdefaultim Namespace des Objekts impersonieren, wenn keiner gesetzt ist. Ein Mandant, derserviceAccountNamevergisst, bekommt fast keine Berechtigungen statt Fluxs Cluster-Admin-Identität.
Committe die Patches in die von Bootstrap erzeugte kustomization.yaml in diesem Ordner. Erneutes Ausführen von Bootstrap behält Anpassungen, die du in dieser Datei hinzufügst. Prüfe die aktuelle Flux-Dokumentation zur Mandantenfähigkeit auf den exakten Patch für deine Version.
Einschränken, was Mandanten tun können
Über die Namespace-Grenze hinaus kommen zusätzliche Kontrollen in Betracht:
- Namespace-bezogenes RBAC. Ersetze das erzeugte
cluster-admin-Role-Binding durch eine engere Rolle, wenn Mandanten etwa keine Roles oder NetworkPolicies erstellen sollen. - Admission Policy. Nutze Kyverno oder eine ValidatingAdmissionPolicy, um Image-Registries, Ressourcenlimits durchzusetzen oder privilegierte Pods zu verbieten.
- Quotas. Füge dem Mandanten-Namespace neben dem RBAC eine
ResourceQuotaund eineLimitRangehinzu. - Netzwerkisolation. Füge Default-Deny-
NetworkPolicy-Objekte hinzu, damit Mandanten-Namespaces nicht miteinander sprechen können.
Die Isolation prüfen
Füge dem Repository des Mandanten ein Manifest hinzu, das etwas außerhalb des Mandanten-Namespaces erstellt, etwa eine ClusterRole, und pushe. Prüfe dann:
flux get kustomizations -n apps
kubectl describe kustomization dev-team -n apps
Die Kustomization schlägt mit einem Forbidden-Fehler fehl, der den Service Account nennt, und genau das willst du. Entferne das fehlerhafte Manifest, und Flux erholt sich von selbst.
Vergleich mit projektbasierter Mandantenfähigkeit
Manche Werkzeuge modellieren Mandanten als Projekte mit eigenen Policy-Objekten. Flux kennt kein solches Konzept. Ein Mandant ist schlicht ein Namespace plus ein Service Account, den Flux impersoniert, was bedeutet, dass der Kubernetes-API-Server der einzige Ort ist, an dem Berechtigungen durchgesetzt werden.
Beliebte Anleitungen
-
Push vs. Pull: Wie Flux auf Kubernetes ausliefert Warum pull-basierte, Git-gesteuerte Auslieferung verändert, wie du Cluster deployst, absicherst und wiederherstellst. -
Deine erste Anwendung mit GitRepository und Kustomization deployen Richte Flux mit einer Kustomization-Ressource auf Manifeste in Git aus und sieh dem Sync zu. -
Sync-Verhalten steuern: Intervalle, Prune, Drift-Korrektur und Rollback Entscheide, wann Flux Änderungen anwendet, was es löscht, wie du es pausierst und wie du ein fehlerhaftes Deployment rückgängig machst. -
Image-Updates mit Flux Image Automation automatisieren Lass Flux neue Container-Image-Tags erkennen und in Git zurückcommitten. -
Multi-Cluster mit Flux konfigurieren Mehrere Cluster aus einem Repository verwalten, mit gemeinsamer Infrastruktur und Unterschieden pro Cluster. -
Flux CD vs. Argo CD: Ein GitOps-Werkzeug wählen Vergleiche Architektur, UI, Helm, Secrets, Mandantenfähigkeit und Image-Automatisierung, um das richtige Werkzeug zu wählen.