Back to Blog

Helm & Kustomize for the CKAD Exam: Deploying Your Application Across Environments

A developer's guide to Helm and Kustomize for the CKAD exam — Kustomize bases and overlays, kustomize edit set image, kubectl apply -k, installing and upgrading Helm releases, overriding values with --set and -f, helm template to inspect before apply, and the exam tasks that actually appear.

By Sailor Team , September 9, 2026

Most CKAD candidates learn to write a Deployment YAML by hand and stop there. But the exam’s Application Deployment domain expects more than raw manifests — it expects you to package and ship the same application into different environments without copy-pasting YAML and hand-editing image tags. That is exactly the problem Helm and Kustomize solve, and both are named tools on the current CKAD curriculum.

This guide takes a developer’s view of the two tools for the CKAD exam. We won’t rebuild your app from scratch — you already know how to write a Pod spec. Instead we’ll focus on the workflow the exam tests: take an application you own, and use Kustomize overlays or a Helm chart to deploy it to dev, staging, and prod, changing only what needs to change per environment. If you also sit the CKA, the CKA Helm & Kustomize guide is the cluster-admin companion to this page — same tools, more of an operator’s angle.

Why a Developer Needs Helm or Kustomize

Imagine your app is a Deployment plus a Service plus a ConfigMap. It runs fine in dev. Now you need it in staging with 3 replicas, a different image tag, and a staging- name prefix, and in prod with 6 replicas and a production database URL. The naive approach — three near-identical copies of the same YAML — rots immediately: a fix in one copy silently drifts from the others.

Kustomize and Helm both eliminate that duplication, using opposite philosophies:

ToolCore ideaYou write…You get…
KustomizeOverlay patches on a shared basePlain YAML + small patchesMerged plain YAML — no templating language
HelmTemplate + valuesA chart with {{ }} placeholdersRendered YAML from a values file

Kustomize is template-free: everything is valid Kubernetes YAML that gets layered. Helm is a package manager: a chart is parameterized and you fill in the blanks. Both are built to answer the same question — “how do I run this one application in many places?” The exam rewards knowing which levers each tool exposes and how to pull them quickly.

Kustomize Fundamentals: Base + Overlays

Kustomize is built into kubectl (kubectl apply -k, kubectl kustomize), so on the exam there is nothing to install. The unit of a Kustomize project is a directory containing a kustomization.yaml file.

A base holds the resources common to every environment:

app/
├── base/
│   ├── kustomization.yaml
│   ├── deployment.yaml
│   └── service.yaml
└── overlays/
    ├── staging/
    │   └── kustomization.yaml
    └── prod/
        └── kustomization.yaml

The base kustomization.yaml simply lists its resources:

# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml
  - service.yaml

An overlay references the base and applies environment-specific changes on top:

# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
namePrefix: prod-
namespace: production
commonLabels:
  environment: prod
replicas:
  - name: web
    count: 6
images:
  - name: myorg/web
    newTag: "2.4.1"

That one overlay renames everything with a prod- prefix, drops it into the production namespace, stamps an environment: prod label on every resource, scales the web Deployment to 6, and pins the image tag — all without touching the base. The staging overlay does the same with different numbers. The base never changes.

The fields the exam actually uses

You do not need every Kustomize transformer. These are the ones worth committing to muscle memory:

FieldEffect
resourcesFiles or directories (including other bases) to include
namePrefix / nameSuffixPrepend/append to every resource name
namespaceForce all resources into one namespace
commonLabelsAdd labels to every resource and to selectors
commonAnnotationsAdd annotations to every resource
imagesOverride image name/tag without editing the Deployment
replicasOverride replica counts by resource name
configMapGeneratorGenerate a ConfigMap (with a content hash suffix)
patchesStrategic-merge or JSON 6902 patches for anything else

commonLabels deserves a warning: because it also rewrites label selectors, changing it on a live Deployment can produce an immutable-selector error. Prefer commonLabels for values fixed at creation (like environment) and use labels (metadata-only) or annotations for things that change later.

Applying and Inspecting Kustomize

Two commands cover the exam:

# Render the merged YAML to stdout — inspect before you touch the cluster
kubectl kustomize overlays/prod

# Build AND apply in one step
kubectl apply -k overlays/prod

Always kubectl kustomize first when a task says “verify” or “review” — you can eyeball the prefix, replica count, and image tag before applying. To remove what an overlay created, kubectl delete -k overlays/prod.

kustomize edit set image — a real developer task

A classic exam-style instruction is “update the web Deployment to use image myorg/web:2.5.0.” If the standalone kustomize binary is present you can do this without opening an editor:

