Skip to main content
RunBook Academy

Git, CI/CD & GitOpsLXXVIII · FluxKustomize

Kustomization controller — reconciling Kustomize manifests into the cluster

Advanced⏱ ~27 mingitflux

What you'll learn

  • Describe what kustomize-controller does and which CRD it owns
  • Read a Kustomization spec and identify the source reference, interval, path, prune, wait, and health-check fields
  • Configure prune and dependsOn for a production Kustomization
  • Use `flux create kustomization` to manage a Kustomization against a GitRepository source

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

kustomize-controller is the workhorse of a Flux install. It owns the Kustomization CRD, consumes a source artifact from source-controller, runs kustomize build against a path inside that artifact, and applies the rendered manifests into the target cluster.

What kustomize-controller does

The controller watches Kustomization CRDs. For each one it performs four phases per reconcile:

  1. Read source. Look up the source CRD named in spec.sourceRef, wait for its Ready=True condition, and fetch the artifact from the in-cluster URL.
  2. Build. Run kustomize build against spec.path inside the artifact.
  3. Diff. Compare the rendered manifest set against the cluster’s live state.
  4. Apply and prune. Apply the diff into the cluster; prune any resource present in the previous apply but absent in the new one if spec.prune=true.
flowchart LR
    K["Kustomization CRD"] --> KC["kustomize-controller"]
    KC --> R["Read source artifact"]
    R --> B["kustomize build path/"]
    B --> D["diff against live state"]
    D -->|"diff empty"| OK["Ready=True"]
    D -->|"diff present"| AP["server-side apply"]
    AP --> K8s["Cluster"]
    KC --> H["Health checks"]

The Kustomization spec

The fields that matter:

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  sourceRef:
    kind: GitRepository
    name: apps
  interval: 10m0s
  path: ./clusters/production
  prune: true
  wait: true
  timeout: 5m0s
  force: false
  healthChecks:
    - apiVersion: apps/v1
      kind: Deployment
      name: payments-api
      namespace: payments
  dependsOn:
    - name: namespaces
  • spec.sourceRef - the source CRD this Kustomization consumes. The controller waits for Ready=True.
  • spec.interval - the reconcile interval. Production default is 10m0s.
  • spec.path - the path inside the source artifact to kustomize build. Must contain a kustomization.yaml.
  • spec.prune - if true, the controller deletes any resource present in the cluster from a prior apply but absent in the new build.
  • spec.wait - if true, the controller blocks the reconcile until applied resources report Ready.
  • spec.healthChecks - explicit health checks the controller runs alongside the built-in kstatus checks.
  • spec.dependsOn - an ordered list of Kustomizations that must complete before this one applies.

Creating a Kustomization

flux create kustomization apps \
  --source=GitRepository/apps \
  --path=./clusters/production \
  --prune=true \
  --wait=true \
  --interval=10m0s \
  --depends-on=namespaces \
  --export

--source takes Kind/name and resolves to sourceRef. --depends-on repeats for multiple dependencies. --export prints the YAML; without it, the command applies the CRD.

Inspect and reconcile:

flux get kustomizations
flux reconcile kustomization apps
flux get kustomization apps --status

flux get kustomizations --status includes the last applied revision, the last failed revision, and the inventory of applied objects - the audit answer to “what is running here”.

Pruning, drift, and the apply contract

When spec.prune=true, the controller deletes any cluster resource it owns that is absent in the new build. The controller inventories every resource it applies, identified by the kustomize.toolkit.fluxcd.io/name label. A resource that was never applied by the controller is not pruned.

Under the hood

The controller’s apply is server-side apply with force ownership. The controller owns every field it applies; any out-of-band change to a managed field is reverted on the next reconcile.

Production discipline

  1. spec.path contains a kustomization.yaml. A bare manifest directory loses the post-build hooks that make Kustomize worth using.
  2. spec.prune=true is paired with branch protection. A broken PR should not auto-prune before review.
  3. spec.dependsOn is used for ordering, not fan-in. Split the tree into smaller Kustomizations.

Cross-course references

  • Kubernetes for Production Sysadmins - Parts VII-VIII (Workloads) cover the Deployments the Kustomization applies.
  • Git, CI/CD & GitOps for Infrastructure Engineers - Part LXXVI (GitOps Repo Architecture) is the repository layout spec.path points at.

Quiz

Knowledge check · 4 questions

  1. Q1. Which field in a Kustomization spec tells the controller to delete any cluster resource it previously applied that is absent from the new build?

  2. Q2. A Kustomization with `spec.prune=false` will leave drift in the cluster and still report Ready=True, because the controller's only contract is to apply the new build, not to delete the old.

  3. Q3. Name the four phases of a kustomize-controller reconcile in order, and identify which phase invokes the kubectl apply.

  4. Q4. Diagnose why a Kustomization is reporting Ready=False, reason=DependencyNotReady, and recommend the fix.

    A team runs `flux get kustomizations` and sees that the `apps` Kustomization is reporting Ready=False, reason=DependencyNotReady. The team runs `flux get kustomization apps -o yaml` and sees spec.dependsOn contains a `namespaces` Kustomization that no longer exists. The `namespaces` directory was deleted from the Git tree six weeks ago; the `apps` Kustomization spec was not updated.

Passing score: 75%. Answers are checked in this browser.