skip to content

ConfigMaps

ConfigMaps hold non-secret key-value config that a pod reads as environment variables through envFrom, as single values through valueFrom, or as a mounted volume — and only volume mounts pick up later edits. That asymmetry is the most asked ConfigMap question.

part ofKubernetesoverview, primer and where to startread it →
on this pageshow

questions

5

In Kubernetes, what are the ways a Pod can consume a ConfigMap, and how does injecting values as environment variables differ from mounting the ConfigMap as a volume?

level: juniorimportance: must knowfreq 72%

answer

  1. envFrom = all keys, configMapKeyRef = one key
  2. volume = key becomes a file
  3. env frozen at container start
  4. volume refreshes; subPath does not
  5. missing key → CreateContainerConfigError unless optional

basics

~20 s

Three ways: envFrom to import all keys as env vars, valueFrom.configMapKeyRef to map one key to one env var, or a volume where each key becomes a file. Env values freeze at container start; mounted files are refreshed while the Pod runs.

solid answer

~50 s

A ConfigMap is a namespaced API object holding key/value config data. A Pod consumes it three ways: - **`envFrom.configMapRef`** — every key becomes an environment variable (optionally with a prefix). - **`env[].valueFrom.configMapKeyRef`** — one specific key becomes one named env variable, letting you rename it. - **A `configMap` volume** — each key becomes a file whose contents are the value; `items` lets you project only selected keys to chosen paths. The important difference is lifecycle and shape. Environment variables are resolved once, by the kubelet, when the container starts, so a later edit to the ConfigMap never reaches a running container — you need a Pod restart. Volume-mounted files are kept in sync by the kubelet and change under the running process (unless mounted with `subPath`). Env vars also only carry short scalars; volumes are the way to deliver whole files such as `nginx.conf` or `application.yaml`. Missing key or missing ConfigMap fails container start unless marked `optional: true`.

code

yaml · 41 lines
yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  LOG_LEVEL: "debug"
  FEATURE_X: "true"
  application.yaml: |
    server:
      port: 8080
---
apiVersion: v1
kind: Pod
metadata:
  name: demo
spec:
  containers:
    - name: app
      image: example/app:1.0
      envFrom:
        - configMapRef:
            name: app-config
            optional: false
      env:
        - name: APP_LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: LOG_LEVEL
      volumeMounts:
        - name: config
          mountPath: /etc/app
          readOnly: true
  volumes:
    - name: config
      configMap:
        name: app-config
        defaultMode: 0444
        items:
          - key: application.yaml
            path: application.yaml

go deeper

for a junior

Name the three consumption forms and state the core rule: env vars are fixed at container start, volume files can change.

for a middle

Add the mechanics — kubelet resolves env at container creation, keeps volumes in sync via an atomic symlink swap, subPath opts out — plus optional/missing-key failure modes.

for a senior

Discuss which form you standardise on and why, the blast radius of editing a shared ConfigMap, and the fact that live file updates are useless unless the app re-reads or you force a rollout.

for a principal

Frame it as a config-delivery contract: immutable versioned artefacts and forced rollouts versus mutable live config, what that means for rollback and audit, and where per-tenant or per-region configuration should actually live.

