Kustomize cheatsheet.

Structure

manifests/
├── base/
│   ├── kustomization.yaml
│   ├── deployment.yaml
│   ├── service.yaml
│   └── ...
└── overlays/
    ├── dev/
    │   ├── kustomization.yaml
    │   └── patches.yaml
    ├── staging/
    └── prod/

base/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml
  - ingress.yaml

commonLabels:
  app: web

commonAnnotations:
  managed-by: kustomize

images:
  - name: myapp
    newTag: v1.0.0

overlays/prod/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: prod

resources:
  - ../../base

namePrefix: prod-
nameSuffix: -v1

replicas:
  - name: web
    count: 5

images:
  - name: myapp
    newName: ghcr.io/me/myapp
    newTag: ${GIT_SHA}

patches:
  - path: resources-patch.yaml
    target:
      kind: Deployment
      name: web
  - patch: |-
      - op: replace
        path: /spec/replicas
        value: 10
    target:
      kind: Deployment
      name: web

configMapGenerator:
  - name: app-config
    behavior: merge
    literals:
      - LOG_LEVEL=info
      - ENV=production

secretGenerator:
  - name: app-secrets
    envs:
      - secrets.env

Build / apply

kubectl kustomize overlays/prod              # render to stdout
kubectl apply -k overlays/prod

Or:

kustomize build overlays/prod | kubectl apply -f -

Patches

Strategic merge patch:

# resources-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata: { name: web }
spec:
  template:
    spec:
      containers:
        - name: web
          resources:
            limits: { cpu: 2, memory: 1Gi }

JSON patch (in kustomization.yaml):

patches:
  - patch: |-
      - op: add
        path: /spec/template/spec/containers/0/env/-
        value: { name: NEW, value: "x" }
    target: { kind: Deployment, name: web }

ConfigMap / Secret generators

configMapGenerator:
  - name: app-config
    files:
      - config.yaml
      - app.properties
    literals:
      - LOG_LEVEL=info

secretGenerator:
  - name: db-secret
    literals:
      - password=supersecret
    type: Opaque

generatorOptions:
  disableNameSuffixHash: false      # default false; suffix hashes for atomic updates

Hash suffix triggers pod restart on config change (good).

Components

Reusable units:

components/
└── monitoring/
    ├── kustomization.yaml
    ├── prometheus-rules.yaml
    └── servicemonitor.yaml
# components/monitoring/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
resources:
  - prometheus-rules.yaml
  - servicemonitor.yaml
# overlays/prod/kustomization.yaml
components:
  - ../../components/monitoring

vars (deprecated, use replacements)

replacements:
  - source:
      kind: ConfigMap
      name: app-config
      fieldPath: data.HOST
    targets:
      - select: { kind: Deployment, name: web }
        fieldPaths: [spec.template.spec.containers.0.env.[name=HOST].value]

Helm + Kustomize

helmCharts:
  - name: ingress-nginx
    repo: https://kubernetes.github.io/ingress-nginx
    version: 4.10.0
    releaseName: ingress
    namespace: ingress-nginx
    valuesFile: ingress-values.yaml
kubectl kustomize --enable-helm overlays/prod

Common patterns

Dev / staging / prod variants

# overlays/dev: 1 replica, no ingress
# overlays/staging: 2 replicas, internal ingress
# overlays/prod: 5 replicas, public ingress + cert-manager

Single base, three overlays.

Multi-tenant

Per-customer overlay with namespace + branding configmap.

Common mistakes

  • Editing base instead of patching from overlay.
  • ConfigMap hash invalidating on every build (forgot behavior: replace).
  • patches.yaml referencing wrong resource name (post namePrefix).
  • Mixing helm and kustomize naïvely → conflicts.
  • Forgetting namespace: in overlay → applies to wrong ns.

kubectl kustomize vs apply -k

# Print:
kubectl kustomize overlays/prod

# Apply:
kubectl apply -k overlays/prod

# Diff:
kubectl diff -k overlays/prod

Read this next

If you want my Kustomize template structure, it’s at rajpoot.dev .


Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .