Kustomize Reference: Overlays, Patches, ConfigMapGenerator & ArgoCD GitOps
Kustomize is built into kubectl (since 1.14) and lets you manage Kubernetes manifests across environments without templating — using patches, overlays, and generators.
1. Kustomize vs Helm
When to use Kustomize, when to use Helm
| Kustomize | Helm | |
|---|---|---|
| Approach | Overlays and patches (no templating) | Go templates + values files |
| Learning curve | Low — it’s just YAML | Medium — template syntax, hooks |
| Multiple environments | Overlays (base + prod/staging) | Values files per environment |
| Third-party apps | Patch existing manifests | Install charts from registries |
| Secrets | SecretGenerator (SOPS integration) | Helm secrets plugin |
| GitOps (ArgoCD/Flux) | Native support, no extra step | Native support |
| Best for | Your own apps, internal tools | Third-party software (databases, monitoring) |
# Rule of thumb: # Kustomize = your own apps across environments (base + overlays) # Helm = installing third-party software from a chart registry # They're complementary — many teams use both
2. Directory Structure
Base + overlay pattern — the standard layout
k8s/
├── base/
│ ├── kustomization.yaml # base resources
│ ├── deployment.yaml
│ ├── service.yaml
│ └── configmap.yaml
└── overlays/
├── staging/
│ ├── kustomization.yaml # extends base
│ └── patch-replicas.yaml # staging-specific patches
└── production/
├── kustomization.yaml
├── patch-replicas.yaml
└── patch-resources.yaml
# base/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
- configmap.yaml
# overlays/production/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base # extend the base
namePrefix: prod- # prefix all resource names
namespace: production
commonLabels:
environment: production
patches:
- path: patch-replicas.yaml
- path: patch-resources.yaml
# Build and apply:
kubectl kustomize overlays/production | kubectl apply -f -
# Or (equivalent, but deploys directly):
kubectl apply -k overlays/production
3. Patches
Strategic merge patch, JSON patch, and inline patches
# Strategic Merge Patch (most readable):
# patch-replicas.yaml — only changes replicas, everything else from base is preserved
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app # must match the base Deployment name
spec:
replicas: 5 # override to 5 in production
# JSON 6902 Patch (surgical changes by path):
# kustomization.yaml:
patches:
- target:
kind: Deployment
name: my-app
patch: |-
- op: replace
path: /spec/replicas
value: 5
- op: add
path: /spec/template/spec/containers/0/env/-
value:
name: ENVIRONMENT
value: production
- op: remove
path: /spec/template/spec/containers/0/resources/limits/cpu
# Inline patch (no separate file):
patches:
- target:
kind: Deployment
name: my-app
patch: |
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: my-app
image: my-app:production-tag
resources:
limits:
memory: "1Gi"
requests:
memory: "512Mi"
4. Images — No Templating Needed
Override image tags per environment without string substitution
# In overlays/production/kustomization.yaml:
images:
- name: my-app # image name in base manifest
newTag: "1.4.0" # pin to specific tag
- name: nginx
newTag: "1.25.4-alpine"
- name: my-app
newName: gcr.io/my-project/my-app # change registry too
newTag: "${IMAGE_TAG}" # CI/CD can set this with kustomize edit
# In CI/CD (set tag without editing files manually):
kustomize edit set image my-app=my-app:${GIT_SHA}
# Full CI/CD pattern:
# 1. Build + push image with SHA tag
# 2. kustomize edit set image my-app=registry.io/my-app:${GIT_SHA}
# 3. git commit + push (triggers ArgoCD/Flux sync)
kustomize edit set image my-app=registry.io/my-app:${GIT_SHA}
git add k8s/overlays/production/kustomization.yaml
git commit -m "ci: deploy ${GIT_SHA}"
5. ConfigMapGenerator & SecretGenerator
Auto-roll deployments when config changes
# ConfigMapGenerator — creates ConfigMap from files or literals
# AND appends a content hash to the name (e.g., my-config-5c8hb97g)
# This forces a rolling Deployment restart when config changes!
# kustomization.yaml:
configMapGenerator:
- name: my-app-config
files:
- config.properties # file in same directory
literals:
- LOG_LEVEL=info
- MAX_POOL_SIZE=10
# Deployment auto-references by base name, Kustomize resolves the hash:
spec:
containers:
- envFrom:
- configMapRef:
name: my-app-config # Kustomize replaces with my-app-config-XXXX
# SecretGenerator (base64 encoding handled automatically):
secretGenerator:
- name: my-app-secrets
literals:
- DB_PASSWORD=mysecret
type: Opaque
- name: tls-cert
files:
- tls.crt
- tls.key
type: kubernetes.io/tls
# For production: use SOPS encryption
# Store encrypted secrets in git, kustomize-controller decrypts on-cluster
# Or use External Secrets Operator to fetch from Vault/AWS SM
kubectl rollout restart after config changes.6. Components & ArgoCD Integration
Reusable components and GitOps patterns
# Kustomize Components (Kustomize 4.1+) — reusable feature modules
# components/monitoring/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
resources:
- servicemonitor.yaml
patches:
- path: add-prometheus-annotations.yaml
# Include optional components in overlay:
# overlays/production/kustomization.yaml:
components:
- ../../components/monitoring # opt-in monitoring for production
- ../../components/network-policy
# ArgoCD Application pointing to Kustomize overlay:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app-production
spec:
source:
repoURL: https://github.com/myorg/my-app
path: k8s/overlays/production # Kustomize overlay path
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated: {prune: true, selfHeal: true}
# ArgoCD auto-detects kustomization.yaml and runs kustomize build
# Build + validate locally:
kustomize build overlays/production # render final YAML
kustomize build overlays/production | kubectl apply --dry-run=server -f - # server-side validate
kubectl kustomize overlays/production # built-in kubectl version
Track Kubernetes and Kustomize version compatibility.
ReleaseRun monitors releases for Kubernetes, Docker, Helm, ArgoCD, and 13+ technologies.
Related: Helm Reference | ArgoCD & GitOps Reference | Kubernetes YAML Reference
🔍 Free tool: K8s YAML Security Linter — after kustomize build, paste the output here to check 12 K8s security misconfigurations before applying.
Founded
2023 in London, UK
Contact
hello@releaserun.com