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/, andcomponents/to make the repository easy to navigate and understand -
Use strategic merge patches for simple changes: Prefer
patchesStrategicMergeover 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
replacementsfield over deprecatedvarsfor 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 ofkustomize build . | kubectl apply -f -for simpler deployments - Add
--dry-run=client -o yamlto preview changes without cluster access - Use
kustomize cfg treeto visualize resource relationships and dependencies - Set
KUSTOMIZE_PLUGIN_HOMEenvironment variable for custom plugin locations - Check built-in transformer documentation:
kustomize config help