ConfigMaps and Secrets
Create ConfigMaps and Secrets from literals, files and env files, inject them as environment variables or mounted files, and know which changes ever reach a running Pod.
After this lesson
- 01You can create a ConfigMap or Secret from literals, a file or an env file in one command, and decode any Secret value.
- 02You can inject one key with env.valueFrom, a whole object with envFrom, and files with a configMap or secret volume, including items and subPath.
- 03You can say which consumption methods pick up an update, and what immutable: true changes.
This lesson covers the competency Use ConfigMaps and Secrets to configure applications. Exam tasks here are short and very literal: a named object with named keys, consumed in a specific way, by a specific container. The grader reads the object, then the Pod spec, and often runs env or cat inside the container. Every detail in the question is checkable, so read it twice.
Create them imperatively
# ConfigMaps
kubectl -n wl-config create configmap app-config --from-literal=APP_MODE=production --from-literal=APP_COLOR=blue
kubectl -n wl-config create configmap nginx-conf --from-file=default.conf=./site.conf # key=path sets the key name
kubectl -n wl-config create configmap app-env --from-env-file=./app.env # one key per KEY=VALUE line
kubectl -n wl-config create configmap scripts --from-file=./scripts/ # one key per file in the directory
# Secrets: same flags, plus a type
kubectl -n wl-config create secret generic db --from-literal=username=app --from-literal=password='s3cr3t!'
kubectl -n wl-config create secret tls web-tls --cert=tls.crt --key=tls.key
kubectl -n wl-config create secret docker-registry regcred --docker-server=registry.example.com --docker-username=ci --docker-password='token'
# Look before you mount
kubectl -n wl-config describe configmap app-config
kubectl -n wl-config get secret db -o yamlWith --from-file the key is the file's base name unless you write key=path; the value is the whole file. With --from-env-file each line becomes its own key, and quotes are kept literally, so A="x" stores the quotes too. Mixing up the two is the most common reason a mounted file or a variable comes out wrong.
base64 is an encoding, not protection
kubectl -n wl-config get secret db -o jsonpath='{.data.password}' | base64 -d; echo
echo -n 's3cr3t!' | base64 # -n matters: without it the trailing newline is encoded too
kubectl -n wl-config create secret generic db2 --from-literal=password='s3cr3t!' --dry-run=client -o yamlIn YAML, data takes base64 values and stringData takes plain text that the API server encodes on write; stringData is never returned on read. Secrets sit in etcd unencrypted unless the API server has an encryption configuration (covered in the architecture module), and anyone allowed to create Pods in a namespace can read every Secret there by mounting it. RBAC on Secrets and on Pod creation is the real control.
apiVersion: v1
kind: Pod
metadata:
name: env-demo
namespace: wl-config
spec:
containers:
- name: app
image: busybox:1.36
command: ["sleep", "3600"]
env:
- name: MODE # one key, under a new name
valueFrom:
configMapKeyRef:
name: app-config
key: APP_MODE
- name: DB_PASS
valueFrom:
secretKeyRef:
name: db
key: password
envFrom: # every key becomes a variable
- configMapRef:
name: app-config
- prefix: DB_ # username becomes DB_username
secretRef:
name: dbIf a referenced object or key is missing, the container does not start and the Pod shows CreateContainerConfigError; kubectl describe pod names the missing piece. Add optional: true to the reference only when the question allows the value to be absent. A name set under env wins over the same name from envFrom.
spec:
containers:
- name: nginx
image: nginx:1.27
volumeMounts:
- name: conf # one file dropped into an existing directory
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
- name: creds # the whole Secret as a directory of files
mountPath: /etc/creds
readOnly: true
volumes:
- name: conf
configMap:
name: nginx-conf # configMap uses "name" ...
items: # only these keys, under these file names
- key: default.conf
path: default.conf
- name: creds
secret:
secretName: db # ... secret uses "secretName"
defaultMode: 0400 # octal in YAML; the API stores it as 256Mounting a volume on a directory hides whatever the image had there. That is fine for /etc/creds and harmful for /etc/nginx. When you must add one file to a directory that already has content, use subPath, and accept the trade-off in the next table.
Setting immutable: true on a ConfigMap or Secret is a one-way door: you cannot unset it, only delete the object. In exchange the kubelet stops watching it, which takes real load off the API server on large clusters, and no one can change configuration under a running app by accident.
In the docs · the tab you get on exam day
- Configure a Pod to Use a ConfigMap ↗search: “configure pod configmap”
- Distribute Credentials Securely Using Secrets ↗search: “distribute credentials secrets”
- Secrets ↗search: “secret types”
- ConfigMaps ↗search: “configmap”
context · kubectl config use-context kind-cka
Configure a Deployment from a ConfigMap and a Secret
wl-config: create a ConfigMap app-config with the keys APP_MODE=production and APP_COLOR=blue, and a Secret app-secret of type Opaque with the key DB_PASSWORD=s3cr3t-pass. Then create a Deployment app with 2 replicas, image busybox:1.36, container name app, running sleep 3600. The container must get an environment variable MODE from the key APP_MODE of app-config, every key of app-secret as an environment variable, and every key of app-config as a file under /etc/app.- 01
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-config-1/setup | bash - 02
Solve it in your terminal
Work the way the exam makes you: kubectl, the docs, nothing else. Put any answer files under
/tmp/cka/. - 03
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-config-1/verify | bashCounts toward your readiness score. - 04
Clean up
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-config-1/cleanup | bash
context · kubectl config use-context kind-cka
Replace a config file and mount a Secret with strict permissions
/tmp/cka/wl-config/default.conf. In namespace wl-config, create a ConfigMap proxy-conf from that file with the key default.conf, and a Secret proxy-token with the key token set to abc123. Then create a Pod proxy (image nginx:1.27) in which the ConfigMap's file replaces /etc/nginx/conf.d/default.conf, so that http://localhost:8080/healthz inside the Pod returns healthy, and the Secret is available as the file /etc/proxy/token with permissions 0400.- 01
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-config-2/setup | bash - 02
Solve it in your terminal
Work the way the exam makes you: kubectl, the docs, nothing else. Put any answer files under
/tmp/cka/. - 03
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-config-2/verify | bashCounts toward your readiness score. - 04
Clean up
curl -fsSL https://codewithmuh.com/labs/cka/t/wl-config-2/cleanup | bash
Finished reading?
0 of 2 tasks passed. Readiness counts tasks, so run them before you move on.