Learn to manage application configuration with ConfigMaps and sensitive data with Secrets. Master environment variables, volume mounts, and security best practices.
Configuration management is crucial for running applications in Kubernetes. ConfigMaps store non-confidential configuration data, while Secrets store sensitive information like passwords, tokens, and certificates. Together, they enable you to separate configuration from container images, making applications more portable and secure.
In this lesson, you'll learn how to create, manage, and consume ConfigMaps and Secrets effectively, following security best practices for production environments.
ConfigMaps store non-confidential data in key-value pairs. They allow you to decouple configuration from container images.
Use Cases:
Key Characteristics:
Creating ConfigMaps:
Secrets store sensitive data like passwords, tokens, and certificates. They provide a layer of protection over ConfigMaps.
Types of Secrets:
Security Considerations:
Note: Base64 is encoding, not encryption. Anyone with access can decode Secrets.
ConfigMaps can be consumed in Pods through environment variables or volume mounts.
Environment Variables:
Volume Mounts:
Best Practice:
Secrets are consumed similarly to ConfigMaps but with security considerations.
Consumption Methods:
Security Tips:
Immutable ConfigMaps and Secrets provide protection against accidental updates and improve cluster performance.
Benefits:
Use Cases:
Migration Strategy:
For production, implement proper secret encryption and consider external secret managers.
Encryption at Rest:
External Secret Managers:
Benefits of External Managers:
Create a fully configured application using ConfigMaps and Secrets.
1#!/bin/bash
2# ConfigMaps and Secrets Lab
3# ==========================
4
5set -e
6
7NAMESPACE="config-demo"
8
9echo "========================================"
10echo " ConfigMaps and Secrets Lab"
11echo "========================================"
12
13# Create namespace
14kubectl create namespace $NAMESPACE --dry-run=client -o yaml | kubectl apply -f -
15
16# 1. Create ConfigMap
17echo -e "
18[1] Creating ConfigMap..."
19cat <<EOF | kubectl apply -n $NAMESPACE -f -
20apiVersion: v1
21kind: ConfigMap
22metadata:
23 name: app-config
24data:
25 APP_NAME: "MyWebApp"
26 LOG_LEVEL: "info"
27 CACHE_ENABLED: "true"
28 nginx.conf: |
29 server {
30 listen 80;
31 server_name localhost;
32 location / {
33 root /usr/share/nginx/html;
34 index index.html;
35 }
36 location /health {
37 return 200 'OK';
38 add_header Content-Type text/plain;
39 }
40 }
41EOF
42
43# 2. Create Secret
44echo -e "
45[2] Creating Secret..."
46cat <<EOF | kubectl apply -n $NAMESPACE -f -
47apiVersion: v1
48kind: Secret
49metadata:
50 name: app-secrets
51type: Opaque
52stringData:
53 DB_PASSWORD: "supersecretpassword"
54 API_KEY: "sk-abc123xyz789"
55EOF
56
57# 3. Deploy application
58echo -e "
59[3] Deploying application..."
60cat <<EOF | kubectl apply -n $NAMESPACE -f -
61apiVersion: apps/v1
62kind: Deployment
63metadata:
64 name: webapp
65spec:
66 replicas: 2
67 selector:
68 matchLabels:
69 app: webapp
70 template:
71 metadata:
72 labels:
73 app: webapp
74 spec:
75 containers:
76 - name: nginx
77 image: nginx:alpine
78 ports:
79 - containerPort: 80
80 # ConfigMap as env vars
81 env:
82 - name: APP_NAME
83 valueFrom:
84 configMapKeyRef:
85 name: app-config
86 key: APP_NAME
87 - name: LOG_LEVEL
88 valueFrom:
89 configMapKeyRef:
90 name: app-config
91 key: LOG_LEVEL
92 # Secret as env var
93 - name: DB_PASSWORD
94 valueFrom:
95 secretKeyRef:
96 name: app-secrets
97 key: DB_PASSWORD
98 # ConfigMap as volume
99 volumeMounts:
100 - name: nginx-config
101 mountPath: /etc/nginx/conf.d/default.conf
102 subPath: nginx.conf
103 - name: secrets-volume
104 mountPath: /etc/secrets
105 readOnly: true
106 resources:
107 requests:
108 memory: "64Mi"
109 cpu: "100m"
110 volumes:
111 - name: nginx-config
112 configMap:
113 name: app-config
114 items:
115 - key: nginx.conf
116 path: nginx.conf
117 - name: secrets-volume
118 secret:
119 secretName: app-secrets
120 defaultMode: 0400
121---
122apiVersion: v1
123kind: Service
124metadata:
125 name: webapp
126spec:
127 type: NodePort
128 selector:
129 app: webapp
130 ports:
131 - port: 80
132 nodePort: 30081
133EOF
134
135# Wait for deployment
136kubectl rollout status deployment/webapp -n $NAMESPACE
137
138# 4. Verify configuration
139echo -e "
140[4] Verifying configuration..."
141POD=$(kubectl get pods -n $NAMESPACE -l app=webapp -o jsonpath='{.items[0].metadata.name}')
142
143echo "Environment variables:"
144kubectl exec -n $NAMESPACE $POD -- env | grep -E "(APP_NAME|LOG_LEVEL|DB_PASSWORD)" | head -3
145
146echo -e "
147Nginx config file:"
148kubectl exec -n $NAMESPACE $POD -- cat /etc/nginx/conf.d/default.conf | head -10
149
150echo -e "
151Secrets volume:"
152kubectl exec -n $NAMESPACE $POD -- ls -la /etc/secrets/
153
154# 5. Test the application
155echo -e "
156[5] Testing application..."
157kubectl exec -n $NAMESPACE $POD -- wget -qO- http://localhost/health
158
159echo -e "
160========================================"
161echo " Lab Complete!"
162echo "========================================"
163echo ""
164kubectl get all -n $NAMESPACE
165echo ""
166echo "Cleanup: kubectl delete namespace $NAMESPACE"Your progress is saved in this browser, on this device only.