Courseiva
CKADChapter 10 of 18Objective 5.1

ConfigMaps and Secrets for Application Configuration

Your application breaks in production because a database password is hard-coded into the container image and you cannot update it without rebuilding and redeploying everything. ConfigMaps and Secrets solve this by letting you inject configuration and sensitive data into your applications without touching the application code or images at all. For the CKAD exam, mastering these objects is non-negotiable because they appear in at least one question every single year, often multiple times.

12 min read
Beginner
Updated Jul 23, 2026
Editorial oversight: Johnson Ajibi· Security Systems Architect · MSc IT Security · IEEE Senior Member

A simple way to picture ConfigMaps and Secrets for Application Configuration

The 12-Floor Apartment Building Maintenance Analogy

A 12-floor apartment building has 48 identical flats, each with the same heating system controlled by a programmable thermostat. The building manager needs to change the heating schedule for every single flat from '20°C at 7am' to '21°C at 6am' because the weather has turned cold. If the manager had to walk into each flat separately, reprogram the thermostat by hand, and then double-check all 48 were done correctly, it would take an entire day. Worse, if she made a typo in flat 37, that family would freeze or overheat until she found the mistake.

Instead, the manager updates one central document: a laminated 'Master Heating Schedule' pinned in the boiler room. Then she sends a brief text to every tenant: 'Your thermostat is now linked to the master schedule. Do not change it manually.' Now, changing all 48 flats means editing one piece of paper. If she wants different temperatures for the north-facing flats (colder in winter), she adds a second master sheet just for those flats. One urgent change — 'Turn off all heating for floor 3 due to pipe repair' — takes seconds. The key difference: the thermostats read the master schedule every hour, so any update propagates instantly without touching the physical devices. The building manager never touches a thermostat again. She just manages the central schedules. This is precisely how ConfigMaps work: they are those master sheets. Secrets work the same way, except the information on the sheet is locked in a safe that only authorised people can open. In Kubernetes, your application containers are the thermostats, and ConfigMaps and Secrets are the centralised, version-controlled instruction documents they read.

How It Actually Works

ConfigMaps and Secrets are Kubernetes API objects designed for one job: decouple configuration data from your application code and containers. Before these existed, developers would either hard-code values (like environment names, database URLs, feature flags) into the application binary, or store them in environment variables inside the Dockerfile. Both approaches were terrible because:

Changing any configuration required a full rebuild and redeploy of the container image.

Secrets like passwords or API tokens were visible to anyone who could read the Dockerfile or inspect the image layers.

Different environments (development, staging, production) required different images, defeating the whole point of a single immutable image.

ConfigMaps and Secrets exist to solve those exact problems.

A ConfigMap is a simple key-value store. You define it in a YAML file or create it on the command line. The keys are plain text strings (like 'DB_HOST' or 'LOG_LEVEL'), and the values are also plain text (like 'localhost' or 'DEBUG'). You then attach the ConfigMap to your Pod so that the Pod can read those values at runtime, without the values being baked into the container image. The Pod can consume a ConfigMap in two ways: as environment variables (so the application sees them like regular OS environment variables) or as mounted files (so a file appears inside the container's filesystem with the ConfigMap's content).

