DEV Community

Cover image for πŸ” Kubernetes Secrets & ConfigMaps: Securely Manage Your App Configurations
zaheetdev
zaheetdev

Posted on

πŸ” Kubernetes Secrets & ConfigMaps: Securely Manage Your App Configurations

Managing your app configurations and secrets securely is non-negotiable in modern cloud-native development. Kubernetes offers two native resources to do this:

  • πŸ›  ConfigMaps for non-sensitive configuration
  • πŸ” Secrets for credentials, tokens, and other sensitive values

In this guide, we’ll show how to use both in a real-world Node.js app deployed to Kubernetes.


✨ What You'll Learn

βœ… Difference between ConfigMaps and Secrets

βœ… Creating secure configurations using YAML

βœ… Deploying a Node.js app with injected env vars

βœ… Debugging and accessing environment inside the container

βœ… Docker + Kubernetes best practices for configuration


πŸ“¦ Demo Image & Source Code

We're using a public Docker image that reads environment variables and returns them:


πŸ“ Project Structure

k8s-config-demo/
β”œβ”€β”€ index.js
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ configmap.yaml
β”œβ”€β”€ secret.yaml
└── deployment.yaml
Enter fullscreen mode Exit fullscreen mode

🧠 Why ConfigMaps & Secrets?

ConfigMap

  • Stores non-sensitive values like APP_MODE, URLs, etc.

Secret

  • Stores sensitive data like DB_USER, DB_PASSWORD
  • Encoded in Base64 and supports encryption at rest

Using them ensures:

  • πŸ” You don’t hardcode values
  • πŸ” You can change config without rebuilding the image
  • 🧩 They integrate cleanly into deployments

🧰 The Application Code (index.js)

const http = require('http');
const PORT = process.env.PORT || 3000;
const DB_USER = process.env.DB_USER;
const DB_PASSWORD = process.env.DB_PASSWORD;
const APP_MODE = process.env.APP_MODE || 'dev';

http.createServer((req, res) => {
  res.end(`Mode: ${APP_MODE}, DB_USER: ${DB_USER}`);
}).listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});
Enter fullscreen mode Exit fullscreen mode

🐳 Dockerfile

FROM node:alpine
WORKDIR /app
COPY index.js .
CMD ["node", "index.js"]
Enter fullscreen mode Exit fullscreen mode

Build and push (already done):

docker build -t zaheetdeveloper/k8s-config-demo:v1 .
docker push zaheetdeveloper/k8s-config-demo:v1
Enter fullscreen mode Exit fullscreen mode

πŸ”§ Step-by-Step Kubernetes Setup

1️⃣ Create the ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_MODE: production
Enter fullscreen mode Exit fullscreen mode
kubectl apply -f configmap.yaml
Enter fullscreen mode Exit fullscreen mode

Config creation successful


2️⃣ Create the Secret

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  DB_USER: YWRtaW4=       # 'admin'
  DB_PASSWORD: c2VjdXJl   # 'secure'
Enter fullscreen mode Exit fullscreen mode
kubectl apply -f secret.yaml
Enter fullscreen mode Exit fullscreen mode

Creating Secrets with kubectl

3️⃣ Create the Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-config-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: config-app
  template:
    metadata:
      labels:
        app: config-app
    spec:
      automountServiceAccountToken: false
      containers:
      - name: app-container
        image: zaheetdeveloper/k8s-config-demo:v1
        env:
        - name: APP_MODE
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: APP_MODE
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_USER
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_PASSWORD
        ports:
        - containerPort: 3000
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
            ephemeral-storage: "128Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
            ephemeral-storage: "512Mi"
Enter fullscreen mode Exit fullscreen mode
kubectl apply -f deployment.yaml
Enter fullscreen mode Exit fullscreen mode

App Deployment and Get Pods Screenshot


πŸ§ͺ Testing & Debugging

kubectl get pods
kubectl logs -l app=config-app
Enter fullscreen mode Exit fullscreen mode

Expected output:

Server running on port 3000
Enter fullscreen mode Exit fullscreen mode

App Logs Screenshot


kubectl port-forward deployment/app-config-test 3000:3000
Enter fullscreen mode Exit fullscreen mode

Visit in browser: http://localhost:3000
App NodeJs Browser Screenshot


kubectl exec -it pod/<pod-name> -- /bin/sh
env
Enter fullscreen mode Exit fullscreen mode

App Bash and its env Screenshot


πŸ›‘οΈ Best Practices

  • Encrypt secrets at rest using KMS
  • Avoid storing secrets in source code
  • Use RBAC to control access
  • Explore tools like Sealed Secrets or External Secrets Operator

πŸ’¬ Conclusion

You now know how to:

  • Use ConfigMaps and Secrets in Kubernetes
  • Inject them securely into containers
  • Deploy and inspect a working environment

➑️ Demo image: Docker Hub

πŸ“‚ Source code & YAMLs: GitHub

Top comments (0)