Introduction
Helm packages Kubernetes templates as releases. Kustomize takes a different approach: it starts from ordinary Kubernetes YAML and layers changes on top without using template expressions. This is useful when you want a shared base and small environment-specific differences such as names, namespaces, replica counts, or patches.
In this lab, you will create a base Deployment and Service, render that base with Kustomize, then create a production overlay that changes the name, namespace, replica count, and application message. Finally, you will deploy the overlay with kubectl apply -k and test the resulting Service.
Prepare a Kustomize Workspace
In this step, you will prepare a namespace and confirm that Kustomize support is available through kubectl.
Start in /home/labex/project. This lab keeps the base manifests and overlay files in this workspace.
mkdir -p /home/labex/project
cd /home/labex/project
Check that the Kubernetes API server is reachable. If the VM has just started and the node is not ready yet, wait a few seconds and run the command again.
kubectl get nodes --request-timeout=5s
Expected output includes:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
Wait until the cluster networking Pod is Ready. You will test a Service at the end of the lab, so cluster networking needs to be healthy.
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
Expected output:
pod/calico-node-... condition met
Create a namespace named ckad-prep-kustomize and set it as the current namespace:
kubectl create namespace ckad-prep-kustomize
kubectl config set-context --current --namespace=ckad-prep-kustomize
Confirm the namespace and check that kubectl kustomize is available. kubectl kustomize renders Kustomize directories without applying them.
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
kubectl kustomize --help | sed -n '1,3p'
Expected output includes:
ckad-prep-kustomize
Build a set of KRM resources...
Create a Reusable Base
In this step, you will create a Kustomize base from ordinary Kubernetes YAML.
A base is the shared starting point. It should contain complete, valid Kubernetes objects before any environment-specific customization is added. Here the base contains one Deployment and one Service. The application writes the value of the MESSAGE environment variable into a small web page.
Create the base directory:
mkdir -p kustomize-demo/base
Write the base Deployment:
cat > kustomize-demo/base/deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: kustomize-web
labels:
app: kustomize-web
spec:
replicas: 1
selector:
matchLabels:
app: kustomize-web
template:
metadata:
labels:
app: kustomize-web
spec:
terminationGracePeriodSeconds: 0
containers:
- name: web
image: busybox:1.36
env:
- name: MESSAGE
value: base-v1
command:
- /bin/sh
- -c
- |
mkdir -p /www
echo "$MESSAGE" > /www/index.html
httpd -f -p 8080 -h /www
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 1
periodSeconds: 2
EOF
Write the base Service. Its selector matches the Pod label from the Deployment.
cat > kustomize-demo/base/service.yaml <<'EOF'
apiVersion: v1
kind: Service
metadata:
name: kustomize-web
spec:
selector:
app: kustomize-web
ports:
- port: 80
targetPort: 8080
EOF
Create the base kustomization.yaml. This file tells Kustomize which resources belong to the base.
cat > kustomize-demo/base/kustomization.yaml <<'EOF'
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
EOF
Render the base without applying it:
kubectl kustomize kustomize-demo/base | sed -n '1,120p'
Expected output includes a Service named kustomize-web, a Deployment named kustomize-web, replicas: 1, and value: base-v1.
Add a Production Overlay
In this step, you will create an overlay that customizes the base for a production-style deployment.
An overlay points to a base and then adds changes. This overlay will put the objects in ckad-prep-kustomize, add the prod- name prefix, scale the Deployment to three replicas, and patch the MESSAGE value to prod-v2.
Create the overlay directory:
mkdir -p kustomize-demo/overlays/prod
Write a Deployment patch. The patch names the original base object, kustomize-web. Kustomize matches the patch before it adds the prod- prefix.
cat > kustomize-demo/overlays/prod/deployment-patch.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: kustomize-web
spec:
replicas: 3
template:
spec:
containers:
- name: web
env:
- name: MESSAGE
value: prod-v2
EOF
Create the overlay kustomization.yaml. The resources entry points back to the base, while namespace, namePrefix, and patches describe the customization.
cat > kustomize-demo/overlays/prod/kustomization.yaml <<'EOF'
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: ckad-prep-kustomize
namePrefix: prod-
resources:
- ../../base
patches:
- path: deployment-patch.yaml
EOF
Render the production overlay:
kubectl kustomize kustomize-demo/overlays/prod | sed -n '1,160p'
Expected output includes:
name: prod-kustomize-web
namespace: ckad-prep-kustomize
replicas: 3
value: prod-v2
Deploy and Test the Customized Application
In this step, you will apply the production overlay and test the Service it creates.
The command kubectl apply -k renders a Kustomize directory and sends the rendered objects to the Kubernetes API server. You do not need to create a temporary YAML file.
Apply the production overlay:
kubectl apply -k kustomize-demo/overlays/prod
Expected output includes:
service/prod-kustomize-web created
deployment.apps/prod-kustomize-web created
Wait for the customized Deployment:
kubectl rollout status deployment/prod-kustomize-web --timeout=120s
Expected output:
deployment "prod-kustomize-web" successfully rolled out
Inspect the objects created from the overlay:
kubectl get deployment,service prod-kustomize-web
Expected output includes:
deployment.apps/prod-kustomize-web 3/3
service/prod-kustomize-web
Create a client Pod and test the Service. The response should be prod-v2, which proves that the overlay patch changed the running application configuration.
kubectl run kustomize-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --for=condition=Ready pod/kustomize-client --timeout=120s
kubectl exec kustomize-client -- wget -qO- http://prod-kustomize-web
Expected output:
prod-v2
Summary
You built a Kustomize base from ordinary Deployment and Service YAML, then created a production overlay that changed the namespace, object names, replica count, and application message. You rendered both the base and overlay before applying the overlay with kubectl apply -k, then verified the customized application through its Service.


