Skip to content

Kustomize Cheatsheet

Installation

Platform Command
kubectl (built-in) kubectl version --client (v1.14+, no installation needed)
macOS (Homebrew) brew install kustomize
Linux (curl) curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" \| bash && sudo mv kustomize /usr/local/bin/
Windows (Chocolatey) choco install kustomize
Windows (Scoop) scoop install kustomize
Docker docker run --rm -v $(pwd):/work k8s.gcr.io/kustomize/kustomize:v5.0.0 build /work
Verify Installation kustomize version or kubectl kustomize --help

Basic Commands

Command Description
kustomize build . Generate customized YAML from current directory
kubectl kustomize . Build using kubectl's integrated kustomize
kubectl apply -k . Build and apply manifests directly to cluster
kustomize build . > output.yaml Build and save output to file
kustomize create Create a new kustomization.yaml file
kustomize create --autodetect Create kustomization.yaml with auto-detected resources
kustomize create --namespace prod Create kustomization.yaml with specified namespace
kustomize edit add resource deployment.yaml Add a resource to kustomization.yaml
kustomize edit add base ../base Add a base directory reference
kustomize edit set namespace production Set the namespace for all resources
kustomize edit set nameprefix prod- Add prefix to all resource names
kustomize edit set namesuffix -v2 Add suffix to all resource names
kustomize edit add label app:myapp Add common labels to all resources
kustomize edit add annotation version:1.0.0 Add common annotations to all resources
kustomize build . \| kubectl apply --dry-run=client -f - Validate manifests without applying

ConfigMap and Secret Management

Command Description
kustomize edit add configmap my-config --from-literal=key1=value1 Create ConfigMap from literal values
kustomize edit add configmap app-config --from-file=config.properties Create ConfigMap from file
kustomize edit add configmap env-config --from-env-file=.env Create ConfigMap from environment file
kustomize edit add secret db-secret --from-literal=password=secret123 Create Secret from literal values
kustomize edit add secret tls-secret --from-file=tls.crt=cert.pem Create Secret from files
kustomize edit add configmap app-config --behavior=merge Create ConfigMap with merge behavior
kustomize edit add configmap app-config --disableNameSuffixHash=true Create ConfigMap without hash suffix

Image Management

Command Description
kustomize edit set image myapp=myapp:v2.0.0 Update image tag for a container
kustomize edit set image myapp=gcr.io/project/myapp:v2.0.0 Update image with full registry path
kustomize edit set image frontend=frontend:v1.2.0 backend=backend:v1.3.0 Update multiple images simultaneously
kustomize edit set image myapp=myapp:latest Set image to latest tag

Advanced Usage

Command Description
kustomize edit set replicas deployment/myapp=3 Set replica count for specific deployment
kustomize edit add patch --path patch-deployment.yaml Add a strategic merge patch file
kustomize edit add patch --kind Deployment --name myapp --patch '[{"op": "replace", "path": "/spec/replicas", "value": 3}]' Add inline JSON patch
kustomize build overlays/production Build from specific overlay directory
kustomize build --enable-alpha-plugins . Build with alpha plugin support enabled
kustomize build --load-restrictor=LoadRestrictionsNone . Build without load restrictions
kustomize build --reorder=legacy . Build with legacy resource ordering
kustomize build --output /tmp/output.yaml . Build with specific output file
kustomize cfg grep "kind=Deployment" Search for resources by kind
kustomize cfg count . Count resources in kustomization
kustomize cfg tree . Display resource tree structure
kustomize edit add component ../../components/monitoring Add reusable component to overlay
kustomize edit add resource crd.yaml Add Custom Resource Definition
kustomize edit add transformer patch-transformer.yaml Add custom transformer
kustomize build . \| kubectl apply --dry-run=server -f - Server-side validation before applying

Configuration

Basic kustomization.yaml Structure

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

# Resources to include
resources:
  - deployment.yaml
  - service.yaml
  - configmap.yaml

# Namespace for all resources
namespace: production

# Common labels applied to all resources
commonLabels:
  app: myapp
  environment: prod

# Common annotations applied to all resources
commonAnnotations:
  managed-by: kustomize
  version: "1.0.0"

# Name prefix/suffix
namePrefix: prod-
nameSuffix: -v1

# Images to replace
images:
  - name: myapp
    newName: gcr.io/myproject/myapp
    newTag: v2.0.0

# Replica counts
replicas:
  - name: myapp-deployment
    count: 3

Overlay Structure with Base

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

# Reference to base
bases:
  - ../../base

# Production-specific namespace
namespace: production

# Production-specific patches
patchesStrategicMerge:
  - deployment-patch.yaml
  - service-patch.yaml

# Production replicas
replicas:
  - name: myapp
    count: 5

# Production images
images:
  - name: myapp
    newTag: v2.0.0

Strategic Merge Patch Example

