Kubernetes ConfigMap & Secret Hands‐on Lab - neerajk555/Kubernetes GitHub Wiki
This lab will cover:
- ConfigMap – creation, usage, update, and cleanup
- Secret – creation, usage, update, and cleanup
- Best practices and verification commands
Prerequisites
- A running Kubernetes cluster (Minikube, Kind, or Cloud cluster).
kubectl
installed and configured.- Basic knowledge of Pods.
1. ConfigMap Hands-on
A ConfigMap stores non-sensitive configuration data in key-value format.
Step 1: Create a ConfigMap
We will create a ConfigMap in three ways.
1A. From Literal Values
kubectl create configmap app-config \
--from-literal=APP_ENV=production \
--from-literal=APP_PORT=8080
Explanation:
kubectl create configmap
→ Creates a new ConfigMap.--from-literal
→ Directly define key-value pairs.app-config
→ Name of the ConfigMap.
Verify:
kubectl get configmap app-config -o yaml
You should see:
data:
APP_ENV: production
APP_PORT: "8080"
1B. From File
- Create a file
app.properties
:
echo "APP_ENV=staging" > app.properties
echo "APP_PORT=9090" >> app.properties
- Create ConfigMap from file:
kubectl create configmap app-config-file --from-file=app.properties
- Verify:
kubectl describe configmap app-config-file
Explanation:
Each line in the file is stored as the file’s content under the file name as the key.
1C. From YAML Manifest
app-config.yaml
:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-yaml
data:
APP_ENV: "dev"
APP_PORT: "3000"
FEATURE_FLAG: "true"
Apply:
kubectl apply -f app-config.yaml
Verify:
kubectl get configmap app-config-yaml -o yaml
Step 2: Use ConfigMap in a Pod
We can inject ConfigMap data as environment variables or files.
2A. As Environment Variables
configmap-env-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: configmap-env-pod
spec:
containers:
- name: demo-container
image: busybox
command: ["sh", "-c", "env; sleep 3600"]
envFrom:
- configMapRef:
name: app-config
Explanation:
envFrom
loads all keys from the ConfigMap as environment variables.busybox
prints the environment variables and sleeps.
Deploy:
kubectl apply -f configmap-env-pod.yaml
kubectl logs configmap-env-pod
You will see:
APP_ENV=production
APP_PORT=8080
2B. As Files in a Volume
configmap-volume-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: configmap-volume-pod
spec:
containers:
- name: demo-container
image: busybox
command: ["sh", "-c", "ls /etc/config; cat /etc/config/*; sleep 3600"]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
Explanation:
- Mounts each ConfigMap key as a separate file in
/etc/config
. - File name = key, content = value.
Deploy and check logs:
kubectl apply -f configmap-volume-pod.yaml
kubectl logs configmap-volume-pod
Step 3: Update ConfigMap
kubectl edit configmap app-config
# Change APP_PORT: "8081"
- If mounted as Volume → Files update automatically.
- If used as Env Vars → Pod must be restarted:
kubectl delete pod configmap-env-pod
kubectl apply -f configmap-env-pod.yaml
Step 4: Cleanup ConfigMap Resources
kubectl delete pod configmap-env-pod configmap-volume-pod
kubectl delete configmap app-config app-config-file app-config-yaml
2. Secret Hands-on
A Secret stores sensitive data like passwords or API keys.
Step 1: Create a Secret
1A. From Literal Values
kubectl create secret generic db-secret \
--from-literal=DB_USER=admin \
--from-literal=DB_PASS=MyP@ss123
Verify:
kubectl get secret db-secret -o yaml
Values will appear base64-encoded.
Decode to check:
kubectl get secret db-secret -o jsonpath='{.data.DB_USER}' | base64 --decode
1B. From File
echo -n "admin" > username.txt
echo -n "MyP@ss123" > password.txt
kubectl create secret generic db-secret-file \
--from-file=username.txt \
--from-file=password.txt
Explanation:
- Each file name = key, content = value (base64-encoded).
1C. From YAML Manifest
Encode values:
echo -n "admin" | base64 # YWRtaW4=
echo -n "MyP@ss123" | base64 # TXlQQHNzMTIz
db-secret.yaml
:
apiVersion: v1
kind: Secret
metadata:
name: db-secret-yaml
type: Opaque
data:
DB_USER: YWRtaW4=
DB_PASS: TXlQQHNzMTIz
Apply:
kubectl apply -f db-secret.yaml
Step 2: Use Secret in a Pod
2A. As Environment Variables
secret-env-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: demo-container
image: busybox
command: ["sh", "-c", "env; sleep 3600"]
envFrom:
- secretRef:
name: db-secret
Check logs:
kubectl logs secret-env-pod
2B. As Files in a Volume
secret-volume-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: secret-volume-pod
spec:
containers:
- name: demo-container
image: busybox
command: ["sh", "-c", "ls /etc/secret; cat /etc/secret/*; sleep 3600"]
volumeMounts:
- name: secret-volume
mountPath: /etc/secret
volumes:
- name: secret-volume
secret:
secretName: db-secret
Step 3: Update Secret
kubectl create secret generic db-secret \
--from-literal=DB_USER=admin \
--from-literal=DB_PASS=NewP@ss456 \
--dry-run=client -o yaml | kubectl apply -f -
Mounted as volumes → auto-update
Used as env vars → restart Pod
Step 4: Cleanup Secret Resources
kubectl delete pod secret-env-pod secret-volume-pod
kubectl delete secret db-secret db-secret-file db-secret-yaml
3. Best Practices
- Never commit secrets in Git → Use an external secret manager.
- Use encryption at rest for etcd for secrets.
- Use RBAC to restrict secret access.
- Prefer volume mounts for dynamic updates.
- Use immutable ConfigMaps/Secrets for rarely changed configs.