Skip to main content
RunBook Academy

KubernetesXX · ConfigurationConfiguration

ConfigMaps — key-value configuration decoupled from container images

Advanced⏱ ~17 minkubectlkubeadm

What you'll learn

  • Describe what ConfigMaps are for and what they are not for (Secrets, large data)
  • Author ConfigMaps from literals, files, and directories
  • Distinguish env-var consumption from file consumption
  • Reason about the 1 MiB size limit and other ConfigMap constraints

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

A ConfigMap is the standard Kubernetes object for non-sensitive configuration: feature flags, application settings, external service URLs, log levels. ConfigMaps decouple configuration from container images — a single image can run with different configs across environments — and they are designed to be consumed by Pods in two ways, as environment variables and as mounted files. This lesson covers the format, the limits, and the patterns that work.

What a ConfigMap is

apiVersion: v1
kind: ConfigMap
metadata:
  name: web-config
  namespace: prod
data:
  log_level: info
  feature_flags: |
    {
      "checkout_v2": true,
      "new_search": false
    }
  database_url: postgres://db.prod/data

A ConfigMap has metadata (name, namespace, labels) and a free-form data map of string keys to string values. The values are arbitrary UTF-8; the size limit is 1 MiB total across all keys.

flowchart LR
    A["ConfigMap<br/>web-config"] --> B[Pod spec]
    B --> C[env vars]
    B --> D[mounted files]
    C --> E[Process env]
    D --> F[Container filesystem]

Authoring a ConfigMap

From literal values:

kubectl create configmap web-config -n prod \
  --from-literal=log_level=info \
  --from-literal=database_url=postgres://db.prod/data

From files:

kubectl create configmap web-config -n prod \
  --from-file=nginx.conf=./nginx.conf \
  --from-file=app.properties=./app.properties

From a directory:

kubectl create configmap web-config -n prod \
  --from-file=./config/

The keys are the file names; the values are the file contents. The same ConfigMap can mix literals and files.

From a manifest:

apiVersion: v1
kind: ConfigMap
metadata:
  name: web-config
data:
  log_level: info
  app.conf: |
    [server]
    port = 8080
    workers = 4

The 1 MiB limit

The total size of a ConfigMap (the keys, the values, and the metadata) is bounded at 1 MiB. Larger data goes in a PVC, an external store, or a different mechanism.

Consuming a ConfigMap as env vars

spec:
  containers:
  - name: web
    image: web:v1
    envFrom:
    - configMapRef:
        name: web-config

envFrom injects every key in the ConfigMap as an environment variable. The container sees LOG_LEVEL=info, DATABASE_URL=postgres://db.prod/data, etc.

For selective injection:

env:
- name: LOG_LEVEL
  valueFrom:
    configMapKeyRef:
      name: web-config
      key: log_level
- name: DATABASE_URL
  valueFrom:
    configMapKeyRef:
      name: web-config
      key: database_url

valueFrom with configMapKeyRef reads a specific key.

Consuming a ConfigMap as files

spec:
  containers:
  - name: web
    image: web:v1
    volumeMounts:
    - name: config
      mountPath: /etc/web
  volumes:
  - name: config
    configMap:
      name: web-config

The ConfigMap’s keys become files in the mount path. With the example above, the container sees:

/etc/web/log_level      # contents: info
/etc/web/feature_flags  # contents: {...}
/etc/web/database_url   # contents: postgres://...

For named keys:

volumeMounts:
- name: config
  mountPath: /etc/web/app.conf
  subPath: app.conf
volumes:
- name: config
  configMap:
    name: web-config

subPath mounts a single key as a file at the specified path. Useful when the application expects a specific filename.

Real-time updates

flowchart TB
    A[ConfigMap updated] --> B{Updated object<br/>in etcd}
    B --> C{Kubelet watches<br/>ConfigMap?}
    C -->|yes| D{Pod consumes as<br/>env or files?}
    D -->|env vars| E["Env vars NOT updated<br/>Pod must restart"]
    D -->|files| F["Files updated<br/>after kubelet sync"]
    F --> G["Application must<br/>reload or SIGHUP"]

This is the most common ConfigMap confusion in production:

  • Env vars from ConfigMap are immutable in the running Pod. They are read once when the container starts. A ConfigMap update does not change the running container’s env vars; the Pod must be restarted.
  • Files from ConfigMap are eventually consistent. The kubelet syncs the mount within ~60 seconds (configurable via syncPeriod). The application must detect the change and reload; many do not.

This asymmetry is the source of “I changed the config but nothing happened” tickets.

immutability

ConfigMaps and Secrets can be marked immutable:

immutable: true

Once set, the data cannot be changed. Any update is rejected. This is correct for configuration that should not change at runtime (e.g., the configuration baked into a release). It is wrong for configuration that is expected to roll (e.g., a feature flag toggled weekly).

Quiz

Knowledge check · 4 questions

  1. Q1. What is the maximum size of a ConfigMap?

  2. Q2. ConfigMaps are encrypted by default in etcd.

  3. Q3. Your team tries to store a 10 MiB JSON schema in a ConfigMap. The API server rejects the apply. Diagnose and propose alternatives.

    ConfigMap web-schema with 10 MiB JSON. The apply fails with request entity too large.

  4. Q4. What are the two ways a Pod can consume a ConfigMap, and how does update behavior differ between them?

Passing score: 75%. Answers are checked in this browser.

Production discipline

  • ConfigMaps are for non-sensitive configuration. Secrets, certificates, and credentials belong in Secrets (with encryption at rest) or external secret managers.
  • The 1 MiB limit is real. Verify the total size before applying; kubectl get configmap -o yaml | wc -c is a quick check.
  • Document the consumption pattern. A ConfigMap mounted as files is not the same as one consumed as env vars. The application must be designed for the consumption it receives.
  • Test the update path. A change to the ConfigMap should produce the expected effect on the running Pod. Verify with a test cluster.
  • Use immutability for release-baked configuration. A ConfigMap that should never change at runtime is immutable; the cluster cannot drift.

ConfigMaps are the right tool for non-sensitive configuration. The discipline is in the consumption pattern — env vars vs files, restart-on-update vs reload-on-update — and in choosing the right object for the data (ConfigMap vs Secret vs PVC vs object store).