# deployment-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
        - name: myapp
          resources:
            limits:
              memory: "2Gi"
              cpu: "1000m"
            requests:
              memory: "1Gi"
              cpu: "500m"
          env:
            - name: ENVIRONMENT
              value: "production"

JSON Patch Example

# kustomization.yaml with JSON patches
patchesJson6902:
  - target:
      group: apps
      version: v1
      kind: Deployment
      name: myapp
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 5
      - op: add
        path: /spec/template/spec/containers/0/env/-
        value:
          name: NEW_VAR
          value: "new_value"

ConfigMap Generator

configMapGenerator:
  - name: app-config
    files:
      - application.properties
      - config.json
    literals:
      - ENVIRONMENT=production
      - LOG_LEVEL=info
    behavior: create  # create, replace, or merge
    options:
      disableNameSuffixHash: false
      labels:
        app: myapp
      annotations:
        config-version: "1.0"

Secret Generator

secretGenerator:
  - name: db-credentials
    literals:
      - username=admin
      - password=secretpassword
    type: Opaque
  - name: tls-secret
    files:
      - tls.crt=cert.pem
      - tls.key=key.pem
    type: kubernetes.io/tls

Replacements (Variable Substitution)

replacements:
  - source:
      kind: ConfigMap
      name: app-config
      fieldPath: data.app_version
    targets:
      - select:
          kind: Deployment
        fieldPaths:
          - spec.template.metadata.labels.version
      - select:
          kind: Service
        fieldPaths:
          - metadata.annotations.[app.version]

Components (Reusable Configuration)

# components/monitoring/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component

resources:
  - servicemonitor.yaml
  - prometheusrule.yaml

labels:
  - pairs:
      monitoring: enabled
# Using component in overlay
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - ../../base

components:
  - ../../components/monitoring
  - ../../components/logging

Common Use Cases

Use Case 1: Multi-Environment Deployment

# Directory structure
# .
# ├── base/
# │   ├── kustomization.yaml
# │   ├── deployment.yaml
# │   └── service.yaml
# ├── overlays/
# │   ├── dev/
# │   │   └── kustomization.yaml
# │   ├── staging/
# │   │   └── kustomization.yaml
# │   └── production/
# │       └── kustomization.yaml

# Create base
cd base
kustomize create --autodetect
kustomize edit add label app:myapp

# Create dev overlay
cd ../overlays/dev
kustomize create
kustomize edit add base ../../base
kustomize edit set namespace dev
kustomize edit set replicas deployment/myapp=1
kustomize edit set image myapp=myapp:dev

# Create production overlay
cd ../production
kustomize create
kustomize edit add base ../../base
kustomize edit set namespace production
kustomize edit set replicas deployment/myapp=5
kustomize edit set image myapp=myapp:v1.0.0

# Deploy to different environments
kubectl apply -k overlays/dev
kubectl apply -k overlays/staging
kubectl apply -k overlays/production

Use Case 2: Adding Secrets and ConfigMaps

# Create base configuration
kustomize create --resources deployment.yaml,service.yaml

# Add ConfigMap from file
kustomize edit add configmap app-config \
  --from-file=application.properties \
  --from-literal=LOG_LEVEL=info

# Add Secret from literals
kustomize edit add secret db-credentials \
  --from-literal=username=admin \
  --from-literal=password=changeme

# Add Secret from files
kustomize edit add secret tls-certs \
  --from-file=tls.crt=./certs/server.crt \
  --from-file=tls.key=./certs/server.key

# Build and verify
kustomize build . | grep -A 10 "kind: ConfigMap"
kustomize build . | grep -A 10 "kind: Secret"

# Apply to cluster
kubectl apply -k .

Use Case 3: Patching Resources for Different Environments

# Create production overlay
mkdir -p overlays/production
cd overlays/production

# Create kustomization
kustomize create
kustomize edit add base ../../base
kustomize edit set namespace production

# Create patch file for resource limits
cat <<EOF > deployment-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
        - name: myapp
          resources:
            limits:
              memory: "4Gi"
              cpu: "2000m"
            requests:
              memory: "2Gi"
              cpu: "1000m"
EOF

# Add patch to kustomization
kustomize edit add patch --path deployment-patch.yaml

# Add production-specific environment variables
cat <<EOF > env-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
        - name: myapp
          env:
            - name: ENVIRONMENT
              value: "production"
            - name: DB_HOST
              value: "prod-db.example.com"
EOF

kustomize edit add patch --path env-patch.yaml

# Build and apply
kustomize build . | kubectl apply -f -

Use Case 4: Using Components for Optional Features

# Create monitoring component
mkdir -p components/monitoring
cd components/monitoring

# Create component kustomization
cat <<EOF > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component

resources:
  - servicemonitor.yaml

labels:
  - pairs:
      monitoring.enabled: "true"
EOF

