Create a ConfigMap three ways
A ConfigMap is a Kubernetes object that holds key/value config
data. Pods can pull from it as environment variables, command-line
args, or files mounted into a volume.
There are three idiomatic ways to create one.
From a literal
kubectl create configmap sample --from-literal=message=hello
Inspect it:
kubectl get configmap sample -o yaml
The data: map has one entry: message: hello.
From a file on disk
cat config/sample.properties
kubectl create configmap sample2 --from-file=config/sample.properties
The file's name becomes the key, its contents the value:
kubectl describe configmap sample2
From a YAML manifest
cat config/config-map-3.yaml
kubectl apply -f config/config-map-3.yaml
kubectl describe configmap sample3 shows three keys: message,
retries, feature.banner.
Click Verify step when all three exist.
Hint
From literal: `kubectl create configmap sample --from-literal=message=hello`. From file: `kubectl create configmap sample2 --from-file=config/sample.properties`. From YAML: `kubectl apply -f config/config-map-3.yaml`.
Inject a ConfigMap as environment variables
Look at the Deployment manifest โ it pulls two env vars from the two
ConfigMaps you just created:
cat config/configmap-demo.yaml
env:
- name: GREETING
valueFrom:
configMapKeyRef:
name: sample
key: message
- name: MESSAGE
valueFrom:
configMapKeyRef:
name: sample3
key: message
Apply it:
kubectl apply -f config/configmap-demo.yaml
Wait for the pod:
kubectl wait --for=condition=Available deployment/configmap-demo --timeout=60s
Look at the env inside the container:
kubectl exec deploy/configmap-demo -- printenv | grep -E '^(GREETING|MESSAGE)='
Output:
GREETING=hello
MESSAGE=Cloud AI Campus says hi
Env vars are read at container start. Updating the ConfigMap
doesn't update env vars โ you need to restart the pod. For live
updates, use the volume mount instead (next step).
Click Verify step.
Hint
`kubectl apply -f config/configmap-demo.yaml`, then `kubectl exec deploy/configmap-demo -- printenv` should show GREETING and MESSAGE.
Mount a ConfigMap as a volume
The same Deployment also mounts ConfigMap sample3 as a volume at
/etc/config. Each key in the ConfigMap becomes a file with the
key's value as its content.
List the mounted files:
kubectl exec deploy/configmap-demo -- ls -la /etc/config
You should see three files: message, retries, feature.banner.
Read one:
kubectl exec deploy/configmap-demo -- cat /etc/config/message
Cloud AI Campus says hi
Why volumes vs env vars? Volumes update live. Edit the
ConfigMap:
kubectl patch configmap sample3 --type merge -p '{"data":{"message":"updated"}}'
Re-read the file inside the pod โ it may take 10-60 seconds for the
kubelet to refresh the projected files:
for i in 1 2 3 4 5 6; do
kubectl exec deploy/configmap-demo -- cat /etc/config/message
sleep 10
done
Eventually the file shows updated. Env vars wouldn't.
Click Verify step when /etc/config/message reads updated.
Hint
The same Deployment mounts `sample3` at `/etc/config`. `kubectl exec deploy/configmap-demo -- ls /etc/config`.
Create a Secret
ConfigMaps are perfect for non-sensitive config. For credentials,
keys, certificates โ anything you wouldn't want printed in plain
text โ use a Secret.
The two object kinds behave almost identically (env vars + volume
mounts), but Secrets:
- are base64-encoded at rest (not encrypted by default โ see the
warning at the end).
- can be marked as encrypted at rest by configuring the API
server's encryption provider.
- are kept in
tmpfs when mounted as volumes, never written to disk
on the node.
Create a generic Secret from a literal:
kubectl create secret generic db-creds --from-literal=password='s3cret!'
Inspect โ note the value is base64-encoded:
kubectl get secret db-creds -o yaml
Decode it for sanity-checking:
kubectl get secret db-creds -o jsonpath='{.data.password}' | base64 -d; echo
Base64 is encoding, not encryption. Anyone with read access
to the Secret can decode it. Production clusters layer on
KMS-backed encryption-at-rest and RBAC to restrict who can read
Secrets at all.
Click Verify step when the Secret exists.
Hint
`kubectl create secret generic db-creds --from-literal=password=s3cret!`.
Consume the Secret as an env var
The Deployment manifest in config/secret-demo.yaml pulls
db-creds.password into the container as DB_PASSWORD:
cat config/secret-demo.yaml
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-creds
key: password
Apply:
kubectl apply -f config/secret-demo.yaml
kubectl wait --for=condition=Available deployment/secret-demo --timeout=60s
Verify the env arrived in the container:
kubectl exec deploy/secret-demo -- printenv DB_PASSWORD
You should see s3cret!.
The pod can't tell whether the env came from a Secret or a
ConfigMap โ they look identical inside the container. But your
cluster operators do see the difference: Secrets are audited
separately, can be encrypted, and tend to be locked down with
tighter RBAC.
One more thing. Look at what the pod is logging โ it's a tiny
busybox loop that prints the password to stdout:
kubectl logs deploy/secret-demo --tail=3
Lesson: consuming a Secret safely is the app's responsibility.
Kubernetes hands you a string; if your app leaks it to logs or
returns it in an HTTP response, that's on the app.
Click Verify step.
Hint
`kubectl apply -f config/secret-demo.yaml`, then `kubectl exec deploy/secret-demo -- printenv DB_PASSWORD`.