Flux CD est conçu nativement pour le multi-tenancy : chaque équipe peut avoir
son propre dépôt Git, ses propres namespaces et ses propres droits dans le
cluster, sans accès aux ressources des autres équipes. Ce guide explique
comment mettre en place cette isolation en utilisant les ServiceAccount Flux
et les permissions RBAC Kubernetes standards.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre le modèle de tenant de Flux (pas de CRD custom — juste du K8s)
- Créer un namespace dédié avec un
ServiceAccountFlux pour chaque équipe - Configurer une
Kustomizationpour s’exécuter sous le compte d’une équipe - Restreindre les dépôts Git autorisés par équipe
- Appliquer la politique de no-cross-namespace pour les sources
- Structurer un dépôt multi-tenant en pratique
Prérequis
Section intitulée « Prérequis »- Flux bootstrappé et fonctionnel
- Connaissance des bases RBAC Kubernetes (Role, ClusterRole, RoleBinding)
- Au moins deux équipes ou applications à isoler
Le modèle d’isolation de Flux
Section intitulée « Le modèle d’isolation de Flux »Contrairement à ArgoCD qui utilise les AppProject pour l’isolation, Flux
utilise le RBAC Kubernetes natif. L’isolation repose sur deux mécanismes :
-
ServiceAccountpar équipe — ChaqueKustomizationouHelmReleasepeut s’exécuter sous l’identité d’unServiceAccountdédié avec des droits limités à son namespace. -
Politiques de sources cross-namespace — Par défaut, une ressource Flux dans le namespace
team-ane peut pas référencer uneGitRepositorydans le namespaceflux-system(ou tout autre namespace). Vous devez autoriser explicitement ce partage.
Sans isolation (état par défaut)
Section intitulée « Sans isolation (état par défaut) »flux-system namespace └── kustomize-controller (droits cluster-admin) └── Kustomization: team-a → déploie dans team-a └── Kustomization: team-b → déploie dans team-bDans ce modèle, le contrôleur Flux s’exécute avec des droits cluster-admin.
Une Kustomization de l’équipe A peut potentiellement créer des ClusterRole
ou modifier le namespace team-b.
Avec isolation (modèle recommandé)
Section intitulée « Avec isolation (modèle recommandé) »flux-system namespace └── kustomize-controller └── Kustomization: team-a → ServiceAccount: team-a-flux (droits: team-a seulement) └── Kustomization: team-b → ServiceAccount: team-b-flux (droits: team-b seulement)Chaque Kustomization s’exécute avec les droits du ServiceAccount de
l’équipe. Le kustomize-controller se comporte juste comme un intermédiaire
qui impersonne le ServiceAccount désigné.
Créer un tenant complet
Section intitulée « Créer un tenant complet »Voici la procédure complète pour créer un tenant pour l’équipe frontend.
- Créer le namespace et le ServiceAccount
apiVersion: v1kind: Namespacemetadata: name: frontend---apiVersion: v1kind: ServiceAccountmetadata: name: flux-tenant namespace: frontend- Créer les droits RBAC du ServiceAccount
Le tenant peut créer et gérer des ressources dans son namespace, mais pas
créer de ClusterRole ou accéder aux autres namespaces :
apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: flux-tenant namespace: frontendroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin # Droits admin dans ce namespace seulementsubjects: - kind: ServiceAccount name: flux-tenant namespace: frontend- Créer la Source GitRepository pour le tenant
apiVersion: source.toolkit.fluxcd.io/v1kind: GitRepositorymetadata: name: frontend-config namespace: frontend # Dans le namespace du tenant, pas flux-systemspec: interval: 1m url: https://github.com/my-org/frontend-config ref: branch: main secretRef: name: frontend-git-credentials- Créer la Kustomization avec serviceAccountName
apiVersion: kustomize.toolkit.fluxcd.io/v1kind: Kustomizationmetadata: name: frontend-apps namespace: frontend # Dans le namespace du tenantspec: interval: 5m path: ./apps prune: true sourceRef: kind: GitRepository name: frontend-config namespace: frontend # Même namespace que la Kustomization serviceAccountName: flux-tenant # Impersonation du ServiceAccount tenant targetNamespace: frontend- Ajouter le tenant à la Kustomization racine
Dans clusters/my-cluster/, créez ou éditez la Kustomization qui gère
les tenants :
apiVersion: kustomize.toolkit.fluxcd.io/v1kind: Kustomizationmetadata: name: tenants namespace: flux-systemspec: interval: 5m path: ./tenants prune: true sourceRef: kind: GitRepository name: flux-system- Poussez dans Git et vérifiez :
git add tenants/git commit -m "feat: add frontend tenant"git push origin main
flux reconcile kustomization tenantsflux get kustomizationsPolitique de sources cross-namespace
Section intitulée « Politique de sources cross-namespace »Par défaut depuis Flux v0.27, les Kustomization et HelmRelease ne
peuvent pas référencer des sources dans d’autres namespaces sans autorisation
explicite.
Pour permettre à la Kustomization du namespace frontend de partager la
GitRepository de flux-system, créez un CrossNamespaceObjectReference
ou, plus simplement, placez la GitRepository dans le même namespace que
la Kustomization.
Si vous voulez partager une source depuis flux-system, ajoutez une annotation
sur la source :
apiVersion: source.toolkit.fluxcd.io/v1kind: GitRepositorymetadata: name: shared-infra namespace: flux-system labels: app.kubernetes.io/component: source# Pas d'annotation nécessaire côté source, mais la Kustomization# doit utiliser spec.crossNamespaceSelector ou pointer vers son namespaceLa pratique la plus simple et la mieux isolée : chaque tenant a sa propre
GitRepository dans son namespace.
Interdire les ressources cross-namespace (sécurité renforcée)
Section intitulée « Interdire les ressources cross-namespace (sécurité renforcée) »Pour bloquer complètement les références cross-namespace, activez la politique au niveau du contrôleur :
# Dans gotk-components.yaml ou votre configuration Flux# Ajoutez --no-cross-namespace-refs dans args du kustomize-controllerspec: template: spec: containers: - name: manager args: - --no-cross-namespace-refs=trueAvec cette option, toute Kustomization qui tente de référencer une source
dans un namespace différent sera immédiatement rejetée avec une erreur.
Structure d’un dépôt multi-tenant
Section intitulée « Structure d’un dépôt multi-tenant »Voici une structure recommandée pour gérer plusieurs tenants depuis le même dépôt d’administration :
fleet-infra/├── clusters/│ └── my-cluster/│ ├── flux-system/ ← Flux se gère lui-même│ └── tenants.yaml ← Kustomization qui charge ./tenants├── tenants/│ ├── frontend/│ │ ├── namespace.yaml│ │ ├── rbac.yaml│ │ ├── gitrepository.yaml│ │ └── kustomization.yaml│ ├── backend/│ │ └── ...│ └── data-team/│ └── ...└── infrastructure/ └── ... ← Ressources cluster-wide administrées par l'équipe plateformeL’équipe plateforme gère fleet-infra (les tenants + l’infrastructure).
Chaque équipe applicative gère son propre frontend-config ou backend-config.
Restreindre les droits d’une Kustomization
Section intitulée « Restreindre les droits d’une Kustomization »Pour une isolation encore plus fine, créez un Role custom qui liste
précisément les ressources qu’un tenant peut créer :
apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: flux-tenant-role namespace: frontendrules: - apiGroups: ["apps"] resources: ["deployments", "statefulsets"] verbs: ["*"] - apiGroups: [""] resources: ["services", "configmaps", "serviceaccounts"] verbs: ["*"] - apiGroups: ["networking.k8s.io"] resources: ["ingresses"] verbs: ["*"] # Interdire explicitement la création de RBAC # (en ne listant pas ces ressources)Ce Role empêche le tenant de créer des ClusterRole, des NetworkPolicy
global, ou d’accéder aux Secrets des autres namespaces.
Vérifier l’isolation
Section intitulée « Vérifier l’isolation »# Lister les Kustomizations par namespacekubectl get kustomizations -A# NAMESPACE NAME READY SUSPENDED# flux-system flux-system True False# flux-system tenants True False# frontend frontend-apps True False
# Vérifier le ServiceAccount utilisékubectl describe kustomization frontend-apps -n frontend# Spec:# Service Account Name: flux-tenant
# Tester que le tenant NE peut pas modifier le namespace flux-systemkubectl auth can-i create deployments -n flux-system \ --as=system:serviceaccount:frontend:flux-tenant# noÀ retenir
Section intitulée « À retenir »- Flux utilise le RBAC Kubernetes natif pour l’isolation — pas de CRD d’isolation spécifique.
- Chaque tenant a son propre
ServiceAccountavec desRoleBindinglimités à son namespace. - Le champ
serviceAccountNamedans uneKustomizationdélègue l’exécution au compte du tenant. - Placer la
GitRepositorydans le même namespace que laKustomizationévite les problèmes de références cross-namespace. --no-cross-namespace-refsrenforce l’isolation en interdisant tout partage de sources entre namespaces.- L’équipe plateforme gère le dépôt d’admin (tenants + infra) ; chaque équipe gère son propre dépôt applicatif.