Flux Kustomization resources are the heart of GitOps deployments, but understanding how they actually work under the hood is surprisingly nuanced.
Let’s watch a Kustomization resource in action. Imagine you have a simple Kubernetes Deployment in a Git repository, and you want Flux to manage it.
First, you’ll define your Kustomization resource in Kubernetes:
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: my-app-deployment
namespace: flux-system
spec:
interval: 10m
path: ./apps/my-app/overlays/production # Path to your Kustomized manifests in Git
prune: true
sourceRef:
kind: GitRepository
name: flux-system # Name of your GitRepository source
validation: client # Or 'server' depending on your setup
This tells Flux: "Every 10 minutes, go to the flux-system GitRepository, look at the ./apps/my-app/overlays/production directory, apply whatever manifests are there, and if anything in that directory is no longer present in Git, delete it from the cluster."
Now, let’s look at what’s in that Git directory:
# apps/my-app/overlays/production/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: nginx:1.21.6
ports:
- containerPort: 80
When Flux reconciles this Kustomization, it doesn’t just kubectl apply the files. It first fetches the specified Git commit. Then, it uses kustomize build (or a similar internal process) on the path you’ve defined. This means if you had a kustomization.yaml file in that directory, Flux would process that as well, allowing for overlays and patching.
The result of kustomize build is a set of raw Kubernetes manifests. Flux then takes these raw manifests and applies them to your cluster. The prune: true setting means that after applying the current set of manifests, Flux will compare them against the previous set it applied. Any resources that existed in the previous set but are not in the current set will be deleted. This is crucial for ensuring your cluster state precisely matches your Git repository.
The sourceRef points to a GitRepository custom resource, which is where Flux actually stores the credentials and URL for your Git repo. Flux will periodically fetch changes from this repository based on the interval defined in the GitRepository resource itself.
The validation field (client or server) determines how Flux validates the applied manifests. client validation means Flux performs basic schema validation locally. server validation means it relies on the Kubernetes API server for validation, which is generally more robust.
Here’s a slightly more complex scenario: imagine you have a base deployment.yaml and you want to apply different replica counts for production and staging.
In Git:
# apps/my-app/base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: nginx:1.21.6
ports:
- containerPort: 80
# apps/my-app/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base/deployment.yaml
patchesStrategicMerge:
- replicas.yaml
# apps/my-app/overlays/production/replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app # Must match the name in the base
spec:
replicas: 5 # Production replica count
And your Flux Kustomization resource would point to ./apps/my-app/overlays/production. Flux will execute kustomize build on this directory, which will merge the replicas.yaml into the base deployment.yaml, resulting in a Deployment with 5 replicas.
The most crucial detail many overlook is how Flux handles drift detection and reconciliation. When Flux applies a Kustomization, it records the state of the applied resources. If a user or another controller manually changes a resource managed by Flux (e.g., kubectl scale deployment my-app --replicas=10), Flux, on its next reconciliation, will detect this drift and revert the resource back to the state defined in Git. This is the core of GitOps – the Git repository is the single source of truth, and Flux enforces it.
The next step you’ll often encounter is managing secrets, which involves understanding the SecretGenerator or SOPS integration within Flux.