πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Configuration intermediate ⏱ 15 minutes K8s 1.28+

Kubernetes Kustomize Configuration Management

Manage Kubernetes configurations with Kustomize. Build overlays for multiple environments, patch resources, generate ConfigMaps and Secrets, and integrate

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: Kustomize customizes Kubernetes YAML without templates. Define a base configuration, then create overlays (dev/staging/prod) that patch specific fields. Built into kubectl: use kubectl apply -k ./overlays/production/. Key features: strategic merge patches, JSON patches, ConfigMap/Secret generators, name prefixes/suffixes, and common labels.

The Problem

  • Copying YAML files per environment leads to drift and duplication
  • Helm templates add complexity for simple configuration differences
  • Need to change just image tag or replica count per environment
  • ConfigMaps and Secrets need to trigger rollouts when changed
  • Want to use plain YAML without learning a templating language

The Solution

Directory Structure

my-app/
β”œβ”€β”€ base/
β”‚   β”œβ”€β”€ kustomization.yaml
β”‚   β”œβ”€β”€ deployment.yaml
β”‚   β”œβ”€β”€ service.yaml
β”‚   └── configmap.yaml
└── overlays/
    β”œβ”€β”€ dev/
    β”‚   β”œβ”€β”€ kustomization.yaml
    β”‚   └── replica-patch.yaml
    β”œβ”€β”€ staging/
    β”‚   β”œβ”€β”€ kustomization.yaml
    β”‚   └── resource-patch.yaml
    └── production/
        β”œβ”€β”€ kustomization.yaml
        β”œβ”€β”€ replica-patch.yaml
        └── hpa.yaml

Base Configuration

# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml

commonLabels:
  app.kubernetes.io/name: my-app
  app.kubernetes.io/managed-by: kustomize

configMapGenerator:
  - name: app-config
    literals:
      - LOG_LEVEL=info
      - CACHE_TTL=300
# base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: my-app
  template:
    metadata:
      labels:
        app.kubernetes.io/name: my-app
    spec:
      containers:
        - name: app
          image: registry.example.com/my-app:latest
          ports:
            - containerPort: 8080
          envFrom:
            - configMapRef:
                name: app-config
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "256Mi"

Production Overlay

# overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - ../../base
  - hpa.yaml         # Additional resources for prod

namespace: production

namePrefix: prod-

images:
  - name: registry.example.com/my-app
    newTag: "v2.1.0"    # Pin specific version

replicas:
  - name: my-app
    count: 5

configMapGenerator:
  - name: app-config
    behavior: merge    # Merge with base ConfigMap
    literals:
      - LOG_LEVEL=warn
      - CACHE_TTL=3600

patches:
  - path: replica-patch.yaml
# overlays/production/replica-patch.yaml (strategic merge patch)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    spec:
      containers:
        - name: app
          resources:
            requests:
              cpu: "500m"
              memory: "512Mi"
            limits:
              cpu: "2"
              memory: "1Gi"

Build and Apply

# Preview rendered output
kubectl kustomize overlays/production/
# or
kustomize build overlays/production/

# Apply directly
kubectl apply -k overlays/production/

# Diff against cluster
kubectl diff -k overlays/production/

Common Kustomize Features

# kustomization.yaml features:

# Change image tags without patching
images:
  - name: nginx
    newName: registry.example.com/nginx
    newTag: "1.25"

# Add labels/annotations to all resources
commonLabels:
  environment: production
  team: platform

commonAnnotations:
  owner: platform-team@example.com

# Generate ConfigMap from file
configMapGenerator:
  - name: nginx-config
    files:
      - nginx.conf
      - configs/app.properties

# Generate Secret
secretGenerator:
  - name: db-credentials
    literals:
      - username=admin
      - password=secret123
    type: Opaque

# JSON patch (more precise than strategic merge)
patches:
  - target:
      kind: Deployment
      name: my-app
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 10
      - op: add
        path: /spec/template/spec/containers/0/env/-
        value:
          name: NEW_VAR
          value: "added-by-patch"

ConfigMap Hash Suffix (Auto-Rollout)

# Kustomize adds hash suffix to ConfigMap names:
# app-config-abc123
# When content changes β†’ new hash β†’ Deployment references new name β†’ triggers rollout

# This ensures pods restart when config changes (unlike plain ConfigMaps)

Common Issues

”no matches for OriginalId” when patching

  • Cause: Patch target name/kind doesn’t match any resource in base
  • Fix: Verify resource name in base matches patch metadata.name exactly

ConfigMap hash suffix breaking external references

  • Cause: Other resources reference ConfigMap by fixed name
  • Fix: Use generatorOptions: { disableNameSuffixHash: true } (loses auto-rollout)

Kustomize version differences (kubectl vs standalone)

  • Cause: kubectl kustomize may be older than standalone kustomize binary
  • Fix: Use standalone: kustomize build | kubectl apply -f -

Best Practices

  1. Base + overlays pattern β€” base is the default; overlays are environment-specific
  2. Use images field for tags β€” don’t patch just to change image version
  3. ConfigMap generators with hash β€” automatic rollout on config changes
  4. Keep patches minimal β€” only override what differs from base
  5. Use replicas field β€” cleaner than patching replica count
  6. Commit kustomize output to Git β€” kustomize build > rendered.yaml for audit trail
  7. Pair with ArgoCD β€” native kustomize support for GitOps

Key Takeaways

  • Kustomize = plain YAML customization without templates (built into kubectl -k)
  • Base + overlays pattern: one base configuration, environment-specific overrides
  • images field changes tags without patches; replicas field sets replica count
  • ConfigMap/Secret generators add hash suffix β†’ automatic rollout on changes
  • Strategic merge patches override specific fields; JSON patches for precise operations
  • kubectl apply -k ./overlays/prod/ β€” one command to deploy environment
  • No templating language to learn β€” just YAML patches and generators
#kustomize #configuration #overlays #gitops #patches
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens