Sign in
← Kubernetes: configuration
7 min · easy · Lesson 2 of 8

ConfigMap as env and as volume

Three ways to pass settings into a Pod from a ConfigMap, and how they differ when the data changes.

Why ConfigMap

In the previous lesson, settings sat right in the Pod manifest, in the env block. That works as long as there's one Pod and one environment. Once the same image ships to dev, staging and prod, it's easier to keep settings in a separate object and plug in the right one for each environment.

A ConfigMap is a Kubernetes object holding key/value pairs, stored in the cluster's API (backed by etcd). On its own it does nothing. You put app settings into it (a database URL, a run mode, a log level), and the Pod picks how to consume them: as env variables or as files.

The image stays the same, each environment gets its own ConfigMap.

A ConfigMap stores values in plain text, visible to anyone with read access to ConfigMaps in the namespace. Put public settings there, not passwords. For passwords there's Secret, covered in the next lesson.

The minimal YAML

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_MODE: prod
  APP_LOG_LEVEL: info

data is a map of strings. Numbers and booleans are written in quotes, same as in env. A multi-line value (a whole nginx.conf, say) is written in YAML with |. There's also binaryData for binary files in base64, but that's rare.

The same thing from the command line:

kubectl create configmap app-config --from-literal=APP_MODE=prod --from-literal=APP_LOG_LEVEL=info

With the flag --from-file=./config.json, the key becomes the file name (config.json), the value its contents.

How to attach it to a Pod

An env variable from a specific key

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

The reference has two parts: the ConfigMap's name (name) and a key inside it (key). The variable's name in the container (APP_MODE on the first line) doesn't have to match the key.

kubelet reads the key once, when it creates the container, and puts the value into env. If you change the ConfigMap, env inside the running container doesn't update. The Pod has to be recreated, which for a Deployment is kubectl rollout restart.

All keys at once through envFrom

ConfigMap metadata.name: app-config data: APP_MODE, APP_LOG_LEVEL Pod · envFrom configMapRef.name: app-config all keys become env name match
The link goes by object name, not by reference. If the names differ, the container won't start.
envFrom:
  - configMapRef:
      name: app-config

Every key of the ConfigMap becomes an env variable with the same name. Handy when there are many keys and they're already named the way you want. They update the same way as env.valueFrom: only when the container is recreated.

The ConfigMap got deleted or its name was misspelled. A running container survives on its old env, but the next time the container starts (a restart after a crash, a new Pod) it lands in CreateContainerConfigError. The cause is written in the Pod's events: kubectl describe pod <name>, the Events block.

A volume of type configMap

volumes:
  - name: config
    configMap:
      name: app-config
      items:
        - key: APP_LOG_LEVEL
          path: log.level
volumeMounts:
  - name: config
    mountPath: /etc/config

volumes is described at the Pod's spec level, volumeMounts on the container. The volume's name is the same in both places.

A volume behaves differently from env. kubelet periodically checks the files against the current version of the ConfigMap and rewrites them. data changes, and roughly a minute later the file inside the Pod updates. The exact delay depends on kubelet's sync period and its cache. For the new value to take effect, the app has to reread the file itself: on a timer, on a filesystem event, or on a signal. nginx, for example, rereads its config on SIGHUP (nginx -s reload).

The items block is needed when the app doesn't need every key, or the file name has to differ from the key name. Without items, every key becomes a file with its own name. With items, only the listed keys show up in the directory.

Three ways side by side

The three ways to attach a ConfigMap differ in whether the data updates in a running Pod:

waywhat it givesupdates live
env.valueFromone key in envno, the Pod must be recreated
envFromall keys in envno, the Pod must be recreated
volumekeys as filesyes, kubelet syncs with a delay

Env is a process's memory: it was set at startup, and nothing outside can change it. kubelet can rewrite a file in a volume at any moment.

kubectl create configmap app-config --from-literal=APP_MODE=prod
kubectl create configmap app-config --from-file=./config.json
kubectl get configmap app-config -o yaml
kubectl describe configmap app-config
kubectl edit configmap app-config
kubectl explain pod.spec.containers.envFrom
kubectl explain pod.spec.volumes.configMap --recursive

Common mistakes

What you'll need for the tasks

Homework

Practice the theory on your own cluster: 3 steps with a check. Set up the cluster with the Kubernetes locally track, the tasks live in the k8s-practice repository.

./run.sh start k8s-configmap     # set up the starting state
./run.sh verify k8s-configmap    # check the current step

In short

Done reading?

Mark the lesson as read to move your track progress forward.

Go through it with an AI agent

The agent explains anything unclear in plain words, gives you 2 labs for this lesson and drills you on interview questions. $49 one-time, lifetime access.

Get access for $49

Tell the agent: use MCP izi, give me lesson k8s-config-02-configmap