Introduction
A ConfigMap stores non-sensitive configuration separately from a container image. This lets you reuse the same application image with different settings, such as development mode, logging level, feature flags, or endpoint names.
In this lab, you will create a ConfigMap, inspect its data, use it to configure a Pod, update the ConfigMap, and recreate the Pod to pick up the new values. Later labs will go deeper into specific environment variable wiring and mounted configuration files; this lab focuses on the ConfigMap object and the core application configuration workflow.
Prepare a ConfigMap Namespace
In this step, you will prepare a clean namespace for ConfigMap practice.
Start in /home/labex/project. You will write one Pod manifest in this directory.
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 before creating application objects.
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-configmaps:
kubectl create namespace ckad-prep-configmaps
Set this namespace as the current context namespace:
kubectl config set-context --current --namespace=ckad-prep-configmaps
Confirm the current namespace:
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
Expected output:
ckad-prep-configmaps
Create and Inspect a ConfigMap
In this step, you will create a ConfigMap that holds simple application settings.
The kubectl create configmap command can create a ConfigMap directly from literal key-value pairs. Each --from-literal flag adds one entry under the ConfigMap's data field.
kubectl create configmap app-settings \
--from-literal=APP_MODE=dev \
--from-literal=LOG_LEVEL=debug \
--from-literal=FEATURE_BANNER=enabled
Expected output:
configmap/app-settings created
Inspect the ConfigMap summary:
kubectl get configmap app-settings
Expected output:
NAME DATA AGE
app-settings 3 ...
Read the stored values. jsonpath prints selected fields without showing the full object.
kubectl get configmap app-settings -o 'jsonpath={.data.APP_MODE}{" "}{.data.LOG_LEVEL}{" "}{.data.FEATURE_BANNER}{"\n"}'
Expected output:
dev debug enabled
You can also view the ConfigMap as YAML to see where the keys live in the object.
kubectl get configmap app-settings -o yaml
Expected output includes:
data:
APP_MODE: dev
FEATURE_BANNER: enabled
LOG_LEVEL: debug
Configure a Pod from the ConfigMap
In this step, you will start a Pod that reads the ConfigMap values as environment variables.
The envFrom.configMapRef field imports all keys from a ConfigMap into the container environment. This is a compact way to connect a small set of non-sensitive settings to an application.
Create config-reader-pod.yaml:
cat > config-reader-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: config-reader
labels:
app: config-reader
spec:
terminationGracePeriodSeconds: 0
containers:
- name: reader
image: busybox:1.36
command:
- /bin/sh
- -c
- 'echo mode=${APP_MODE}; echo level=${LOG_LEVEL}; echo banner=${FEATURE_BANNER}; sleep 3600'
envFrom:
- configMapRef:
name: app-settings
EOF
Apply the Pod manifest:
kubectl apply -f config-reader-pod.yaml
Expected output:
pod/config-reader created
Wait until the Pod is Ready:
kubectl wait --for=condition=Ready pod/config-reader --timeout=120s
Expected output:
pod/config-reader condition met
Read the Pod logs. The application prints values that came from the ConfigMap.
kubectl logs config-reader -c reader
Expected output:
mode=dev
level=debug
banner=enabled
Update the ConfigMap and Recreate the Pod
In this step, you will update the ConfigMap and recreate the Pod so the container receives the new values.
When a ConfigMap is used as environment variables, the running container does not automatically change its environment. A new container must start to read the updated values. This is an important CKAD detail because you may need to update configuration and then restart or recreate the workload.
Patch the ConfigMap:
kubectl patch configmap app-settings --type merge --patch '{"data":{"APP_MODE":"prod","LOG_LEVEL":"warn","FEATURE_BANNER":"disabled"}}'
Expected output:
configmap/app-settings patched
Confirm the new ConfigMap values:
kubectl get configmap app-settings -o 'jsonpath={.data.APP_MODE}{" "}{.data.LOG_LEVEL}{" "}{.data.FEATURE_BANNER}{"\n"}'
Expected output:
prod warn disabled
Delete the old Pod:
kubectl delete pod config-reader
Expected output includes:
pod "config-reader" deleted
Recreate the Pod from the same manifest and wait until it is Ready:
kubectl apply -f config-reader-pod.yaml
kubectl wait --for=condition=Ready pod/config-reader --timeout=120s
Expected output:
pod/config-reader created
pod/config-reader condition met
Read the logs again. The new Pod now sees the updated ConfigMap values.
kubectl logs config-reader -c reader
Expected output:
mode=prod
level=warn
banner=disabled
Summary
You created a ConfigMap, inspected its data, connected it to an application Pod, updated the ConfigMap, and recreated the Pod so the container picked up the new values. This gives you the core ConfigMap workflow before moving into more detailed environment variable and file-mount patterns in later labs.


