Skip to main content
RunBook Academy

KubernetesCV · KustomizeKustomize

Kustomize production discipline — render before apply, review, pin, sign

Advanced⏱ ~16 minkubectlkustomizeargocd

What you'll learn

  • Render before apply (kubectl kustomize)
  • Review the rendered output in PRs
  • Pin image tags explicitly
  • Apply the operational discipline of treating Kustomize as production configuration

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

Kustomize production discipline is the operational rigour that turns a useful tool into production configuration. This lesson walks the safety nets, the anti-patterns, and the discipline.

The safety nets

flowchart LR
    A[Kustomize safety nets] --> B["kubectl kustomize: render before apply"]
    A --> C["PR review: review the rendered diff"]
    A --> D["Pin image tags: no latest"]
    A --> E["Test selectors: verify commonLabels"]
    A --> F["Argo CD: declarative GitOps"]
    A --> G["Staging test: apply to staging first"]

The safety nets:

  • Render before apply. kubectl kustomize overlays/prod shows the rendered output. Review it before applying.
  • PR review. The rendered diff is reviewed in the PR. The reviewer verifies the expected changes.
  • Pin image tags. Never use :latest or no tag in production.
  • Verify selectors. commonLabels with includeSelectors: true changes selectors; verify they still match Pods.
  • Argo CD integration. Use Argo CD for GitOps-driven Kustomize deployments.
  • Staging test. Always apply to staging first.

Render before apply

# Render the overlay
kubectl kustomize overlays/prod

# Diff against the current cluster
kubectl kustomize overlays/prod | kubectl diff -f -

# Apply only if the diff is what you expect
kubectl apply -k overlays/prod

The workflow:

  1. Render the overlay with kubectl kustomize.
  2. Diff against the current cluster state with kubectl diff.
  3. Apply only if the diff is what you expect.

This is the discipline: render, diff, review, apply.

Pin image tags

images:
  - name: myapp
    newName: myapp
    newTag: "2.0.0"  # pinned, not latest
  - name: postgres
    newName: postgres
    newTag: "16.3"  # pinned, not latest

Always pin the image tag to a specific version. A floating tag (:latest or no tag) is unpredictable: the image may change without warning.

Verify selectors

# Before commonLabels
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp

# After commonLabels with includeSelectors: true
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
    env: prod  # added
spec:
  selector:
    matchLabels:
      app: myapp
      env: prod  # added — Pod template must also have this label
  template:
    metadata:
      labels:
        app: myapp
        env: prod  # added

The discipline: after adding commonLabels with includeSelectors: true, verify the selector still matches the Pod template. Mismatched selectors cause Deployments to fail to roll out new Pods.

Quiz

Knowledge check · 4 questions

  1. Q1. Why should `kubectl kustomize` output be reviewed rather than applied directly from source?

  2. Q2. Adding `commonLabels` to an existing Kustomize overlay is a safe, purely additive change.

  3. Q3. Explain why one Deployment is running two different builds, and pin the overlay so it cannot recur.

    `checkout` in `prod-app` has 12 Pods. `kubectl -n prod-app get pods -o jsonpath='{range .items[*]}{.status.containerStatuses[0].imageID}{"\n"}{end}' | sort | uniq -c` reports 9 Pods on one digest and 3 on another. The prod overlay sets `images: [{name: checkout, newTag: latest}]`, the Pod template carries `imagePullPolicy: Always`, and three Pods were rescheduled onto a replacement node this morning.

  4. Q4. Which kustomization.yaml field pins an image to exact bytes rather than to a tag, and why is `newTag` alone not enough for production?

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

The operational discipline

Kustomize in production rests on five non-negotiable elements:

  • Render before apply. Always kubectl kustomize first.
  • Review the diff. The rendered diff is the operational signal.
  • Pin image tags. No floating tags.
  • Verify selectors. After commonLabels changes.
  • Test in staging. Every overlay change goes through staging first.

Kustomize is production configuration. Treat it with the same rigour as any other production tool.