Storing configuration settings directly within a container image creates a rigid and tightly coupled system. Every time you need to change a database endpoint, adjust a feature flag, or modify an external API URL, you would have to rebuild, push, and redeploy the entire image. This process is slow, error-prone, and violates the principle of separating configuration from code. Kubernetes provides a dedicated object to solve this problem: the ConfigMap.
A ConfigMap is a Kubernetes API object used to store non-confidential configuration data in key-value pairs. Think of it as a dictionary or a hash map that lives inside your cluster, accessible by your applications. By decoupling configuration from your container images, you can manage settings for different environments (development, staging, production) without altering your application's core artifacts.
You can create ConfigMaps in two primary ways: imperatively using kubectl or declaratively using a YAML manifest file.
The kubectl create configmap command is useful for quick, on-the-fly creation. You can supply data directly from literals or from files.
To create a ConfigMap from literal key-value pairs, use the --from-literal flag:
kubectl create configmap app-settings \
--from-literal=api.service.url=http://users-api:8080 \
--from-literal=ui.theme=dark
This command creates a ConfigMap named app-settings with two data entries. You can inspect it with kubectl describe configmap app-settings.
To create a ConfigMap from an entire file, you can use the --from-file flag. This is particularly useful for existing configuration files, like nginx.conf or application.properties.
Suppose you have a file named app.properties:
# Application Configuration
feature.new-login.enabled=true
cache.size.mb=256
You can create a ConfigMap that stores the content of this file under a key that matches the filename:
kubectl create configmap app-file-config --from-file=app.properties
For reproducible, version-controlled infrastructure, the declarative approach using a YAML manifest is the standard practice. A ConfigMap manifest defines the desired state, which you can apply to the cluster.
Here is an example of a ConfigMap defined in my-configmap.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-settings-v2
namespace: default
data:
# key-value pairs defined as properties
database.host: "mysql.prod.svc.cluster.local"
database.name: "products"
# key with multi-line content as a single value
ui.properties: |
color.primary=#4263eb
font.size=14px
You create the object by applying this manifest:
kubectl apply -f my-configmap.yaml
The data field contains the key-value pairs. The keys must be valid DNS subdomain names, and the values are arbitrary UTF-8 strings. You can use a pipe | for multi-line string values, which is helpful for embedding entire configuration files directly into the manifest.
Once a ConfigMap is created, you need a way for your application Pods to consume its data. Kubernetes offers three primary methods for this: injecting as environment variables, mounting as files in a volume, or using them as command-line arguments.
Injecting configuration data as environment variables is a common pattern, as many applications are built to read settings from the environment.
You can inject all key-value pairs from a ConfigMap into a Pod using envFrom:
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
spec:
containers:
- name: my-app-container
image: nginx:latest
envFrom:
- configMapRef:
name: app-settings
In this example, every key in the app-settings ConfigMap becomes an environment variable inside my-app-container. For instance, the key api.service.url would become an environment variable named API_SERVICE_URL. Note that Kubernetes converts the key to an uppercase name and replaces dots and dashes with underscores, following standard environment variable naming conventions.
Alternatively, you can inject a specific key from a ConfigMap using valueFrom:
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod-selective
spec:
containers:
- name: my-app-container
image: busybox
command: [ "/bin/sh", "-c", "echo Theme is $APP_THEME" ]
env:
- name: APP_THEME
valueFrom:
configMapKeyRef:
name: app-settings # Name of the ConfigMap
key: ui.theme # The key to inject
This approach gives you fine-grained control, allowing you to choose which keys to expose and what to name the resulting environment variables.
For applications that expect to read configuration from files, mounting a ConfigMap as a volume is the ideal solution. When you mount a ConfigMap, each key in the data field becomes a file in the mount directory, and the content of that file is the key's value.
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod-volume
spec:
containers:
- name: my-app-container
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: config-volume # Reference to the volume defined below
mountPath: /etc/config # Directory inside the container
volumes:
- name: config-volume # Defines the volume
configMap:
name: app-settings-v2 # The ConfigMap to mount
In this manifest:
volumes section at the Pod level defines a volume named config-volume and specifies that its source is the app-settings-v2 ConfigMap.volumeMounts section within the container specification mounts that volume into the container's filesystem at the path /etc/config.After this Pod starts, you could execute a shell inside the container and find the following file structure:
/etc/config/database.host (containing the string mysql.prod.svc.cluster.local)/etc/config/database.name (containing the string products)/etc/config/ui.properties (containing the multi-line string defined in the ConfigMap)This method is powerful because it allows you to provide entire configuration files to your application without altering its code.
A diagram showing a single ConfigMap being consumed by two different Pods. Pod A injects the data as environment variables, while Pod B mounts the same data as files in a volume.
A significant behavior to understand is how changes to a ConfigMap affect running Pods that consume it. The propagation method depends on how the ConfigMap is consumed.
Environment Variables: If a Pod consumes a ConfigMap as environment variables, the values are injected when the Pod starts. Updates made to the ConfigMap will not be reflected in the running container. The environment variables are static for the lifetime of the container. To apply the new configuration, you must restart the Pod.
Mounted Volumes: If a Pod consumes a ConfigMap as a mounted volume, the files in the mount are updated automatically when the ConfigMap changes. There can be a short delay for this synchronization, managed by the Kubelet. However, the application running inside the container must be able to detect the file change and reload its configuration. Many applications do not do this automatically, so they might still require a restart to pick up the new settings.
Because of this behavior, the most reliable way to roll out a configuration change is to trigger a rolling update of the Deployment managing the Pods. This ensures that new Pods are created with the updated configuration in a controlled manner, preventing inconsistencies.
By using ConfigMaps, you build more flexible and manageable applications on Kubernetes. This object provides a clean separation between your application logic and its runtime configuration, a fundamental practice for creating portable and scalable systems.
Was this section helpful?
© 2026 ApX Machine LearningEngineered with