# Create ServiceMonitor resource
cat <<EOF > servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: myapp
spec:
  selector:
    matchLabels:
      app: myapp
  endpoints:
    - port: metrics
      interval: 30s
EOF

# Use component in production overlay
cd ../../overlays/production
kustomize edit add component ../../components/monitoring

# Build with monitoring enabled
kustomize build .

# Deploy
kubectl apply -k .

Use Case 5: Managing Multiple Applications

# Directory structure for multiple apps
# .
# ├── apps/
# │   ├── frontend/
# │   │   ├── base/
# │   │   └── overlays/
# │   ├── backend/
# │   │   ├── base/
# │   │   └── overlays/
# │   └── database/
# │       ├── base/
# │       └── overlays/
# └── clusters/
#     ├── dev/
#     └── production/

# Create cluster-level kustomization for production
cd clusters/production
cat <<EOF > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: production

resources:
  - ../../apps/frontend/overlays/production
  - ../../apps/backend/overlays/production
  - ../../apps/database/overlays/production

commonLabels:
  environment: production
  cluster: production-us-east-1
EOF

# Deploy entire production cluster
kubectl apply -k clusters/production

# Deploy only frontend
kubectl apply -k apps/frontend/overlays/production

# Build and review all production resources
kustomize build clusters/production > production-manifests.yaml

Best Practices

  • Use base and overlays pattern: Keep common configurations in base and environment-specific changes in overlays to follow DRY principles and maintain consistency across environments

  • Enable name suffix hashing for ConfigMaps/Secrets: This triggers pod restarts when configuration changes, ensuring applications pick up new configs automatically (disableNameSuffixHash: false)

  • Organize directory structure logically: Use a clear hierarchy like base/, overlays/dev/, overlays/production/, and components/ to make the repository easy to navigate and understand

  • Use strategic merge patches for simple changes: Prefer patchesStrategicMerge over JSON patches for readability and maintainability when making straightforward modifications to resources

  • Version control everything: Commit all kustomization files, patches, and manifests to Git for full traceability, rollback capability, and GitOps workflows

  • Validate before applying: Always run kustomize build . | kubectl apply --dry-run=server -f - to catch errors and validate resources against the cluster's OpenAPI schema before actual deployment

  • Use components for optional features: Create reusable components for cross-cutting concerns like monitoring, logging, or security policies that can be optionally included in different overlays

  • Keep patches focused and minimal: Create small, targeted patches that modify only what's necessary rather than duplicating entire resource definitions

  • Use replacements instead of vars: Prefer the newer replacements field over deprecated vars for variable substitution and cross-resource references

  • Document your kustomization structure: Add comments in kustomization.yaml files and maintain a README explaining the overlay strategy and how to deploy to different environments

Troubleshooting

Issue Solution
Error: "no matches for kind X in version Y" Ensure your cluster supports the API version. Check with kubectl api-resources or update the resource's apiVersion field
Resources not being patched Verify patch target matches exactly (name, kind, apiVersion). Use kustomize build . to inspect output and ensure patches are applied
ConfigMap/Secret changes not triggering pod restart Enable name suffix hashing (disableNameSuffixHash: false) so resource names change when content changes, forcing pod recreation
"accumulating resources: accumulation err='accumulating resources from '../base': ...'" Check that base path is correct and base directory contains valid kustomization.yaml. Use relative paths from overlay directory
Duplicate resource error Remove duplicate entries from resources list or check if resource is included both directly and through a base. Use kustomize build . to identify duplicates
Image not being replaced Ensure image name in images field matches container image name exactly. Use kustomize edit set image command to avoid typos
"json: cannot unmarshal string into Go value" Check YAML syntax in kustomization.yaml. Ensure proper indentation and that list items use - prefix. Validate with yamllint
Patches not applying in expected order Patches are applied in order listed. Reorder patches in patchesStrategicMerge or patchesJson6902 arrays to control application sequence
"field X not found in type Y" The field doesn't exist in the resource type. Check Kubernetes API documentation for correct field paths and structure
Namespace not being set on resources Some resources are cluster-scoped (ClusterRole, PersistentVolume). Verify resource kind supports namespaces with kubectl api-resources --namespaced=true
Remote base not loading Check network connectivity and URL format. For GitHub: github.com/org/repo//path?ref=version. Ensure repository is public or credentials are configured
Component not being applied Verify component path is correct and component has kind: Component. Check that component's kustomization.yaml is valid

Quick Reference Tips:

  • Use kubectl apply -k . instead of kustomize build . | kubectl apply -f - for simpler deployments
  • Add --dry-run=client -o yaml to preview changes without cluster access
  • Use kustomize cfg tree to visualize resource relationships and dependencies
  • Set KUSTOMIZE_PLUGIN_HOME environment variable for custom plugin locations
  • Check built-in transformer documentation: kustomize config help