Skip to main content

Chapter 5.1 - ConfigMaps

Learning Objectives

By the end of this chapter, you will be able to:

  • Understand what a ConfigMap is and why to use it
  • Create ConfigMaps in different ways
  • Use ConfigMaps in your Pods
  • Separate configuration from application code
  • Apply best practices for ConfigMaps

Introduction

In application development, configuration often changes depending on the environment (development, staging, production). Hardcoding configuration in code or Docker images is not a good practice.

ConfigMaps allow you to separate configuration from application code.


What is a ConfigMap?

A ConfigMap is a Kubernetes object that stores non-sensitive configuration data as key-value pairs. This data can be used by Pods as environment variables, command arguments, or configuration files.


Why Use ConfigMaps?

Problems Without ConfigMaps

Problems:

  • Configuration hardcoded in the code
  • Need to rebuild the image to change config
  • Difficult to manage different environments
  • No separation of concerns

Advantages With ConfigMaps

Advantages:

  • Configuration separated from code
  • No need to rebuild the image
  • Easy to manage multiple environments
  • Reusable across multiple Pods

Creating ConfigMaps

Method 1: From Literals

kubectl create configmap app-config \
--from-literal=database_url=postgresql://localhost:5432/mydb \
--from-literal=log_level=info \
--from-literal=max_connections=100

Method 2: From a File

Create a config.properties file:

database_url=postgresql://localhost:5432/mydb
log_level=info
max_connections=100
kubectl create configmap app-config --from-file=config.properties

Method 3: From a YAML File

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: default
data:
database_url: "postgresql://localhost:5432/mydb"
log_level: "info"
max_connections: "100"
# Complete file
application.properties: |
server.port=8080
server.host=0.0.0.0
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb

Usage in Pods

Method 1: Environment Variables (Single Key)

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: my-app:1.0
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config
key: database_url
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: log_level

Method 2: All Keys (envFrom)

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: my-app:1.0
envFrom:
- configMapRef:
name: app-config

Result: All ConfigMap keys become environment variables.

Method 3: As a Volume (Files)

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: my-app:1.0
volumeMounts:
- name: config
mountPath: /etc/config
readOnly: true
volumes:
- name: config
configMap:
name: app-config

Result: Each key becomes a file in /etc/config/ with the value as its content.


Complete Example

Step 1: Create the ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
name: webapp-config
data:
# Simple variables
APP_NAME: "My Web Application"
APP_VERSION: "1.0.0"
ENVIRONMENT: "production"

# Configuration file
nginx.conf: |
server {
listen 80;
server_name example.com;
root /usr/share/nginx/html;
index index.html;
}

Step 2: Use in a Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nginx:1.20
env:
- name: APP_NAME
valueFrom:
configMapKeyRef:
name: webapp-config
key: APP_NAME
- name: ENVIRONMENT
valueFrom:
configMapKeyRef:
name: webapp-config
key: ENVIRONMENT
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d
readOnly: true
volumes:
- name: nginx-config
configMap:
name: webapp-config
items:
- key: nginx.conf
path: default.conf

Use Cases

1. Application Configuration

apiVersion: v1
kind: ConfigMap
metadata:
name: app-settings
data:
database_host: "db.example.com"
database_port: "5432"
cache_ttl: "3600"
feature_flags: "feature1,feature2"

2. Configuration Files

apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
}

3. Scripts

apiVersion: v1
kind: ConfigMap
metadata:
name: init-scripts
data:
init.sh: |
#!/bin/bash
echo "Initializing application..."
/app/setup.sh
exec /app/start.sh

Best Practices

1. Organization by Environment

Create separate ConfigMaps for each environment:

# Development
kubectl create configmap app-config-dev --from-file=config-dev.properties

# Production
kubectl create configmap app-config-prod --from-file=config-prod.properties

2. Versioning

Use labels for versioning:

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
labels:
version: v1
environment: production
data:
# ...

3. Do Not Store Sensitive Data

Never put the following in a ConfigMap:

  • Passwords
  • API tokens
  • Private keys
  • Certificates

Use Secrets instead.


Useful Commands

View a ConfigMap

kubectl get configmap app-config
kubectl describe configmap app-config
kubectl get configmap app-config -o yaml

Modify a ConfigMap

kubectl edit configmap app-config

Note: Existing Pods will not see the changes immediately. They need to be restarted.

Delete a ConfigMap

kubectl delete configmap app-config

Limitations

Maximum Size

  • 1 MiB per entry in a ConfigMap
  • Total limited by etcd (typically ~1.5 MiB per object)

Updates

  • Environment variables: Do not change without restarting the Pod
  • Volumes: Updated periodically (delay of a few seconds)

Summary

In this chapter, you learned:

ConfigMap: Kubernetes object to store non-sensitive configuration
Creation: kubectl create, YAML, from files
Usage: Environment variables (env/envFrom) or volumes
Advantages: Config/code separation, flexibility, reusability
Best practices: Organization by environment, versioning, no secrets
Limitations: Maximum size, update requires restart for env vars


Next Steps

Chapter 5.2: Secrets - Managing sensitive data
Lab 5.1: Creating and Using ConfigMaps


Chapter created: December 2024