Platform and Tenant Roles
This document outlines the roles and responsibilities of both Platform Administrators and Tenants in the multi-tenancy setup of the Flux project.
Platform Admin
- Has cluster admin access to the fleet of clusters.
- Has maintainer access to the fleet Git repository.
- Manages cluster-wide resources (CRDs, controllers, cluster roles, etc.).
- Onboards the tenant’s main
GitRepository
andKustomization
. - Manages tenants by assigning namespaces, service accounts and role binding to the tenant’s apps.
Tenant
- Has admin access to the namespaces assigned to them by the platform admin.
- Has maintainer access to the tenant Git repository and apps repositories.
- Manages app deployments with
GitRepositories
andKustomizations
. - Manages app releases with
HelmRepositories
andHelmReleases
.
Creating a Tenant
The Flux CLI offers commands to generate the Kubernetes manifests needed to define tenants. Assuming a platform admin wants to create a tenant named dev-team
with access to the apps
namespace:
Create the tenant base directory:
mkdir -p ./tenants/base/dev-team
Generate the namespace, service account and role binding for the dev-team:
flux create tenant dev-team --with-namespace=apps \ --export > ./tenants/base/dev-team/rbac.yaml
Create the sync manifests for the tenant Git repository:
flux create source git dev-team \ --namespace=apps \ --url=https://github.com// \ --branch=main \ --export > ./tenants/base/dev-team/sync.yaml
Tenant Credentials
Flux can connect to a tenant repository using SSH or token-based authentication. The tenant credentials are stored in the platform admin repository as a Kubernetes secret.
Tenant Onboarding
- Create the tenant namespace, service account and role binding.
- Decrypt the tenant Git credentials using the GPG private key.
- Create the tenant Git credentials Kubernetes secret in the tenant namespace.
- Clone the tenant repository using the supplied credentials.
- Apply the
./staging
directory from the tenant’s repo using the tenant’s service account.
Default Service Account
When Flux is bootstrapped, both kustomize-controller
and helm-controller
will impersonate the default
service account in the tenant namespace when applying changes to the cluster. The default
service account exists in all namespaces and should always be kept without any privileges. To enable a tenant to operate, a service account must be created with the required permissions and its name set to the spec.serviceAccountName
of all Kustomization
and HelmRelease
resources the tenant has.
Default Service Account Patch
The kustomization.yaml
file in both clusters applies a patch that sets a default service account via --default-service-account
to kustomize-controller
and helm-controller
. If a tenant does not specify a service account in a Flux Kustomization
or HelmRelease
, it would automatically default to the default
service account. It is recommended that the default service account has no privileges and each named service account used observes the least privilege model.
Tenant Repository Configuration
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: apps
resources:
- ../base/dev-team
patches:
- path: dev-team-patch.yaml
With this configuration, the Flux instance running on the staging cluster will clone the dev-team’s repository and reconcile the ./staging
directory from the tenant’s repo using the dev-team
service account. Since this service account is restricted to the apps
namespace, the dev-team repository must contain Kubernetes objects scoped to the apps
namespace only.
Security Considerations
The Platform Admin may impose additional policies to enforce specific behaviours. Some considerations include:
- Expand policies to
HelmRepository
andBucket
. - Restrict protocols allowed for
HelmRepository
andGitRepository
. - Restrict providers and regions for
Bucket
.
Policy Validation Webhook
On cluster bootstrap, Flux needs to be configured to deploy the validation webhook and its policies before reconciling the tenants’ repositories. The clusters
directory defines the order in which the infrastructure items and the tenant workloads will be reconciled on the staging and production clusters:
./clusters/
├── production
│ ├── infrastructure.yaml
│ └── tenants.yaml
└── staging
├── infrastructure.yaml
└── tenants.yaml
First, custom resource definitions and their controllers are set up. For example, using Kyverno:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: kyverno
namespace: flux-system
spec:
interval: 10m
sourceRef:
kind: GitRepository
name: flux-system
path: ./infrastructure/kyverno
Tenant Repository Verification
Verify that the tenant Git repository has been cloned:
$ flux -n apps get sources git
NAME READY MESSAGE
dev-team True Fetched revision: dev-team/ca8ec25405cc03f2f374d2f35f9299d84ced01e4
Verify that the tenant Helm repository index has been downloaded:
$ flux -n apps get sources helm
NAME READY MESSAGE
podinfo True Fetched revision: 2022-05-23T10:09:58.648748663Z
Wait for the demo app to be installed:
$ watch flux -n apps get helmreleases
NAME READY MESSAGE REVISION SUSPENDED
podinfo True Release reconciliation succeeded 5.0.3 False
To expand on this example, check the enforce tenant isolation for security related considerations.
Repository Structure
The platform admin repository contains the following top directories:
- clusters dir contains the Flux configuration per cluster.
- infrastructure dir contains common infra tools such as admission controllers, CRDs and cluster-wide polices.
- tenants dir contains namespaces, service accounts, role bindings and Flux custom resources for registering tenant repositories.
├── clusters
│ ├── production
│ └── staging
├── infrastructure
│ ├── kyverno
│ └── kyverno-policies
└── tenants
├── base
├── production
└── staging
A tenant repository contains the following top directories:
- base dir contains
HelmRepository
andHelmRelease
manifests. - staging dir contains
HelmRelease
Kustomize patches for deploying pre-releases on the staging cluster.
Alternative Approach
Kyverno’s resource generation feature can be leveraged to create tenants instead of using the flux create tenant
approach.
Default Patch Examples
patches:
- patch: |
- op: add
path: /spec/template/spec/containers/0/args/-
value: --no-cross-namespace-refs=true
target:
kind: Deployment
name: "(kustomize-controller|helm-controller|notification-controller|image-reflector-controller|image-automation-controller)"
- patch: |
- op: add
path: /spec/template/spec/containers/0/args/-
value: --no-remote-bases=true
target:
kind: Deployment
name: "kustomize-controller"
- patch: |
- 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/serviceAccountName
value: kustomize-controller
target:
kind: Kustomization
name: "flux-system"
Top-Level Directory Explanations
clusters/ - This directory contains configuration and scripts for managing Kubernetes clusters.
clusters/production/ - This directory contains configuration and scripts for managing the production Kubernetes cluster.
clusters/production/flux-system/ - This directory contains configuration and scripts for the FluxCD system in the production cluster.
clusters/staging/ - This directory contains configuration and scripts for managing the staging Kubernetes cluster.
clusters/staging/flux-system/ - This directory contains configuration and scripts for the FluxCD system in the staging cluster.
infrastructure/ - This directory contains infrastructure-related configuration files and scripts.
infrastructure/kyverno-policies/ - This directory contains the actual policy files for Kyverno.
infrastructure/kyverno/ - This directory contains configuration files and scripts for Kyverno, an open-source Kubernetes policy engine.
scripts/ - This directory contains scripts used for various tasks, such as automation and deployment.
tenants/ - This directory contains configuration and scripts for managing tenants, which are separate namespaces or projects within the Kubernetes cluster.
tenants/base/ - This directory contains configuration and scripts for the base tenant.
tenants/base/dev-team/ - This directory contains configuration and scripts for the development team within the base tenant.
tenants/production/ - This directory contains configuration and scripts for the production tenant.
tenants/staging/ - This directory contains configuration and scripts for the staging tenant.