## What a ConfigMap is A ConfigMap is a namespaced Kubernetes API object that stores non-confidential configuration as key/value pairs. Text values live under `data`; base64-encoded binary values live under `binaryData`. It exists so that container images stay generic and environment-specific settings (URLs, feature flags, tuning parameters, whole config files) are supplied at run time. A ConfigMap is inert on its own: it does nothing until a Pod in the *same namespace* references it. There is no cross-namespace reference. ## The three consumption forms **1. `envFrom` — bulk import.** Under `envFrom` you list `configMapRef: {name: my-config}` and every key in the ConfigMap becomes an environment variable of the same name. An optional `prefix` is prepended to each name. This is the least typing and the least control: you cannot rename individual keys, and keys that are not valid environment-variable identifiers (for example `app.properties`) are skipped, with the kubelet recording an event — a silent-looking failure that surprises people. **2. `valueFrom.configMapKeyRef` — one key, one variable.** Inside the container's `env` list you name the variable and point at `{name: my-config, key: log_level}`. This decouples the ConfigMap key from the variable name the application expects, and it makes the dependency explicit and greppable. It is the form to prefer in reviewed manifests. **3. `configMap` volume — keys as files.** You declare a volume of type `configMap` and mount it at a path. Each key becomes a file in that directory whose content is the value. With `items` you project only certain keys, rename their paths, and set per-file `mode` bits. `defaultMode` sets permissions for all files (it is an octal number in YAML, so write `0644`). Mounting a ConfigMap volume over a directory that already exists in the image *replaces* the directory's visible contents — a classic way to accidentally wipe `/etc/nginx/conf.d`. ## What actually differs **Update behaviour.** Environment variables are materialised once: the kubelet reads the ConfigMap when it creates the container and passes the values into the process environment. A process's environment cannot be rewritten from outside, so editing the ConfigMap afterwards changes nothing for running containers until they are recreated. Volume-mounted files are different: the kubelet keeps watching the ConfigMap and refreshes the file contents in place (typically within about a minute, bounded by the kubelet sync period plus its cache TTL). The refresh is atomic — the kubelet writes a new timestamped directory and flips a `..data` symlink — so readers never see a half-written file. Two exceptions: a volume mounted with `subPath` is a one-time copy and never updates, and a ConfigMap marked immutable never changes at all. **Shape of the data.** Environment variables suit short scalars. They are visible to anything that can read `/proc/<pid>/environ`, are inherited by child processes, and show up in crash dumps and `kubectl describe pod`. Whole configuration files belong in volumes: a 40-line YAML file as an env var is unreadable and hits practical size limits. **Failure mode.** If the referenced ConfigMap or key does not exist, the container will not start; the Pod sits in `CreateContainerConfigError` and the kubelet retries. Mark the reference `optional: true` when absence should be tolerated. For volumes, a missing ConfigMap keeps the Pod in `ContainerCreating` with a `FailedMount` event. **Who has to cooperate.** A volume update only helps if the application re-reads the file, or a sidecar/`SIGHUP` handler tells it to. Most applications read config once at startup, so in practice teams deliberately force a restart on change (a checksum annotation on the Pod template, or a hashed ConfigMap name) rather than relying on live propagation. ## Choosing Use `configMapKeyRef` env vars for a handful of scalars that twelve-factor-style apps expect. Use a volume for real config files, for anything larger than a line or two, and when you want the option of live reload. Use `envFrom` sparingly — for a ConfigMap that exists solely to feed one workload's environment — and be aware that it makes the container's environment depend on data you cannot see in the Pod spec. ## Practical notes Keys must consist of alphanumerics, `-`, `_` and `.`. The whole object is capped at roughly 1 MiB. Changing a ConfigMap is a live change to shared state: several Deployments may reference the same object, so an edit can affect workloads you were not thinking about.

  • What happens to the Pod if the ConfigMap key referenced by configMapKeyRef does not exist?
    The kubelet cannot build the container's environment, so the container never starts and the Pod reports `CreateContainerConfigError` with an event naming the missing key. The kubelet keeps retrying, so the Pod recovers on its own once the key appears. Setting `optional: true` on the reference makes the variable simply be omitted instead.
  • You mount a ConfigMap volume at /etc/nginx and nginx stops finding its default files. Why?
    A volume mount shadows whatever was at that path in the image, so the directory now shows only the ConfigMap's keys. Mount at a dedicated path such as `/etc/nginx/conf.d/`, or project a single file with `subPath` — accepting that `subPath` mounts never receive updates.
  • Can a Pod reference a ConfigMap in another namespace?
    No. ConfigMap references resolve within the Pod's own namespace only. To share configuration across namespaces you duplicate the object (via your GitOps/templating tooling) or use a controller that replicates it.

Environment variables are like ingredients read off the recipe card the moment you start cooking — rewriting the card later changes nothing. A volume mount is a card taped to the wall that someone can swap while you cook, but only helps if you look up again.

saying these in an interview costs you the question

  • Claiming an environment variable updates when the ConfigMap is edited
  • Thinking a ConfigMap change automatically restarts the Pods that use it
  • Assuming a Pod can reference a ConfigMap in another namespace
  • Believing keys with dots (app.properties) become valid environment variables under envFrom
  • Mounting a ConfigMap over an image directory without realising the original files are hidden

context

open as a page

You edit a Kubernetes ConfigMap that a running Deployment already consumes. Which of its consumers pick up the new values without a Pod restart, which never do, and roughly how long does propagation take?

level: middleimportance: must knowfreq 64%

basics

~20 s

Files from a configMap volume are refreshed by the kubelet, typically within about a minute. Environment variables never update, and a volume mounted with subPath never updates. Even a refreshed file only helps if the application re-reads it.

open as a page

How do you create a Kubernetes ConfigMap from the command line using literal values, a file, a directory, and a dotenv-style file — and how do the resulting keys differ in each case?

level: juniorimportance: should knowfreq 48%

basics

~20 s

Use kubectl create configmap NAME with --from-literal=K=V (key is K), --from-file=path (key is the file's basename, value is its content), --from-file=key=path to rename, --from-file=dir/ (one key per file), or --from-env-file=.env (one key per line in the file).

open as a page

A Kubernetes ConfigMap is rejected because its data exceeds roughly 1 MiB. Where does that limit come from, and what are your options for delivering configuration larger than that to a container?

level: middleimportance: should knowfreq 36%

basics

~20 s

The API server caps a ConfigMap's data at about 1 MiB because these objects are stored whole in etcd, which has a default per-value size limit. Options: split the data, bake it into the image, mount a PersistentVolume, or fetch it at startup from object storage or a config service.

open as a page

Your service reads its configuration file only at process startup. How do you make a Kubernetes Deployment actually roll out when its ConfigMap changes, and how do you keep that change revertible?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Make the config change alter the Pod template: put a hash of the ConfigMap content in a Pod-template annotation, or give the ConfigMap a content-hash suffix in its name so the reference changes. Either turns the edit into a normal rolling update you can roll back.

open as a page