ConfigMaps and Secrets are tested on every CKAD exam, often inside multiple questions. They sit at the intersection of application configuration, security, and pod design — three areas the exam weighs heavily. The mechanics are simple, but the variants (env vars vs volumes vs projected volumes, subPath mounts, immutable configs) trip up candidates who haven’t drilled them.
This guide covers every ConfigMap and Secret pattern the CKAD tests, with copy-paste commands and YAML you can adapt in seconds. By the end, you’ll know exactly which command to run for each variant.
ConfigMaps: Five Ways to Create One
The CKAD tests creating ConfigMaps from many sources. Memorize all five — questions vary the source.
1. From Literals
kubectl create cm app-config \
--from-literal=APP_ENV=prod \
--from-literal=APP_DEBUG=false \
--from-literal=APP_PORT=8080
Use this for a handful of small key-value pairs.
2. From a Single File (file content as a value)
kubectl create cm app-config --from-file=config.properties
The key is the filename (config.properties); the value is the file’s full contents. To override the key:
kubectl create cm app-config --from-file=app=config.properties
# Now the key is "app", not "config.properties"
3. From a Directory (each file becomes a key)
kubectl create cm app-config --from-file=./configs/
Every file in ./configs/ becomes a key in the ConfigMap. Useful when the question says “load these N config files into a ConfigMap.”
4. From an Env-File (KEY=VALUE per line)
# app.env contains:
# APP_ENV=prod
# APP_DEBUG=false
kubectl create cm app-config --from-env-file=app.env
Each line in the env-file becomes a separate key. This is faster than five --from-literal flags when the question gives you many vars.
5. From YAML
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: prod
APP_DEBUG: "false"
config.properties: |
db.host=db.svc
db.port=5432
The | literal block lets you embed multiline files inline. Numbers and booleans must be quoted as strings.
Secrets: Same Five Methods, with One Twist
Secrets work like ConfigMaps but Kubernetes base64-encodes the values. The CKAD doesn’t test you on the encoding — you supply plain values, and Kubernetes encodes them.
From Literals (most common on the exam)
kubectl create secret generic db-creds \
--from-literal=username=admin \
--from-literal=password=s3cretPass
TLS Secret
kubectl create secret tls my-tls --cert=tls.crt --key=tls.key
Docker Registry Secret
kubectl create secret docker-registry regcred \
--docker-server=registry.io \
--docker-username=user \
--docker-password=pass \
[email protected]
Reference it in a pod:
spec:
imagePullSecrets:
- name: regcred
Decoding a Secret to Verify
kubectl get secret db-creds -o jsonpath='{.data.password}' | base64 -d
echo
The echo adds a trailing newline so the output is readable. This is the fastest way to verify what’s actually in a Secret.
Three Ways to Consume Configuration in a Pod
This is where most CKAD questions live. Memorize the three patterns:
Pattern A: Single Env Var from a ConfigMap or Secret
spec:
containers:
- name: app
image: nginx
env:
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: app-config
key: APP_ENV
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-creds
key: password
Use this when only specific keys are needed in the env.
Pattern B: All Keys as Env Vars (envFrom)
spec:
containers:
- name: app
image: nginx
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: db-creds
Every key in the ConfigMap or Secret becomes an env var with the same name. Use this when the question says “expose all values as environment variables.”
Pattern C: Volume Mount
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: config
mountPath: /etc/app
- name: secrets
mountPath: /etc/secrets
readOnly: true
volumes:
- name: config
configMap:
name: app-config
- name: secrets
secret:
secretName: db-creds
Each key becomes a file at <mountPath>/<key>. The file’s content is the value. This is the right choice when the app reads config from files, not env vars.
SubPath Mounts (the Mount-A-Single-File Trick)
Mounting a ConfigMap directory hides any existing files at that path. To mount just one key as a single file (without overwriting the rest of the directory), use subPath:
volumeMounts:
- name: config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
This mounts only the nginx.conf key as the file at /etc/nginx/nginx.conf, leaving the rest of /etc/nginx/ untouched.
Trap: subPath mounts don’t auto-update when the ConfigMap changes. If a question says “config should update without redeploying,” don’t use subPath.
Setting File Permissions (Mode)
ConfigMaps and Secrets default to mode 0644. Some apps require stricter permissions (e.g., SSH keys at 0600):
volumes:
- name: ssh
secret:
secretName: ssh-key
defaultMode: 0400
Or per-key:
volumes:
- name: config
configMap:
name: app-config
items:
- key: app.conf
path: app.conf
mode: 0400
The CKAD occasionally tests this — recognize the trigger phrase “must be readable only by…”
Picking Specific Keys (items)
Sometimes you want only specific keys from a ConfigMap, not all of them:
volumes:
- name: config
configMap:
name: app-config
items:
- key: app.properties
path: app.properties
- key: nginx.conf
path: nginx/nginx.conf # custom path within the mount
This mounts only app.properties and nginx.conf, with the latter at a nested path.
Immutable ConfigMaps and Secrets
Marking a ConfigMap or Secret as immutable prevents updates and improves cluster performance. The 2026 CKAD curriculum may include this.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: prod
immutable: true
You cannot update an immutable ConfigMap — you must delete and recreate it.
Updating ConfigMaps Without Restarting Pods (and When You Can’t)
ConfigMaps mounted as volumes auto-update inside running pods (after a short delay) — except for subPath mounts. ConfigMaps consumed as env vars do not auto-update; the pod must be recreated.
Triggers in CKAD questions:
- “Update the config and have the pod see the new value without restarting” → mount as a volume, NOT subPath, NOT env var.
- “Update the config and make the change visible to the app” (no other constraints) → either approach works; volume mount is generally safer.
To force pods to pick up an env var change, restart the rollout:
kubectl rollout restart deploy <deployment>
Projected Volumes (Combine Multiple Sources in One Mount)
Projected volumes let you mount data from multiple ConfigMaps and Secrets under a single mount path. The 2026 CKAD curriculum lists this.
volumes:
- name: combined
projected:
sources:
- configMap:
name: app-config
- secret:
name: db-creds
- downwardAPI:
items:
- path: pod-name
fieldRef:
fieldPath: metadata.name
The mount will contain files from each source plus the pod’s name in pod-name. Useful when the question says “expose config and credentials in a single directory.”
Common ConfigMap and Secret Question Variants
Variant 1: Create a ConfigMap with Three Keys, Use Them as Env Vars
kubectl create cm app-config \
--from-literal=APP_ENV=prod \
--from-literal=APP_DEBUG=false \
--from-literal=APP_PORT=8080
# Then in the pod spec, use envFrom:
envFrom:
- configMapRef:
name: app-config
Variant 2: Mount a Secret as a File at a Specific Path
kubectl create secret generic api-key \
--from-literal=token=abcd1234
volumeMounts:
- name: api-key
mountPath: /etc/secrets/api-token
subPath: token
volumes:
- name: api-key
secret:
secretName: api-key
Variant 3: Pod with Both Env Vars (from Secret) and File (from ConfigMap)
spec:
containers:
- name: app
image: nginx
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-creds
key: password
volumeMounts:
- name: config
mountPath: /etc/app
volumes:
- name: config
configMap:
name: app-config
Variant 4: Update a ConfigMap Visible to a Running Pod
“Update
app-configso that keyLOG_LEVELisdebug. The pod must see the change without restarting.”
# Update the ConfigMap
kubectl edit cm app-config
# OR recreate (don't use this if it has many keys)
kubectl create cm app-config --from-literal=LOG_LEVEL=debug \
--dry-run=client -o yaml | kubectl apply -f -
The pod must consume the ConfigMap as a volume mount (no subPath, no env var). Changes propagate within ~60 seconds.
Verifying Your Work
After every ConfigMap or Secret task, verify:
# Inspect the resource
kubectl get cm app-config -o yaml
kubectl get secret db-creds -o yaml
# Check that the pod is consuming it
kubectl exec -it <pod> -- env | grep APP_
kubectl exec -it <pod> -- ls /etc/app
kubectl exec -it <pod> -- cat /etc/app/APP_ENV
The 30 seconds you spend verifying is the cheapest insurance on the exam.
Common Mistakes (and How to Avoid Them)
- Forgetting
genericfor non-TLS Secrets.kubectl create secret generic ...is the right command; withoutgeneric, it errors. - Quoting issues with literals containing special chars. Use single quotes:
--from-literal=password='p@ss!word'. - Mixing up env var name and key name. With
valueFrom.configMapKeyRef, the env var name is what you set inname; the ConfigMap key is inkey. They don’t have to match. - Using subPath when the question wants live updates. subPath mounts don’t auto-update.
- Putting
datavalues that aren’t strings without quoting. YAML will misinterpretfalseor123as a boolean/number unless quoted. - Forgetting
readOnly: trueon Secret mounts. Not strictly required, but common in production-style questions.
How to Practice This Topic
On a kind or kubeadm cluster, drill these scenarios under a 5-minute timer each:
- Create a ConfigMap from 4 literals, mount as env vars in a pod, verify with
kubectl exec. - Create a Secret from 2 literals, mount as a volume in a pod, verify file contents.
- Create a ConfigMap from a directory of 3 files, mount the whole directory in a pod.
- Create a ConfigMap, then update it and verify a running pod sees the change.
- Create a Secret as a file mount with subPath, verify the surrounding directory is intact.
If you can do all five in under 30 minutes total, this domain won’t slow you down.
Validate Your Speed Under Exam Conditions
The CKAD tests whether your ConfigMap/Secret reflexes hold up under time pressure with unfamiliar prompts. Take a full-length scored simulator with our CKAD Mock Exam Bundle — every simulator includes ConfigMap and Secret questions in the same format and time pressure as the real exam.
Frequently Asked Questions
Q: How many ConfigMap/Secret questions appear on the CKAD? A: Typically 3-5 questions, including variants buried inside other tasks (e.g., “deploy this app with config from a ConfigMap”). Total weight: ~15-20%.
Q: Are Secrets actually secure? A: Secrets are base64-encoded, not encrypted. Anyone with read access to the API can decode them. For production, enable encryption-at-rest in etcd (out of CKAD scope but useful to know).
Q: When should I use envFrom vs individual env entries?
A: envFrom when you want all keys exposed as env vars with their original names. Individual env entries when you want only some keys, or when you need to rename them.
Q: Why doesn’t my ConfigMap change show up in the pod? A: If consumed as env vars, you must restart the pod. If mounted as a volume with subPath, you must restart. Only plain volume mounts auto-update.
Q: Can a ConfigMap or Secret be larger than 1 MB? A: Both have a 1 MB size limit. For larger config, use a different mechanism (file in an init container, mounted PVC).
Q: Do I have to base64-encode values when creating a Secret with kubectl?
A: No. With --from-literal, kubectl encodes for you. Only when writing a Secret YAML manually do you need to base64-encode the values in data.
Q: How do I see which pods consume a ConfigMap?
A: kubectl get pods -o yaml | grep -B 5 "<cm-name>" is a rough check. There’s no built-in command for tracking dependents.
Ready to make ConfigMaps and Secrets automatic points on your CKAD? Run a scored full-length simulator with our CKAD Mock Exam Bundle and find out exactly where you stand.