Day 33: Taming Kubernetes ConfigMaps and Secrets for My Flask + Redis App!


Why ConfigMaps and Secrets? 🤔
Picture this: my Flask + Redis app is humming along in Kubernetes, with pods and services set up from Days 31 and 32. But my Flask app needs settings like FLASK_ENV=production
and REDIS_HOST=redis-service
, and my Redis pod might need a password. Hardcoding these in my Docker image or scattering them in YAML files? Yawn—that’s so Day 6 (when I learned Docker environment variables). Kubernetes ConfigMaps and Secrets are here to save the day! ConfigMaps handle non-sensitive settings, while Secrets lock up sensitive data like passwords. Both make my app flexible and secure, like giving it a superhero utility belt. 🦸‍♂️
I kicked off by asking Grok (my AI sidekick from xAI, accessed via grok.com): “What are Kubernetes ConfigMaps and Secrets, and how do they differ?” Using DeepSearch mode, Grok explained that ConfigMaps store plain-text key-value pairs for things like environment settings, while Secrets use base64 encoding for sensitive stuff like passwords. It’s like ConfigMaps are your app’s public to-do list, and Secrets are the locked diary. With that clarity, I was ready to roll!
Step 1: Setting the Stage
First, I fired up my Minikube cluster on my Ubuntu machine:
minikube start --driver=docker
I checked my Flask and Redis pods and services from Day 32:
kubectl get pods,svc
minikube service flask-service --url
Everything was up—my Flask app was chatting with Redis via a ClusterIP service. I opened my notes file with vi
(because who needs fancy editors?):
vi ~/flask-redis-app/notes/Day_33_Activities.txt
I jotted down: “Day 33: Kubernetes ConfigMaps and Secrets - July 3, 2025”. To warm up, I recalled why I used ClusterIP for Redis (internal pod communication) and NodePort for Flask (external access). It’s like setting up a private phone line for Redis and a public website for Flask!
Step 2: ConfigMaps—Organizing App Settings
Time to tidy up my Flask app’s settings with a ConfigMap. I created a file called flask-configmap.yaml
:
vi ~/flask-redis-app/k8s/flask-configmap.yaml
Here’s what I wrote:
apiVersion: v1
kind: ConfigMap
metadata:
name: flask-app-config
data:
FLASK_ENV: "production"
REDIS_HOST: "redis-service"
APP_PORT: "5000"
This ConfigMap is like a settings menu for my app—environment, Redis host, and port, all in one place. I applied it:
kubectl apply -f ~/flask-redis-app/k8s/flask-configmap.yaml
Next, I updated my Flask deployment to use these settings:
vi ~/flask-redis-app/k8s/flask-deployment.yaml
I swapped out hardcoded env
values for ConfigMap references:
spec:
containers:
- name: flask
image: <my-username>/flask-app:latestdnsutils
valueFrom:
configMapKeyRef:
name: flask-app-config
key: REDIS_HOST
- name: APP_PORT
valueFrom:
configMapKeyRef:
name: flask-app-config
key: APP_PORT
I reapplied the deployment:
kubectl apply -f ~/flask-redis-app/k8s/flask-deployment.yaml
Then, I tested it:
minikube service flask-service --url
curl <flask-service-url>
Boom! My Flask app was running smoothly, pulling settings from the ConfigMap. I checked the ConfigMap details with:
kubectl describe configmap flask-app-config
It felt like organizing a messy drawer—everything was neat and accessible! I asked Grok: “How can ConfigMaps be mounted as volumes?” In think mode, Grok explained that I could mount ConfigMaps as files in a pod’s filesystem, which I noted for Day 34 exploration.
Step 3: Secrets—Locking Down Sensitive Data
Now for the juicy part: securing a Redis password with a Secret. First, I encoded my password (redis-password
) in base64:
echo -n 'redis-password' | base64
Output: cmVkaXMtcGFzc3dvcmQ=
. I created a Secret manifest:
vi ~/flask-redis-app/k8s/redis-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: redis-secret
type: Opaque
data:
REDIS_PASSWORD: cmVkaXMtcGFzc3dvcmQ=
I applied it:
kubectl apply -f ~/flask-redis-app/k8s/redis-secret.yaml
Then, I updated my Redis deployment:
vi ~/flask-redis-app/k8s/redis-deployment.yaml
Added:
spec:
containers:
- name: redis
image: redis:latest
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: REDIS_PASSWORD
I also updated my Flask deployment to use the same Secret:
vi ~/flask-redis-app/k8s/flask-deployment.yaml
Added:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: REDIS_PASSWORD
I reapplied both deployments:
kubectl apply -f ~/flask-redis-app/k8s/redis-deployment.yaml
kubectl apply -f ~/flask-redis-app/k8s/flask-deployment.yaml
I tested the app with Redis:
curl <flask-service-url>/set_key?key=test&value=123
curl <flask-service-url>/get_key?key=test
It worked like a charm! The Secret kept my password safe, and I verified it with:
kubectl get secret redis-secret -o yaml
I asked Grok: “What are best practices for securing Kubernetes Secrets?” DeepSearch revealed tips like using external tools (e.g., Sealed Secrets) for production, which I jotted down in my notes.
Step 4: Enhancing the App
To make my app chatty, I added logging:
vi ~/flask-redis-app/app.py
import os
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger.info(f"FLASK_ENV: {os.getenv('FLASK_ENV')}")
logger.info(f"REDIS_HOST: {os.getenv('REDIS_HOST')}")
I rebuilt and pushed the Docker image:
cd ~/flask-redis-app
docker build -t <my-username>/flask-app:latest .
docker push <my-username>/flask-app:latest
Redeployed:
kubectl apply -f ~/flask-redis-app/k8s/flask-deployment.yaml
Checked logs:
kubectl logs -l app=flask
The logs confirmed my ConfigMap settings were in action!
I committed everything to GitHub:
git add .
git commit -m "Day 33: ConfigMaps and Secrets for Flask + Redis"
git push origin main
Subscribe to my newsletter
Read articles from Usman Jap directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
