One of the oldest rules in software delivery is that configuration should not be baked into your build. The same container image should run unchanged in dev, staging, and production — only the values around it change. Kubernetes turns that rule into two first-class objects: the ConfigMap for non-sensitive settings and the Secret for sensitive ones. The Kubernetes and Cloud Native Associate (KCNA) exam expects you to recognise both instantly, know how a Pod consumes them, and — the part that trips people up most — understand exactly what a Secret does and does not protect.
The KCNA rewards breadth and recognition over hands-on speed. You will not be asked to write a projected-volume manifest from memory. You will be shown a scenario — “the team needs to change a database URL without rebuilding the image” — and asked to pick the mechanism. This guide is written at exactly that altitude. If you want the keyboard-level mechanics afterwards, the CKAD ConfigMaps and Secrets guide is the hands-on companion; here we focus on the concepts and the signal words that earn KCNA points.
If you are still assembling your prep, anchor this against the KCNA study guide and the KCNA exam guide for 2026, and treat configuration as the natural next layer on top of the Kubernetes object model and kubectl fundamentals you already know.
Why Decouple Configuration From the Image at All?
Imagine you hard-code a database hostname and an API key into your application and bake them into the container image. You now have three problems the exam cares about:
- You cannot promote the same artifact. Dev and production need different hostnames, so you build two images — and now the thing you tested is not the thing you ship.
- Every config change is a rebuild. Rotating a URL or a feature flag means a full build-and-push cycle, which is slow and error-prone.
- Secrets live in the image layer forever. Anyone who can pull the image can extract the key. Image layers are effectively permanent.
The twelve-factor principle — store config in the environment, not the code — is the cloud native answer, and Kubernetes implements it with ConfigMaps and Secrets. Both are simple key–value stores that live in the cluster and are injected into Pods at runtime. The image stays generic; the environment supplies the specifics.
Signal words: “without rebuilding the image”, “same image across environments”, “externalise configuration”, “change a setting at runtime” → the answer involves a ConfigMap (or a Secret if the value is sensitive), never “rebuild the image.”
ConfigMaps: Non-Sensitive Configuration
A ConfigMap stores plain-text configuration as key–value pairs — think database URLs, log levels, feature flags, or an entire config file such as application.properties or an nginx.conf. It is a namespaced Kubernetes object, so a ConfigMap lives inside one namespace and is consumed by Pods in that same namespace.
A minimal ConfigMap looks like this:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "info"
DATABASE_URL: "postgres://db.internal:5432/app"
# a whole file can be one key, too
app.properties: |
retries=3
timeout=30
Two things to remember for the exam:
- ConfigMaps are not designed for secrets — the values are stored and displayed in plain text.
- There is a practical size limit (a ConfigMap must fit within 1 MiB), because it is stored in etcd like any other object. You would not put a large binary in one.
Secrets: For Sensitive Values — With One Big Caveat
A Secret is structurally almost identical to a ConfigMap — key–value pairs, namespaced, injected the same ways — but it exists to hold sensitive data: passwords, API keys, TLS certificates, tokens. Kubernetes gives Secrets slightly different handling: they are meant to be mounted as tmpfs (in-memory) when used as volumes, kubectl treats them more carefully, and they support typed formats (for example kubernetes.io/tls for a TLS keypair or kubernetes.io/dockerconfigjson for a registry pull secret).
Here is the single most tested idea about Secrets, and it is a trap:
A Kubernetes Secret is base64-encoded, not encrypted. Base64 is trivially reversible —
echo <value> | base64 -dreveals it in one command. On its own, a Secret only keeps data out of plain sight, not out of reach.
So how are Secrets actually protected? Through cluster features layered around them, which the KCNA expects you to recognise:
| Protection | What it does | Who turns it on |
|---|---|---|
| Encryption at rest | etcd encrypts Secret data on disk (e.g. with a KMS provider) | Cluster admin, at the API server |
| RBAC | Restricts who can read Secret objects | Cluster admin, via Roles/RoleBindings |
| tmpfs mounts | Mounted Secrets live in memory, not on the node’s disk | Default behaviour |
| External secret stores | Keep the real secret outside the cluster and sync a reference in | Platform team |
That first row is the exam’s favourite follow-up: “How do you ensure Secrets are encrypted in the datastore?” → enable encryption at rest for etcd, because the default is only base64 encoding. The security depth behind this is a CKS-level topic; if you are curious how it is implemented, see Secrets encryption at rest with KMS — but for the KCNA, recognising that encryption at rest is the answer is enough.
ConfigMap vs Secret: The One-Line Decision
| Use a… | When the value is… | Storage |
|---|---|---|
| ConfigMap | Non-sensitive (URLs, flags, log levels, config files) | Plain text in etcd |
| Secret | Sensitive (passwords, keys, tokens, TLS) | Base64-encoded; encrypt etcd for real protection |
If a scenario mentions a password, credential, token, certificate, or “sensitive,” the answer is a Secret. Everything else non-sensitive is a ConfigMap.
The Four Ways a Pod Consumes Configuration
This is where KCNA questions get concrete. Both ConfigMaps and Secrets are injected into Pods the same four ways, and you should be able to match each to a scenario.
1. As individual environment variables (valueFrom)
Pull one key into one environment variable. Good when the app reads a handful of settings from the environment.
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
2. As a bulk import of every key (envFrom)
Turn all keys in a ConfigMap or Secret into environment variables at once. Handy when there are many settings.
envFrom:
- configMapRef:
name: app-config
3. As files in a mounted volume
Mount the ConfigMap or Secret as a volume; each key becomes a file whose contents are the value. This is the go-to for whole config files (like nginx.conf) and for TLS certificates.
volumes:
- name: config-vol
configMap:
name: app-config
containers:
- name: app
volumeMounts:
- name: config-vol
mountPath: /etc/app
4. As command-line arguments
Reference a config value (already exposed as an env var) inside command/args. Less common, but it appears.
The exam-relevant distinction between environment variables and volume mounts is behavioural, and it is a favourite:
Values injected as environment variables are read once at container start — updating the ConfigMap does not change them until the Pod restarts. Values mounted as a volume are updated automatically (after a short sync delay) without a restart, unless the ConfigMap is immutable or you used a subPath mount.
So if a question says “the running Pods must pick up the new config value without a restart,” the answer points to a volume mount, not environment variables.
Immutability: A Small But Testable Feature
You can mark a ConfigMap or Secret as immutable. Once set, its data cannot be changed — to alter it you delete and recreate it (and roll the Pods). Why would you want that?
- Performance and stability at scale: the kubelet no longer has to watch immutable objects for changes, which reduces load on the API server in large clusters.
- Protection against accidental updates that would silently ripple into every consuming Pod.
The KCNA angle is simply recognising the trade-off: immutability buys stability and scale at the cost of easy updates. If a scenario stresses “prevent accidental changes” or “reduce API server load from many ConfigMaps,” immutable is the signal.
How Configuration Fits the Rest of the Cluster
Configuration objects rarely appear alone on the exam — they connect to workloads and scheduling:
- Workloads consume them. A Deployment or StatefulSet references ConfigMaps and Secrets in its Pod template, so every replica gets the same config. Change the Secret referenced by a Deployment and — for volume mounts — every Pod eventually sees it; for env vars, a rollout is required.
- They interact with resources. Configuration is separate from the CPU/memory requests and limits that drive scheduling — a common trap is to confuse “configuration” (ConfigMap/Secret) with “resource configuration” (requests/limits). They are different objects solving different problems.
- A missing reference blocks the Pod. If a Pod references a ConfigMap or Secret key that does not exist and it is marked required, the container will not start — a
CreateContainerConfigError. Recognising that a config reference can be a scheduling and startup dependency is worth a point.
A Worked Scenario (Exam-Style)
A team runs the same web application image in dev and prod. Production needs a different database endpoint and a database password. They must be able to rotate the password without rebuilding the image, and the password must not be readable by developers who can view ConfigMaps. What should they use?
Walk it the way the exam wants:
- “Same image, different endpoint, no rebuild” → externalise config → ConfigMap for the database endpoint.
- “Password” and “must not be readable by developers” → sensitive value + access control → Secret, protected by RBAC so only the right principals can read it.
- “Rotate without rebuilding the image” → both objects update independently of the image; mount as a volume if the app must pick up changes without a restart.
The right answer is ConfigMap for the endpoint, Secret for the password, RBAC to restrict who reads the Secret — and if pressed on the datastore, encryption at rest. Notice that no answer involving “rebuild the image” or “hard-code the value” is ever correct here.
Common Mistakes on This Topic
- Thinking a Secret is encrypted. It is base64-encoded by default. Encryption at rest is a separate, admin-enabled feature.
- Expecting env-var config to hot-reload. Environment variables are fixed at container start; only volume-mounted config updates live.
- Confusing ConfigMap/Secret with resource requests/limits. Different objects, different domain.
- Assuming cross-namespace access. ConfigMaps and Secrets are namespaced; a Pod can only reference ones in its own namespace.
- Putting sensitive data in a ConfigMap. If it is a credential, it belongs in a Secret.
Frequently Asked Questions
Is a Kubernetes Secret encrypted by default?
No. By default a Secret’s data is only base64-encoded, which is easily reversible. To actually encrypt it in the datastore, a cluster admin must enable encryption at rest for etcd (for example, using a KMS provider). Access is further controlled with RBAC.
What is the main difference between a ConfigMap and a Secret?
Purpose. A ConfigMap holds non-sensitive configuration in plain text; a Secret holds sensitive data and receives slightly more careful handling (typed formats, in-memory tmpfs mounts, and eligibility for encryption at rest). Structurally they are used almost identically.
How do I change configuration without rebuilding my container image?
Store the values in a ConfigMap or Secret and inject them into the Pod as environment variables or a mounted volume. Because the config lives in the cluster, not the image, you can update it independently — this is the whole point of decoupling config from code.
Will my Pods pick up a changed ConfigMap automatically?
Only if the value is consumed as a mounted volume, and then after a short sync delay (immutable ConfigMaps and subPath mounts are exceptions). Values consumed as environment variables are read once at container start and require a Pod restart to change.
Are ConfigMaps and Secrets namespaced?
Yes. Both are namespaced objects. A Pod can only reference a ConfigMap or Secret that lives in the same namespace as the Pod.
How big can a ConfigMap or Secret be?
Each is limited to roughly 1 MiB, because it is stored in etcd like any other API object. They are meant for configuration, not for shipping large files or binaries.
Turn Recognition Into Reflex
Application configuration is one of the most reliable point sources on the KCNA because the mechanics are small and the traps are predictable. If you can instantly tell a ConfigMap from a Secret, name the four ways a Pod consumes them, and remember that a Secret is encoded, not encrypted, you will pick up every configuration question — and the “encryption at rest” and “volume-vs-env hot reload” follow-ups that separate a pass from a fail.
The most dependable way to make that automatic is to work realistic questions under time, see which signal words you misread, and close the gap. Sailor’s KCNA Certification-Ready mock exam bundle is built for exactly that — full-length, domain-weighted exams that mirror the real KCNA, including the configuration scenarios that are easy to under-study. Pair it with the KCNA study guide, and when you want the keyboard-level version of this topic for the hands-on CNCF exams, keep the CKAD ConfigMaps and Secrets guide open beside it.