Kustomize: bases, overlays and patches
Adjust plain YAML for each environment without copying it: a base holds the manifests and an overlay lists the changes.
Key ideas in this lesson · tap one for a simple explanation
What you will be able to do
- Write an overlay that changes the namespace, name prefix, labels, image tag and replica count, without touching the base.
- Change any field with a patch, and choose between a strategic merge patch and a JSON 6902 patch.
- Generate a ConfigMap, explain the hash in its name, and build, compare, apply and delete with -k.
lets you keep one set of files and adjust it for each environment. Example: your Django app runs 1 replica in dev and 3 in prod, each in its own . Instead of two copies of every file, you keep one base. Then you write a small overlay for each environment that lists only the differences.
Kustomize is built into , so it is already in the exam terminal. There are no templates: the base is plain YAML that works on its own. Exam tasks usually give you a base and ask for an overlay, or give you an overlay that does not build.
Base
plain YAML, shared by every environment
base/
Overlay
the changes for one environment
overlays/prod/
kubectl apply -k
builds the result and applies it
Live objects
prod-api in shop-prod, 3 replicas
The overlay points at the base and lists its changes. kubectl builds the final YAML and applies it. The base files never change.
A base and an overlay
The base and each overlay are folders, each with a file called kustomization.yaml. The base's file just lists its . An overlay's file points at the base and says what to change. Here is a production overlay:
# Layout:
# app/base/kustomization.yaml resources: [deployment.yaml, service.yaml]
# app/overlays/dev/kustomization.yaml resources: [../../base]
# app/overlays/prod/kustomization.yaml this file
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
- namespace.yaml # apiVersion: v1, kind: Namespace, metadata.name: shop-prod
namespace: shop-prod
namePrefix: prod-
labels:
- pairs:
env: prod
includeTemplates: true # label the Pods too, leave selectors alone
images:
- name: nginx # every container whose image is nginx:<anything>
newTag: "1.27"
replicas:
- name: api # the base name, before the prefix
count: 3Always look at the result before you apply it. -k takes a kustomization folder, where -f takes a file:
kubectl kustomize app/overlays/prod # print the result, change nothing
kubectl kustomize app/overlays/prod | grep -nE 'name:|namespace:|image:|replicas:'
kubectl diff -k app/overlays/prod # what would change on the live cluster
kubectl apply -k app/overlays/prod
kubectl get -k app/overlays/prod # the live objects this overlay produces
kubectl delete -k app/overlays/prod
kubectl version --client # also prints the bundled Kustomize versionThe fields you will use most
Patches: change any field
When no simple field does the job, write a patch. Kustomize knows two kinds, and both go in the same patches list.
In a strategic merge patch, lists such as containers are merged by each item's name. So you can change one container without repeating the others. A JSON 6902 patch names no object, so it needs a target to say which one.
patches:
# Strategic merge: name the object, write only what changes
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
template:
spec:
containers:
- name: api # merged by container name
resources:
limits:
memory: 256Mi
# JSON 6902: operations need a target
- target:
kind: Service
name: api
patch: |-
- op: replace
path: /spec/type
value: NodePort
- op: add
path: /metadata/labels/exposed
value: "true"Generated ConfigMaps
Kustomize can also write ConfigMaps for you. You list the keys; it builds the ConfigMap and adds a hash of the content to its name, such as api-config-<hash>. secretGenerator builds the same way.
configMapGenerator:
- name: api-config
literals:
- MODE=production
- CACHE_TTL=300Kustomize rewrites every reference it knows to the hashed name: envFrom, valueFrom and volumes. (envFrom loads every key of a ConfigMap as environment variables; ConfigMaps and Secrets teaches it.) The hash is what makes a settings change roll out:
You change a value
in kustomization.yaml
MODE=debug
New hash, new name
a new ConfigMap
api-config-<new hash>
Pod template changes
it now points at the new name
New Pods
the Deployment rolls out
The old ConfigMap stays behind until you delete it.
In the official docs· open on exam day too
- Declarative Management of Kubernetes Objects Using Kustomizesearch: kustomize
- Managing Secrets using Kustomizesearch: secret kustomize
- kubectl kustomizesearch: kubectl kustomize
Build a production overlay
web is in /tmp/cka/kustomize/base. Without modifying the base, create an overlay in /tmp/cka/kustomize/overlays/prod that puts every resource in namespace arx-kust-prod (the overlay must create this namespace), prefixes all names with prod-, runs 3 replicas, changes the nginx image tag to 1.27, and adds the label env=prod to every resource. Apply the overlay with kubectl apply -k.Cluster:kubectl config use-context kind-cka
- 1
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/ar-kust-1/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/ar-kust-1/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 4
Clean up (optional)
curl -fsSL https://codewithmuh.com/labs/cka/t/ar-kust-1/cleanup | bash
Generated config and patches in a staging overlay
/tmp/cka/kustomize/base unchanged, create an overlay in /tmp/cka/kustomize/overlays/staging that deploys into the existing namespace arx-kust-staging and: generates a ConfigMap named web-config with the keys MODE=staging and LOG_LEVEL=debug; loads every key of that ConfigMap as environment variables into the web container; and changes the Service web to type NodePort. Keep the generated name hash. Apply the overlay with kubectl apply -k.Cluster:kubectl config use-context kind-cka
- 1
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/ar-kust-2/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/ar-kust-2/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 4
Clean up (optional)
curl -fsSL https://codewithmuh.com/labs/cka/t/ar-kust-2/cleanup | bash
Finished this lesson?
0 of 2 tasks passed. Your readiness counts tasks, so run them before you move on.