A Secret is almost identical to a ConfigMap, but with one critical difference: the data values are base64-encoded. Base64 is not encryption — it is just an encoding scheme that turns binary or special characters into readable ASCII. Anyone can decode base64 trivially. The actual security value of Secrets comes from cluster-level features like encryption at rest (which encrypts the Secret data when it is stored on disk in etcd, the cluster's database) and RBAC (Role-Based Access Control, which restricts which users and service accounts can read the Secret object). As a CKAD candidate, you must know that 'base64 is not security' — the exam will test this specifically.

Both ConfigMaps and Secrets are namespace-scoped objects. That means they live inside a specific Kubernetes namespace and are only visible to Pods in that namespace. You cannot mount a ConfigMap from namespace 'prod' into a Pod in namespace 'dev'. This is important for isolation.

When you create a ConfigMap or a Secret, it is stored in etcd. The Pod does not fetch it directly from etcd. Instead, the kubelet (the agent running on each worker node) reads the Pod's specification and realises it references a ConfigMap or Secret. The kubelet then retrieves the data from the API server and makes it available to the container. If you use the 'env' method, the kubelet injects the values as environment variables before the container's entrypoint runs. If you use the 'volume mount' method, the kubelet creates a file in the container's filesystem and populates it with the ConfigMap or Secret data.

You can update a ConfigMap or Secret after it is created. When a Pod mounts a ConfigMap or Secret as a volume, Kubernetes periodically checks for changes and updates the files inside the container automatically. The application must be designed to watch for file changes or re-read configuration on each request. If you inject the ConfigMap as environment variables, those are set once when the Pod starts and never updated. This is a common exam trap: the exam asks you to update a ConfigMap and expects you to know that environment-variable-based Pods will not see the update unless you restart the Pod.

Immutability is another feature you need to know. You can mark a ConfigMap or Secret as 'immutable: true'. Once set, you cannot modify that object. You must delete it and create a new one. This is useful for preventing accidental changes to critical configuration. The CKAD exam sometimes asks you to create an immutable ConfigMap.

Finally, the size limit: a ConfigMap or Secret cannot be larger than 1 MB. This is a hard limit imposed by etcd's maximum key-value size. If you need to store larger configuration files, you store them somewhere else (like an object store or a persistent volume) and pass just the URL via a ConfigMap.

How ConfigMaps and Secrets flow from creation to injection into a running container.

Walk-Through

1

Create a ConfigMap

Use 'kubectl create configmap my-config --from-literal=key1=value1 --from-literal=key2=value2' or '--from-file=path/to/file'. This stores the data in the Kubernetes API as a ConfigMap object. Why it matters: it is the first step to decoupling configuration from your container image.

2

Verify the ConfigMap

Run 'kubectl get configmap my-config -o yaml' to inspect the stored data. This confirms the keys and values are present. Why it matters: you cannot debug what you cannot see; verifying early prevents mistakes in later steps.

3

Create a Secret

Use 'kubectl create secret generic my-secret --from-literal=password=secret123'. kubectl automatically base64-encodes the value. Why it matters: this keeps sensitive strings from being visible in your YAML or command history in plain text.

4

Mount the ConfigMap as environment variables in a Pod

In the Pod spec, add 'envFrom:' under containers, referencing the ConfigMap name. Example: 'envFrom: - configMapRef: name: my-config'. Why it matters: this injects all key-value pairs as environment variables so the application can read them at runtime.

5

Mount the Secret as a volume in a Pod

Add a volume definition in the Pod spec that references the Secret, then mount that volume at a specific path inside the container. Example: 'volumes: - name: secret-volume secret: secretName: my-secret'. Why it matters: some applications prefer reading sensitive data from files rather than environment variables, and volume mounts support automatic updates.

6

Test the configuration inside the Pod

Exec into the running container using 'kubectl exec -it <pod-name> -- /bin/sh' and check the environment variables with 'env' or the mounted file with 'cat /path/to/file'. Why it matters: this confirms the decoupling worked and the container is using the correct values from the centralised source.

What This Looks Like on the Job

Consider a real company, 'ShopNow', that runs an e-commerce platform on Kubernetes. The platform has four environments: local development, testing, staging, and production. Each environment has different database URLs, API keys for payment providers, feature flags (like 'show_new_checkout: true/false'), and log levels. The same container image must work in all four environments without modification.

Here is how a platform engineer at ShopNow would use ConfigMaps and Secrets:

1. She creates four ConfigMaps in four separate namespaces: 'shopnow-dev', 'shopnow-test', 'shopnow-staging', 'shopnow-prod'. Each ConfigMap contains key-value pairs for environment-specific settings. For example, in the dev namespace, 'DB_HOST: localhost', but in the prod namespace, 'DB_HOST: rds.prod.shopnow.internal'.

2. She creates Secrets for the database passwords and payment gateway tokens. In dev, the database password is a dummy string like 'devpassword'. In prod, it is the real production password. These Secrets are base64-encoded when stored, and the prod namespace enables encryption-at-rest for extra security. Only the production deployments' service accounts have RBAC permission to read the prod Secrets.

3. She updates the deployment YAML for the web server component to reference the ConfigMap and Secret. The YAML has a 'spec.template.spec.containers[0].envFrom' section that pulls in all keys from the ConfigMap and a separate 'envFrom' for the Secret. The application code reads environment variables like 'DB_HOST' and 'DB_PASSWORD' on startup.

4. The same container image 'shopnow/web:v2.3' works perfectly in both dev (connecting to localhost) and prod (connecting to RDS). The platform engineer never rebuilds the image for different environments.

5. When a new payment provider is added, she creates a new Secret with the new API key in each namespace, updates the deployment to reference that Secret, and rolls out a zero-downtime update. No code changes, no image rebuild, no leaking of secrets in Git repositories.

6. She uses 'kubectl create configmap' and 'kubectl create secret' for quick ad-hoc tests, but in production, all ConfigMaps and Secrets are stored in Git using a GitOps tool like ArgoCD. This gives her a full audit trail of every configuration change.

7. For the monolithic frontend that caches configuration aggressively, she mounts the ConfigMap as a volume (not env vars) so that updates propagate without restarting the Pod. The frontend watches the mount path for file changes and reloads configuration automatically.

The outcome: the team can deploy to any environment with one command, rotate secrets without downtime, and enforce least-privilege access to sensitive data through RBAC.

How CKAD Actually Tests This

The CKAD exam loves ConfigMaps and Secrets because they are small, testable objects that require attention to detail. Here is exactly what you will face:

Question types that appear repeatedly:

- Create a ConfigMap from literal key-value pairs using 'kubectl create configmap'. - Create a ConfigMap from a file using '--from-file'. - Mount a ConfigMap as a volume inside a Pod. - Inject a ConfigMap as environment variables into a Pod. - Create a Secret from literal values and from a file. - Mount a Secret as a volume (often for TLS certificates). - Make a ConfigMap or Secret immutable and then try to update it (the trap is that you cannot). Traps the exam sets (you must watch for these):

- Trapping you with 'env' vs 'envFrom': 'env' lets you set a single environment variable and optionally remap the key name; 'envFrom' imports all keys from a ConfigMap as environment variables with the same key names. The exam question will specify one or the other, and using the wrong one loses marks. - Trapping you with Secret encoding: the exam will ask you to create a Secret with a literal password. You must know to use 'kubectl create secret generic my-secret --from-literal=password=abc123'. You do NOT need to manually base64-encode the value — kubectl does that automatically. But the exam may also give you a YAML file with base64-encoded data and ask you to decode it using 'echo <value> | base64 --decode'. - Trapping you with immutability: if a ConfigMap is immutable, you cannot update it. The correct approach is to delete it and recreate it with a new name, then update the Pod spec to reference the new name. The exam will give you a scenario where the Pod is running and expects the new config — you need to know the volume mount will not see the update unless you restart the Pod (or the app watches for file changes). - Trapping you with namespace mismatch: all objects must be in the same namespace. The exam may try to trick you by creating a ConfigMap in namespace 'default' and trying to mount it in namespace 'production'. That fails. - Trapping you with Secret size: Secrets cannot exceed 1 MB. The exam will not give you a file that exceeds that, but they might ask you to store a large file and expect you to know you cannot fit it in a Secret. - Trapping you with the '--from-env-file' flag: you can use that to create a ConfigMap from a file that contains multiple key=value lines, one per line. The exam may provide such a file and ask you to import it. Key concepts you must memorise:

The exact syntax: 'kubectl create cm my-cm --from-literal=key=value'.

The difference between environment variables and volume mounts.

That Secrets are transmitted encrypted to nodes when TLS is enabled for kubelet communication.

That 'secrets' in the context of a Pod volume mount are actually files, one file per key, with the filename being the key name and the content being the value.

That you can restrict which Pods can use a Secret by placing the Secret in a specific namespace and controlling access via RBAC.

Key Takeaways

ConfigMaps store non-sensitive configuration data as key-value pairs, while Secrets store sensitive data in base64-encoded format.

You can inject ConfigMap and Secret data into Pods either as environment variables (set once at startup) or as mounted files (updated automatically if the object changes).

When using environment variables, updating the ConfigMap or Secret has no effect on already-running Pods; you must restart the Pod to pick up changes.

Base64 encoding is not a security measure; real security for Secrets comes from RBAC, encryption at rest in etcd, and TLS for in-transit data.

ConfigMaps and Secrets are namespace-scoped objects, meaning they are only accessible to Pods within the same namespace.

Immutable ConfigMaps and Secrets cannot be modified after creation; to change them, you must delete and recreate the object with a new name, then update the Pod spec.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

ConfigMap

Stores data as plain text (readable in kubectl get output).

Used for non-sensitive configuration like database hostnames, log levels, feature flags.

Data is not automatically encrypted at rest in etcd unless you enable encryption for all objects.

Secret

Stores data as base64-encoded text (not readable in plain text via kubectl get).

Used for sensitive data like passwords, API tokens, SSH keys, TLS certificates.

Data can be encrypted at rest in etcd using a cluster-wide encryption configuration.

Environment Variable Injection

Values are injected once when the Pod starts; updates to ConfigMap are not reflected.

You must restart the Pod to pick up new values.

Simpler to set up; uses 'envFrom' or 'env' in the Pod spec.

Volume Mount Injection

Values are mounted as files in the container's filesystem, updated automatically (if the ConfigMap changes).

The application can re-read the file to pick up changes without restarting the Pod.

Requires defining a volume and a volume mount in the Pod spec.

Mutable ConfigMap/Secret

You can update the object at any time with new key-value pairs.

Running Pods with volume mounts will automatically see the updated files.

Default behaviour; no special flag needed.

Immutable ConfigMap/Secret

You cannot update the object after creation; must delete and recreate.

Provides a guarantee that configuration will not change unexpectedly, useful for production.

Set 'immutable: true' in the YAML spec.

ConfigMap from Literal

Created using '--from-literal=key=value' syntax.

Best for small, ad-hoc key-value pairs (e.g., FOO=bar).

Multiple literals can be provided on one command line.

ConfigMap from File

Created using '--from-file=path/to/file' syntax.

Best for importing existing configuration files (e.g., application.properties).

The file contents become the value; the filename becomes the key.

Watch Out for These

Mistake

Base64-encoded data in a Secret is encrypted and thus secure.

Correct

Base64 is encoding, not encryption. Anyone can decode it instantly. Real security comes from RBAC, encryption at rest, and TLS in transit.

The word 'secret' sounds like it implies encryption, and base64 output looks like gibberish, so beginners assume it is secure.

Mistake

You must manually base64-encode Secret values when using kubectl create secret.

Correct

kubectl automatically base64-encodes literal values. Only if you write a YAML file manually must you provide the base64-encoded string yourself.

Older documentation and some tutorials show manual base64, leading beginners to believe it is required even with kubectl.

Mistake

Updating a ConfigMap automatically updates the environment variables in all running Pods that use it.

Correct

Environment variables are set only at Pod startup time. Updating the ConfigMap has no effect on running Pods. You must restart the Pod for it to pick up changes.

The volume mount method does update automatically, so beginners extrapolate that environment variables behave the same way.

Mistake

ConfigMaps and Secrets can be shared across namespaces by default.

Correct

Both are namespace-scoped objects. A ConfigMap in namespace 'alpha' cannot be mounted by a Pod in namespace 'beta' unless you manually copy it or use a tool like a cross-namespace operator.

People confuse them with Cluster-wide objects like ClusterRole or Namespace itself.

Mistake

You can store any kind of data larger than 1 MB in a ConfigMap or Secret as long as it is text.

Correct

The hard limit is 1 MB total for the entire object (both keys and values). This is enforced by etcd.

The 1 MB limit is rarely hit in practice, so people assume it does not exist or is larger.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

What is the difference between a ConfigMap and a Secret?

A ConfigMap stores non-sensitive configuration data in plain text. A Secret stores sensitive data but only encodes it with base64 — it does not encrypt it. The real security for Secrets comes from RBAC and encryption at rest, not from base64.

Do I need to base64-encode Secret values when using kubectl create?

No. When you use 'kubectl create secret generic', kubectl automatically base64-encodes the literal values you provide with '--from-literal'. You only need to manually base64-encode if you are writing the YAML file yourself.

If I update a ConfigMap, will my running Pod automatically get the new values?

It depends on how you mounted it. If you use environment variables, the Pod will NOT see the update — you must restart the Pod. If you mount the ConfigMap as a volume, the files inside the container will be updated automatically (but the application must re-read them).

Can a Pod in one namespace use a ConfigMap from a different namespace?

No. ConfigMaps and Secrets are namespace-scoped objects. A Pod can only reference ConfigMaps and Secrets that exist in the same namespace the Pod is running in.

How large can a ConfigMap or Secret be?

The maximum size for a ConfigMap or Secret object is 1 MB. This limit is enforced by etcd, the database that stores all Kubernetes objects. If you need to store larger configuration files, store them externally and pass the URL via a ConfigMap.

How do I make a ConfigMap or Secret immutable?

Set 'immutable: true' in the YAML spec when creating the object, or add it to an existing object (though you cannot then update it). Once immutable, you cannot modify the object. You must delete it and create a new one with a different name.

Terms Worth Knowing

Keep going

You've finished ConfigMaps and Secrets for Application Configuration. Continue through the CKAD study guide to build a complete picture of the exam.

Done with this chapter?