cd overlays/prod
kustomize edit set image myorg/web=myorg/web:2.5.0
kubectl apply -k .

kustomize edit set image rewrites the images: block for you. If only kubectl is available, add or edit the images: entry in kustomization.yaml by hand — the effect is identical. Either way, the point the exam is testing is that you bump an image through the overlay, not by editing the base Deployment.

configMapGenerator and the hash suffix

Kustomize can build a ConfigMap from literals or files and append a content hash to its name:

configMapGenerator:
  - name: web-config
    literals:
      - LOG_LEVEL=info
      - FEATURE_X=true

The generated name becomes something like web-config-8t2hk6c9fd, and Kustomize automatically rewrites every reference to it in your Deployment. The payoff: when the config content changes, the hash changes, the Deployment’s pod template changes, and a rollout is triggered — so config changes actually redeploy your pods instead of silently sitting unused. If you need a stable name, set generatorOptions: { disableNameSuffixHash: true }.

Helm Fundamentals: Charts, Releases & Values

Helm approaches the same problem as a package manager. Three terms carry the exam weight:

  • Chart — a packaged, templated application (a directory or .tgz of templates + a values.yaml).
  • Release — a specific installation of a chart into a cluster, with a name (helm install web ./chart creates the web release).
  • Repository — a place charts are hosted and pulled from.

A chart directory looks like this:

mychart/
├── Chart.yaml        # name, version, appVersion
├── values.yaml       # default values
└── templates/
    ├── deployment.yaml   # uses {{ .Values.image.tag }}
    └── service.yaml

Inside a template, values are interpolated with Go templating:

spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
        - name: web
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

For CKAD you are far more likely to consume and configure a chart than author one, so focus your practice on the lifecycle commands and value overrides.

The Helm lifecycle commands

# Install a chart as a named release
helm install web ./mychart

# See what's installed
helm list

# Change configuration / upgrade to a new chart version
helm upgrade web ./mychart --set image.tag=2.5.0

# Undo — roll back to the previous revision
helm rollback web 1

# Remove the release entirely
helm uninstall web

helm upgrade is idempotent and revision-tracked: every install/upgrade bumps a revision number, and helm rollback <release> <revision> returns to an earlier one. That revision history is Helm’s built-in answer to “undo my last change,” and it’s worth mentioning when a task asks you to revert.

Overriding Helm Values

This is where per-environment configuration lives, and it’s the Helm skill the exam most reliably probes. Two mechanisms, and you can combine them:

# Inline overrides (highest priority) — great for one or two values
helm install web ./mychart --set replicaCount=6 --set image.tag=2.5.0

# A values file — best for many environment-specific settings
helm install web ./mychart -f values-prod.yaml

Precedence runs from lowest to highest: the chart’s own values.yaml → any -f files (in order) → --set flags. So --set always wins over a values file, which always wins over the chart defaults. For nested values, --set uses dotted paths (--set image.tag=2.5.0); for lists, use brackets (--set ports[0]=8080).

Inspect before you apply

Just as kubectl kustomize renders Kustomize output, Helm can render a chart without touching the cluster:

# Render templates locally with your overrides — nothing is installed
helm template web ./mychart -f values-prod.yaml

# Simulate an install server-side and show what would change
helm install web ./mychart --dry-run --debug

Use helm template when a task asks you to verify the generated manifests, and --dry-run when you want the API server’s opinion (including validation) before committing. Reading the rendered output is the single fastest way to confirm your --set flags landed where you expected.

Helm vs Kustomize: Which for What

SituationReach for
Deploying a third-party app someone already packagedHelm (install the chart)
Small per-environment tweaks to YAML you ownKustomize (an overlay)
You want zero templating language, just layered YAMLKustomize
You need versioned releases with rollback and reposHelm
Bumping just an image tag across environmentsEither — kustomize edit set image or --set image.tag

They are not mutually exclusive: a common real-world pattern is to helm template a chart and pipe it through Kustomize for last-mile patches. On the exam, though, a task will point you at one or the other — the giveaway is whether you’re handed a kustomization.yaml/overlay directory (Kustomize) or a chart directory / repo reference (Helm).

Exam-Day Workflow & Speed Tips

  • Read what you were given. A kustomization.yaml in the question directory means Kustomize; a Chart.yaml or a helm repo add hint means Helm. Don’t hand-edit Deployments when the task clearly wants an overlay or a value override.
  • Inspect, then apply. kubectl kustomize <dir> and helm template <release> <chart> are read-only and fast. Confirm the change is present before you apply, so you’re not debugging a live cluster.
  • Bump images through the tool, not the base. Use kustomize edit set image or helm upgrade --set image.tag=.... Editing the base Deployment defeats the point and can cost you the mark.
  • Know your rollback. For Helm, helm rollback <release> <revision> after helm history <release>. For Kustomize, re-apply the previous overlay state.
  • Namespaces matter. Kustomize overlays often set namespace:; Helm installs take -n <namespace>. Verify with kubectl get all -n <ns> after applying.

