You need dev, staging and prod variants of the same manifests without copy-pasting them.
Kustomize builds manifests from a kustomization.yaml without templates: the YAML stays valid Kubernetes YAML, and changes are layered on top. It is built into kubectl (kubectl apply -k dir/, kubectl kustomize dir/ to print the result).
The usual layout is a base with the shared manifests and an overlay per environment that references it:
resources: files or directories to include (an overlay lists the base).namespace,namePrefix/nameSuffix,labels: applied to everything.images: change image names or tags without touching the Deployment.replicas: change replica counts.patches: strategic-merge or JSON 6902 patches for anything else.configMapGenerator/secretGenerator: build ConfigMaps from files or literals, adding a content hash to the name and updating references, so a config change triggers a rolling update automatically.
Kustomize versus Helm: Kustomize is great for your own apps' environment differences and for patching third-party YAML; Helm is better for distributing configurable packages to others. Many teams use both, for example applying a Kustomize patch on top of a rendered Helm chart.
CI pipelines and GitOps tools (Argo CD, Flux) understand Kustomize directories natively.
Example
# base/kustomization.yaml
resources: [deployment.yaml, service.yaml]
# overlays/prod/kustomization.yaml
resources: [../../base]
namespace: shop-prod
images:
- name: ghcr.io/acme/web
newTag: "1.5.0"
replicas:
- {name: web, count: 6}
configMapGenerator:
- name: web-config
literals: [LOG_LEVEL=warn]
patches:
- target: {kind: Deployment, name: web}
patch: |-
- op: add
path: /spec/template/spec/containers/0/resources
value: {requests: {cpu: 500m, memory: 1Gi}}
# kubectl kustomize overlays/prod | less ; kubectl apply -k overlays/prodRemember
- Base plus per-environment overlays, no templating
- images, replicas, patches and generators cover most changes
- Generated ConfigMaps get a hash suffix, so changes roll pods
Watch out for
- Copying the whole base into each environment instead of patching only the differences.