Plain YAML customization: no templating; patch-based overlays. Built into kubectl (kubectl apply -k).
- Structure: base/ (shared) + overlays/ (env-specific patches)
kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
namePrefix: prod-
commonLabels:
env: production
commonAnnotations:
team: platform
images:
- name: nginx
newTag: "1.26"
- name: myapp
newName: registry.io/myapp
newTag: "2.0"
patches:
- path: patch-replicas.yaml
- patch: |
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 5
JSON 6902 patch (precise field targeting)
patches:
- target:
kind: Deployment
name: webapp
patch: |
- op: replace
path: /spec/replicas
value: 5
- op: add
path: /spec/template/spec/containers/0/env/-
value:
name: ENV
value: production
Bases and overlays
resources:
- ../../base
- grafana-depl.yaml
namespace: dev
namePrefix: dev-
configMapGenerator and secretGenerator
configMapGenerator:
- name: app-config
literals:
- DB_HOST=mysql
- DB_PORT=3306
files:
- app.properties
secretGenerator:
- name: db-secret
literals:
- password=s3cr3t
- Generated name:
app-config-<hash>; reference by base name; Kustomize rewrites refs automatically - Suppress hash (not recommended):
options: {disableNameSuffixHash: true}
Commands
kustomize build k8s/overlays/dev
Helm vs Kustomize
Exam gotchas
- Every kustomize dir needs
kustomization.yaml - Overlay references base via
resources: - ../../base images transformer changes tags without editing deployment YAMLconfigMapGenerator / secretGenerator appends hash: reference by base name- Strategic merge patch: specify only what changes; K8s merges with existing spec
- JSON 6902: precise op-based (add/replace/remove); use strategic merge for most exam scenarios