Common Pitfalls

  • Editing the base instead of the overlay. Every environment inherits the base — change it and you change all of them. Environment-specific tweaks belong in the overlay.
  • Forgetting -k / kubectl kustomize vs plain -f. kubectl apply -f kustomization.yaml does not run Kustomize; you need -k <dir> or kubectl kustomize <dir>.
  • --set type surprises. --set replicaCount=6 is fine, but quoted numbers or booleans can render as strings; use helm template to confirm the rendered type.
  • commonLabels on a running Deployment. Selectors are immutable — adding commonLabels after creation can fail. Decide on those labels up front.
  • Assuming config edits redeploy. A plain ConfigMap edit does not restart pods. configMapGenerator’s hash suffix (Kustomize) or bumping a value that lands in the pod template (Helm) is what forces the rollout.

Practice in Realistic Exam Conditions

Helm and Kustomize are muscle-memory topics: the commands are short, but under a two-hour clock you need them to be automatic. Reading about kubectl apply -k is not the same as scaffolding a base, writing a prod overlay, bumping an image, and verifying the result against a live cluster with the timer running.

The Certified Kubernetes Application Developer (CKAD) Mock Exam Bundle gives you five full-length, performance-based mock exams in a browser terminal against a real Kubernetes cluster — the same hands-on format as exam day — with Application Deployment tasks (overlays, image bumps, release upgrades and rollbacks) among the scenarios. Pair it with the 30-day CKAD study plan to sequence deployment tooling alongside the rest of the syllabus, and skim the CKAD exam domains breakdown to see how Application Deployment is weighted against Design and Build, Observability, and the rest.

Conclusion

For the CKAD, Helm and Kustomize are about one skill: shipping the same application into different environments without duplicating YAML. Kustomize layers plain YAML — a base plus overlays that set prefixes, namespaces, replica counts, and image tags. Helm parameterizes a chart and installs it as a versioned release you can upgrade and rollback, with --set and -f for per-environment values. Learn to inspect before you apply (kubectl kustomize, helm template), bump images through the tool rather than the base, and recognize from the files you’re given which tool the task wants. Drill those flows on a live cluster and the Application Deployment questions become some of the fastest points on the exam.

For adjacent topics, review Deployments, rolling updates & rollbacks, building container images (the image your chart or overlay ships), ConfigMaps & Secrets (what configMapGenerator and chart values feed into), and blue/green & canary strategies. Keep the CKAD kubectl cheat sheet close for the apply/inspect commands.

Frequently Asked Questions

Are Helm and Kustomize really on the CKAD exam?

Yes. The Application Deployment domain of the current CKAD curriculum names both — using Kustomize to manage and dynamically update resources, and understanding Helm to deploy packaged applications. Expect tasks that hand you an overlay or a chart and ask you to configure and apply it.

Do I need to install Kustomize separately?

No. Kustomize is built into kubectl as kubectl apply -k and kubectl kustomize. The standalone kustomize binary adds conveniences like kustomize edit set image, but you can achieve the same result by editing kustomization.yaml directly.

How do I change an image tag with each tool?

With Kustomize, set it in the overlay’s images: block (or run kustomize edit set image name=name:tag) and kubectl apply -k. With Helm, helm upgrade <release> <chart> --set image.tag=<tag> (assuming the chart wires that value into the container image).

How do I undo a bad Helm change?

helm history <release> shows the revisions, then helm rollback <release> <revision> returns to an earlier one. Helm tracks every install and upgrade as a numbered revision, so rollback is a first-class operation.

Should I render output before applying?

Yes — it’s the fastest way to catch mistakes. kubectl kustomize <dir> and helm template <release> <chart> render the final YAML locally without touching the cluster, so you can confirm your prefixes, replica counts, and value overrides landed correctly before you apply.

Helm or Kustomize — which should I learn first for CKAD?

Learn Kustomize first: it’s built into kubectl, has no templating language, and its base/overlay model maps directly to the “deploy across environments” tasks the exam favors. Then add Helm’s install/upgrade/rollback and value-override flow.

Limited Time Offer: Get 80% off all Mock Exam Bundles | Sale ends in 7 days. Start learning today.

Claim Now