Skip to main content
Course/Config & Health/ConfigMaps
3/960 min
Config & Health

ConfigMaps

Externalise non-sensitive configuration from container images using ConfigMaps.

beginner60 minRead β†’ Lab β†’ Quiz β†’ Practice
🧠 Brain Warm-Up
🧠 Brain Warm-Up: If a ConfigMap is updated, how does the update propagate to containers using the ConfigMap as environment variables versus those mounting it as a volume, and why?

ConfigMaps and Twelve-Factor Portability

The 12-Factor App methodology states that config should be strictly separated from code. In Kubernetes, this separation is achieved using ConfigMaps. ConfigMaps decouple environment-specific parameters from the immutable container image, allowing the same container image to run across dev, staging, and production environments.

What ConfigMaps Store

  • Environment variable values (LOG_LEVEL=debug)
  • Full configuration files (nginx.conf, application.properties)
  • Command-line arguments

ConfigMaps are for non-sensitive data. Never put passwords or tokens in a ConfigMap β€” use a Secret instead.

Visualizing ConfigMap Projection

                  +-------------------------+
                  |  ConfigMap in etcd      |
                  |  (Key-Value Data Store)  |
                  +-------------------------+
                               |
                               | (API Server)
                               v
                       +---------------+
                       |   Kubelet     |
                       +---------------+
                               |
         +---------------------+---------------------+
         | (Static Injection)                        | (Dynamic Sync Loop)
         v                                           v
+-----------------------------+             +-----------------------------+
|    Environment Variables    |             |        Volume Mount         |
|                             |             |                             |
| - Injected at startup       |             | - Kubelet writes to tmpfs   |
| - Read-only thereafter      |             | - Atomic symlink flip       |
| - Requires Pod restart      |             | - Live update (~1 min sync) |
+-----------------------------+             +-----------------------------+

Consumption Mechanisms & Internal Details

When you reference a ConfigMap in a Pod spec, the injection behaves differently depending on the projection mechanism:

1. Environment Variables (`valueFrom.configMapKeyRef` / `envFrom`)

  • Mechanism: The container runtime (e.g. containerd) reads the ConfigMap values from the API server during container creation and sets them inside the container's process environment block (env).
  • Low-Level Detail: The process reads env vars once during initialization.
  • Update Behavior: Static. If the ConfigMap is modified, the environment variables inside the container do not change. The Pod must be restarted (e.g., via a rolling deployment trigger like kubectl rollout restart) to pick up updates.

2. Volume Mounts

  • Mechanism: The kubelet creates a local directory on the host under /var/lib/kubelet/pods//volumes/kubernetes.io~configmap/ backed by tmpfs (in-memory RAM filesystem). It requests the ConfigMap from the API server and writes the keys as files.
  • Low-Level Detail: To prevent race conditions where a process reads a half-written config file during an update, kubelet uses atomic symlink swapping:

1. It writes the new files to a unique timestamped directory (..data_timestamp).

2. It updates a symbolic link (..data) to point to the new directory.

3. The individual keys are symlinked to files inside ..data.

  • Update Behavior: Dynamic. Kubelet's periodic sync loop (defaulting to every 60 seconds, controlled by syncFrequency and configMapAndSecretChangeDetectionStrategy) will detect the update, fetch the new payload, and update the symlinks.
  • Exception: If you mount a ConfigMap using subPath, the file is bind-mounted directly. The kernel does not update static bind-mounts when the parent directory's symlinks change. Therefore, subPath mounted ConfigMaps do not receive hot updates.

Three Ways to Consume a ConfigMap

1. Single env var

env:
  - name: LOG_LEVEL
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: LOG_LEVEL

2. All keys as env vars (envFrom)

envFrom:
  - configMapRef:
      name: app-config

3. Volume mount (for config files)

volumes:
  - name: config-vol
    configMap:
      name: nginx-conf
containers:
  - volumeMounts:
    - name: config-vol
      mountPath: /etc/nginx

Update Behaviour

Consumption methodHot-reload when ConfigMap changes?
env var / envFromNo β€” pod must be restarted
Volume mountYes β€” kubelet syncs within ~1 minute

This difference is critical for production: if you need live config reloads, mount as a volume and design your app to watch the file.