The two Kubernetes primitives that decouple configuration from container images. ConfigMaps hold non-sensitive settings; Secrets hold sensitive credentials. Both are namespace-scoped, stored in etcd, and consumed by Pods as environment variables or mounted volumes. A core Architecture & Workloads topic on the CKA exam. Synthesized from CKA Day 19 — Kubernetes ConfigMap and Secret Explained and CKA Day 25 — Kubernetes Service Account.
Why Decouple Configuration?
Baking environment-specific values (database URLs, API keys, feature flags) into container images violates the twelve-factor app methodology. It forces you to build a new image for every environment and makes rollbacks painful.
Kubernetes solves this with ConfigMaps and Secrets:
Benefit
How It Works
Environment parity
Same image runs in dev, staging, and prod — only the referenced ConfigMap/Secret changes
Dynamic updates
Volume-mounted ConfigMaps/Secrets update in-place without Pod restarts
Secret isolation
Sensitive data lives in Secrets with tighter RBAC and tmpfs mounting
Centralized config
One ConfigMap can feed dozens of Pods via label selectors
ConfigMap
What Is a ConfigMap?
A ConfigMap is an API object that stores plain-text configuration data as key-value pairs. It is not encrypted and should never hold passwords, tokens, or keys.
Creation Methods
ConfigMaps support four creation patterns — know them all for the exam:
Best for: GitOps, version control, reproducible environments.
Exam Trap: The data field only accepts UTF-8 strings. If you need binary data (e.g., a .p12 certificate), use binaryData instead. Source: CKA Day 19
Secret
What Is a Secret?
A Secret is structurally identical to a ConfigMap but designed for sensitive data. Key differences:
Aspect
ConfigMap
Secret
Data field
data (plain UTF-8 strings)
data (base64-encoded bytes)
Size limit
1 MiB
1 MiB
Default volume mount
Regular filesystem
In-memory tmpfs (never touches node disk)
RBAC sensitivity
Low
High — restrict get/list on Secrets
Etcd storage
Plain text
Base64-encoded (not encrypted by default)
Critical Warning: Secrets are base64-encoded, not encrypted. Anyone who can kubectl get secret can decode the values. For production, enable encryption at rest via EncryptionConfiguration. Source: CKA Day 19
Built-in Secret Types
Kubernetes recognizes several Secret types. The type is metadata, not enforcement — but some controllers behave differently based on it.
Type
Purpose
Opaque
Generic user-defined secrets (default)
kubernetes.io/service-account-token
Auto-generated bearer token for ServiceAccount authentication. Modern clusters (1.24+) use projected volume tokens instead of static Secrets unless explicitly created. See Kubernetes Service Account for token lifecycle.
kubernetes.io/dockercfg
Legacy Docker registry authentication
kubernetes.io/dockerconfigjson
Modern Docker registry authentication (.docker/config.json format)
Caution:envFrom imports every key as an env var. Key names must be valid environment variable names (no hyphens, must start with a letter or underscore). Source: CKA Day 11
Method 2: Volume Mounts
Project ConfigMap or Secret keys as files inside the container:
/etc/nginx/conf.d/
├── default.conf # Key from nginx-config ConfigMap
/etc/nginx/ssl/
├── tls.crt # Key from tls-secret Secret
└── tls.key # Key from tls-secret Secret
Live Updates with Volume Mounts
Object
Volume Mount Updates?
Env Var Updates?
ConfigMap
✅ Yes — kubelet re-syncs files every ~60s
❌ No — Pod must restart
Secret
✅ Yes — kubelet re-syncs files every ~60s
❌ No — Pod must restart
When mounted as a volume, the kubelet watches the referenced ConfigMap/Secret and updates the files in the container without restarting the Pod. The application must detect file changes itself (e.g., via inotify or a configuration reload mechanism).
Production Pattern: Use a sidecar or fsnotify in your app to reload configuration when mounted files change. Sidecar Pattern
ImagePullSecrets
A special Secret type (kubernetes.io/dockerconfigjson) used to authenticate with private container registries. Unlike other Secrets, it is referenced at the Pod spec level, not inside containers:
Without imagePullSecrets, kubelet cannot pull the image and the Pod enters ImagePullBackOff. A cleaner alternative to repeating this field in every Pod is attaching the imagePullSecrets to a ServiceAccount; all Pods using that ServiceAccount automatically inherit the registry credentials. Source: CKA Day 25
By default, Secrets are base64 in etcd. Use EncryptionConfiguration to encrypt with AES-GCM or KMS.
Restrict RBAC on Secrets
Only grant get/list on Secrets to controllers and specific service accounts, not broad developer roles. Use Roles for namespace-scoped Secret access; use ClusterRoles sparingly and only when cross-namespace visibility is required.
Prefer volume mounts over env vars for Secrets
Env vars leak in kubectl describe pod, docker inspect, and /proc/<pid>/environ. Mounted files in tmpfs are more isolated.
Rotate Secrets regularly
Update Secret objects and trigger rolling updates. Use external secret managers (Vault, AWS Secrets Manager) for heavy rotation.
Don’t commit Secrets to Git
Use Sealed Secrets, External Secrets Operator, or CI/CD secret injection. Never store raw Secret YAML in version control.
Use dedicated namespaces
Isolate application Secrets from system Secrets (kube-system).
Troubleshooting Matrix
Symptom
Cause
Fix
CreateContainerConfigError
ConfigMap or Secret referenced but does not exist
Create the object first; check namespace
Invalid value / key not found
Typo in configMapKeyRef.key or secretKeyRef.key
Verify key exists with kubectl get configmap -o yaml
ImagePullBackOff
Missing imagePullSecrets for private registry
Create docker-registry Secret and reference in Pod spec
Secret value is base64 garbage in YAML
Forgot to encode; or double-encoded
Use echo -n "value" | base64 for YAML; use CLI for auto-encoding
ConfigMap too large
Exceeds 1 MiB etcd object limit
Split into multiple ConfigMaps; use volumes for large files
ConfigMap/Secret changes not reflected
Using env vars instead of volume mounts
Switch to volumeMount + volume pattern for live reload
CKA Speed Patterns
# Create ConfigMap from literals (exam speed)kubectl create configmap app-config --from-literal=key=value# Create ConfigMap from filekubectl create configmap nginx-config --from-file=nginx.conf# Create Secret from literals (auto base64)kubectl create secret generic db-secret --from-literal=password=secret123# View decoded Secret valuekubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d# Inject all ConfigMap keys as env varskubectl run debug --image=busybox --env-from=configMapRef:name=app-config --restart=Never
YAML Memory: For the exam, memorize the valueFrom block structure:
Exam-style hands-on tasks for this topic. Complete each task before reviewing the solution. Time yourself — CKA tasks average 5–7 minutes.
Task 1: Create a ConfigMap and Inject as Env Vars
You are asked to create a ConfigMap app-config from literal env=production and mount it as environment variables in a Pod app.
Requirements: Use envFrom to inject all keys.
Verification:kubectl exec app -- env | grep envSolution:
Task 2: Create a Secret and Mount as a File
You are asked to create a Secret db-pass with password S3cr3t! and mount it as a file at /etc/secrets/password in a Pod web.
Requirements: The mount must be read-only.
Verification:kubectl exec web -- cat /etc/secrets/passwordSolution:
Task 3: Troubleshoot a Missing ConfigMap
A Pod api is failing with CreateContainerConfigError. It cannot find its config.
Requirements: Verify the ConfigMap name and mount path, then fix the Pod spec.
Verification:kubectl get pod api shows Running.
Solution:
kubectl describe pod api | grep -A 5 Events# Check if the referenced ConfigMap existskubectl get configmap# If name or key is wrong, either create the missing ConfigMap or edit the Pod speckubectl edit pod api
Falco — Custom runtime-security rules are shipped into Falco DaemonSet Pods as a ConfigMap mounted as a volume — the same volumeMount + volume pattern demonstrated on this page. Source: Falco CKS Scenarios