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)