Nextgen Blog
HomeLearnAIQuantumRoboticsSecuritySpaceAbout
Nextgen Blog

By Anubhav — full stack engineer, IIT Mandi CSE. Deep dives into AI, software engineering, and the technologies shaping the next generation of tech.

Navigate

  • Home
  • Learn
  • Blog
  • Archive
  • About

Topics

  • Artificial Intelligence
  • Quantum Computing
  • Robotics
  • Cybersecurity
  • Space Tech

Connect

Built with ❤️ & By - Anubhav

© 2026 Nextgen Blog by Anubhav. All rights reserved.

Privacy PolicyTerms of Service
Phase 02 · Core WorkloadsChapter 10 of 33
09.
Phase 02Read time ~11 minDifficulty intermediate

ConfigMaps & Secrets

Warrior, now we move from Kubernetes infrastructure to something you'll use constantly in real applications:

In this chapter
  • 01The Problem
  • 02ConfigMap
  • 03Creating a ConfigMap
  • 04Imperative way
  • 05ConfigMap YAML
  • 06Using ConfigMap in a Pod
  • 07What Does envFrom Do?
  • 08Accessing It in Node.js
  • 09Injecting Individual Values
  • 10ConfigMap as a File
  • 11Now: Secrets
  • 12Creating a Secret
  • 13Secret YAML
  • 14VERY IMPORTANT: Base64 ≠ Encryption
  • 15Better Secret YAML with stringData
  • 16Using Secret in a Deployment
  • 17ConfigMap + Secret Together
  • 18Real Node.js Example
  • 19ConfigMap
  • 20Secret
  • 21Deployment
  • 22The Flow
  • 23Environment Variables vs ConfigMap
  • 24Environment variable
  • 25ConfigMap
  • 26Secret Security
  • 27Don't Do This ❌
  • 28Better Production Architecture
  • 29ConfigMap vs Secret
  • 30One Important Gotcha: Updates
  • 31ConfigMap Does Not Automatically Restart Pods
  • 32Practical Exercise
  • 33Step 1 — Create namespace
  • 34Step 2 — Create ConfigMap
  • 35Step 3 — Create Secret
  • 36Step 4 — Create Pod
  • 37Step 5 — Enter the Pod
  • 38Important Commands
  • 39Interview Questions
  • 40Q1. What is a ConfigMap?
  • 41Q2. What is a Secret?
  • 42Q3. Is Kubernetes Secret encrypted by default?
  • 43Q4. How can a Pod consume a ConfigMap?
  • 44Q5. How can a Pod consume a Secret?
  • 45Q6. Should passwords be stored in ConfigMaps?
  • 46Q7. Does changing a ConfigMap automatically restart Pods?
  • 47Your Kubernetes architecture so far
  • 48Next → Chapter 10: Volumes & Persistent Storage
In this chapter (48 sections)
01The Problem02ConfigMap03Creating a ConfigMap04Imperative way05ConfigMap YAML06Using ConfigMap in a Pod07What Does envFrom Do?08Accessing It in Node.js09Injecting Individual Values10ConfigMap as a File11Now: Secrets12Creating a Secret13Secret YAML14VERY IMPORTANT: Base64 ≠ Encryption15Better Secret YAML with stringData16Using Secret in a Deployment17ConfigMap + Secret Together18Real Node.js Example19ConfigMap20Secret21Deployment22The Flow23Environment Variables vs ConfigMap24Environment variable25ConfigMap26Secret Security27Don't Do This ❌28Better Production Architecture29ConfigMap vs Secret30One Important Gotcha: Updates31ConfigMap Does Not Automatically Restart Pods32Practical Exercise33Step 1 — Create namespace34Step 2 — Create ConfigMap35Step 3 — Create Secret36Step 4 — Create Pod37Step 5 — Enter the Pod38Important Commands39Interview Questions40Q1. What is a ConfigMap?41Q2. What is a Secret?42Q3. Is Kubernetes Secret encrypted by default?43Q4. How can a Pod consume a ConfigMap?44Q5. How can a Pod consume a Secret?45Q6. Should passwords be stored in ConfigMaps?46Q7. Does changing a ConfigMap automatically restart Pods?47Your Kubernetes architecture so far48Next → Chapter 10: Volumes & Persistent Storage

How does your application get configuration and sensitive values inside Kubernetes?

For example, your Node.js application may need:

NODE_ENV=production
PORT=3000
DATABASE_URL=...
REDIS_HOST=redis-service
JWT_SECRET=...
OPENAI_API_KEY=...

You should not hardcode these values into your source code or Docker image.

Kubernetes gives us two major objects:

ConfigMap  → non-sensitive configuration
Secret     → sensitive data

1. The Problem#

Suppose your Node.js code contains:

const databaseUrl =
  "postgresql://admin:password123@postgres:5432/mydb";

This is a bad practice.

Why?

Because the secret is now inside your:

Source code
   ↓
Git
   ↓
Docker image
   ↓
Deployment

Anyone with access to the repository/image may potentially see it.

Instead:

Node.js Application
        ↑
        │
   Environment
    Variables
        ↑
   ┌────┴─────┐
   │          │
ConfigMap   Secret

2. ConfigMap#

A ConfigMap stores non-sensitive configuration data.

Examples:

NODE_ENV=production
PORT=3000
API_URL=https://api.example.com
LOG_LEVEL=info
REDIS_HOST=redis-service

Don't use ConfigMap for passwords, API keys, tokens, etc.


3. Creating a ConfigMap#

Imperative way#

kubectl create configmap app-config \
  --from-literal=NODE_ENV=production \
  --from-literal=PORT=3000

Check:

kubectl get configmaps

or:

kubectl get cm

4. ConfigMap YAML#

The declarative approach is:

apiVersion: v1
kind: ConfigMap
 
metadata:
  name: app-config
 
data:
  NODE_ENV: "production"
  PORT: "3000"
  LOG_LEVEL: "info"

Apply:

kubectl apply -f configmap.yaml

Check:

kubectl get configmap app-config

To see its contents:

kubectl describe configmap app-config

5. Using ConfigMap in a Pod#

Creating a ConfigMap isn't enough.

Your application needs to consume it.

Example:

apiVersion: apps/v1
kind: Deployment
 
metadata:
  name: node-api
 
spec:
  replicas: 2
 
  selector:
    matchLabels:
      app: node-api
 
  template:
    metadata:
      labels:
        app: node-api
 
    spec:
      containers:
        - name: node-api
          image: my-node-api:1.0
 
          envFrom:
            - configMapRef:
                name: app-config

Now Kubernetes injects:

NODE_ENV
PORT
LOG_LEVEL

into the container's environment.


6. What Does envFrom Do?#

This:

envFrom:
  - configMapRef:
      name: app-config

means:

Take all key-value pairs from app-config and make them environment variables inside the container.

So:

data:
  NODE_ENV: "production"
  PORT: "3000"

becomes:

Container
 
NODE_ENV=production
PORT=3000

7. Accessing It in Node.js#

Your Node.js application can then use:

console.log(process.env.NODE_ENV);
console.log(process.env.PORT);

For example:

const port = process.env.PORT || 3000;
 
app.listen(port, () => {
  console.log(`Server running on ${port}`);
});

Your application doesn't need to know where the configuration came from.


8. Injecting Individual Values#

You don't always want every ConfigMap value.

Suppose:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
 
data:
  NODE_ENV: "production"
  PORT: "3000"
  LOG_LEVEL: "info"

You can select only one:

env:
  - name: NODE_ENV
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: NODE_ENV

Now only:

NODE_ENV

is injected.


9. ConfigMap as a File#

ConfigMaps can also be mounted as files.

Example:

apiVersion: v1
kind: Pod
 
metadata:
  name: nginx
 
spec:
  containers:
    - name: nginx
      image: nginx
 
      volumeMounts:
        - name: config
          mountPath: /etc/myconfig
 
  volumes:
    - name: config
      configMap:
        name: app-config

Kubernetes can expose the ConfigMap data as files inside:

/etc/myconfig

This is useful for configuration files such as:

nginx.conf
application.properties
config.json

10. Now: Secrets#

This is extremely important.

A Secret stores sensitive configuration.

Examples:

DATABASE_PASSWORD
JWT_SECRET
API_KEY
AWS_ACCESS_KEY
OAuth credentials
TLS certificates

Conceptually:

ConfigMap
   ↓
Public/non-sensitive configuration
 
Secret
   ↓
Sensitive configuration

11. Creating a Secret#

Imperative:

kubectl create secret generic db-secret \
  --from-literal=DB_USER=admin \
  --from-literal=DB_PASSWORD=myPassword123

Check:

kubectl get secrets

You might see:

NAME         TYPE     DATA
db-secret    Opaque   2

Notice Kubernetes doesn't normally display the values in kubectl get secrets.


12. Secret YAML#

You may see Secrets written like:

apiVersion: v1
kind: Secret
 
metadata:
  name: db-secret
 
type: Opaque
 
data:
  DB_USER: YWRtaW4=
  DB_PASSWORD: bXlQYXNzd29yZDEyMw==

Those values are Base64 encoded.

For example:

admin

becomes:

YWRtaW4=

13. VERY IMPORTANT: Base64 ≠ Encryption#

This is one of the most important Kubernetes interview questions.

If you see:

YWRtaW4=

you can decode it.

For example:

echo "YWRtaW4=" | base64 --decode

Result:

admin

Therefore:

Kubernetes Secret data being Base64 encoded does NOT mean the data is encrypted.

Think:

Base64
   ↓
Encoding

not:

Base64
   ↓
Encryption

14. Better Secret YAML with stringData#

Instead of manually encoding values, you can use:

apiVersion: v1
kind: Secret
 
metadata:
  name: db-secret
 
type: Opaque
 
stringData:
  DB_USER: admin
  DB_PASSWORD: myPassword123

Kubernetes handles the conversion.

This is convenient, but putting plaintext secrets in Git is still a security problem.

For production, teams often use external secret-management systems such as:

AWS Secrets Manager
Azure Key Vault
Google Secret Manager
HashiCorp Vault
External Secrets Operator

15. Using Secret in a Deployment#

Just like ConfigMap:

apiVersion: apps/v1
kind: Deployment
 
metadata:
  name: node-api
 
spec:
  replicas: 2
 
  selector:
    matchLabels:
      app: node-api
 
  template:
    metadata:
      labels:
        app: node-api
 
    spec:
      containers:
        - name: node-api
          image: my-node-api:1.0
 
          envFrom:
            - secretRef:
                name: db-secret

Now the container receives:

DB_USER
DB_PASSWORD

as environment variables.


16. ConfigMap + Secret Together#

This is a very common real-world pattern.

containers:
  - name: node-api
    image: my-node-api:1.0
 
    envFrom:
      - configMapRef:
          name: app-config
 
      - secretRef:
          name: db-secret

Architecture:

                    Node.js Pod
                        │
             ┌──────────┴──────────┐
             │                     │
        ConfigMap                Secret
             │                     │
       non-sensitive             sensitive
             │                     │
             └──────────┬──────────┘
                        │
                  Environment
                    Variables

17. Real Node.js Example#

Imagine your application needs:

NODE_ENV
PORT
DATABASE_URL
REDIS_HOST
JWT_SECRET

We can separate them.

ConfigMap#

apiVersion: v1
kind: ConfigMap
 
metadata:
  name: node-api-config
 
data:
  NODE_ENV: "production"
  PORT: "3000"
  REDIS_HOST: "redis-service"

Secret#

apiVersion: v1
kind: Secret
 
metadata:
  name: node-api-secret
 
type: Opaque
 
stringData:
  DATABASE_URL: "postgresql://admin:password@postgres:5432/app"
  JWT_SECRET: "super-secret-key"

Deployment#

apiVersion: apps/v1
kind: Deployment
 
metadata:
  name: node-api
 
spec:
  replicas: 3
 
  selector:
    matchLabels:
      app: node-api
 
  template:
    metadata:
      labels:
        app: node-api
 
    spec:
      containers:
        - name: node-api
          image: my-node-api:1.0
          ports:
            - containerPort: 3000
 
          envFrom:
            - configMapRef:
                name: node-api-config
 
            - secretRef:
                name: node-api-secret

Your Node.js application can simply do:

const {
  NODE_ENV,
  PORT,
  DATABASE_URL,
  REDIS_HOST,
  JWT_SECRET
} = process.env;

18. The Flow#

This is the mental model I want you to remember:

                  Kubernetes
                      │
          ┌───────────┴───────────┐
          │                       │
      ConfigMap                 Secret
          │                       │
          │                       │
          └───────────┬───────────┘
                      │
                  Deployment
                      │
                      ▼
                    Pod
                      │
                      ▼
                Node.js Container
                      │
                      ▼
              process.env.*

19. Environment Variables vs ConfigMap#

Don't confuse these concepts.

Environment variable#

PORT=3000

is simply a value available to the process.

ConfigMap#

PORT=3000

is Kubernetes-managed configuration that can be injected into the application.

So:

ConfigMap → source of configuration
Environment variable → one way to deliver it to application

20. Secret Security#

Secrets deserve special attention.

A common misconception is:

"If it's a Kubernetes Secret, it's automatically completely secure."

That's not correct.

You need to consider:

RBAC
   ↓
Who can read the Secret?
 
API Server
   ↓
How is it accessed?
 
etcd
   ↓
How is it stored?
 
Encryption at rest
   ↓
Is etcd data encrypted?
 
External secret manager
   ↓
Can sensitive credentials stay outside Kubernetes?

Kubernetes supports encryption at rest for Secret data, but the exact configuration depends on the cluster.


21. Don't Do This ❌#

Don't commit:

stringData:
  DATABASE_PASSWORD: "MyRealPassword123"

to a public Git repository.

Also avoid:

const password = "MyRealPassword123";

inside application code.

And don't bake secrets into a Dockerfile:

ENV DATABASE_PASSWORD="MyRealPassword123"

Bad idea.


22. Better Production Architecture#

A more mature architecture looks like:

Developer
    │
    ▼
Git Repository
    │
    │ application code
    ▼
Docker Image
    │
    ▼
Kubernetes
    │
    ├── ConfigMap
    │
    └── External Secret Manager
             │
             ├── AWS Secrets Manager
             ├── Azure Key Vault
             ├── GCP Secret Manager
             └── Vault

The application receives the values at runtime.


23. ConfigMap vs Secret#

Feature ConfigMap Secret
Purpose Configuration Sensitive data
Passwords ❌ ✅
API keys ❌ ✅
NODE_ENV ✅ ❌
PORT ✅ ❌
Base64 encoding No requirement Commonly used
Encryption Not inherently Can be encrypted at rest
Environment variables ✅ ✅
Volume mount ✅ ✅

24. One Important Gotcha: Updates#

Suppose your ConfigMap contains:

LOG_LEVEL=info

and you change it to:

LOG_LEVEL=debug

What happens to your application?

It depends on how the ConfigMap is consumed.

If injected as environment variables:

envFrom:
  - configMapRef:
      name: app-config

existing containers do not automatically receive the changed environment variable.

You generally need to restart/recreate the Pods.

For example:

kubectl rollout restart deployment node-api

If a ConfigMap is mounted as a volume, Kubernetes can update the mounted files eventually, although applications may still need to reload the configuration themselves.

This distinction is important in production.


25. ConfigMap Does Not Automatically Restart Pods#

Another common interview question.

If:

ConfigMap changes

Kubernetes does not automatically perform a Deployment rollout merely because the ConfigMap changed.

Common deployment tooling patterns use annotations/checksums or explicitly trigger a rollout.

For example:

kubectl rollout restart deployment/node-api

26. Practical Exercise#

Let's create a small setup.

Step 1 — Create namespace#

kubectl create namespace config-demo

Step 2 — Create ConfigMap#

kubectl create configmap app-config \
  --from-literal=APP_NAME=MyNodeApp \
  --from-literal=APP_ENV=development \
  -n config-demo

Step 3 — Create Secret#

kubectl create secret generic app-secret \
  --from-literal=API_KEY=my-secret-key \
  -n config-demo

Step 4 — Create Pod#

apiVersion: v1
kind: Pod
 
metadata:
  name: config-demo
  namespace: config-demo
 
spec:
  containers:
    - name: app
      image: busybox
      command: ["sh", "-c", "env; sleep 3600"]
 
      envFrom:
        - configMapRef:
            name: app-config
 
        - secretRef:
            name: app-secret

Apply:

kubectl apply -f pod.yaml

Step 5 — Enter the Pod#

kubectl exec -it config-demo -n config-demo -- sh

Then:

env

You should find:

APP_NAME=MyNodeApp
APP_ENV=development
API_KEY=my-secret-key

Congratulations—you've just injected Kubernetes configuration into a container.


27. Important Commands#

kubectl get configmaps
kubectl get cm
kubectl describe configmap app-config
kubectl get secrets
kubectl describe secret app-secret
kubectl create configmap app-config \
  --from-literal=KEY=value
kubectl create secret generic app-secret \
  --from-literal=KEY=value
kubectl delete configmap app-config
kubectl delete secret app-secret

28. Interview Questions#

Q1. What is a ConfigMap?#

A Kubernetes object used to store non-sensitive configuration data separately from application code and container images.

Q2. What is a Secret?#

A Kubernetes object intended for sensitive data such as passwords, tokens, and API keys.

Q3. Is Kubernetes Secret encrypted by default?#

Don't simply say "yes."

A better answer:

Secret data is commonly represented using Base64 in Kubernetes manifests/API responses, which is encoding rather than encryption. Kubernetes supports encryption at rest, but whether it is configured depends on the cluster.

Q4. How can a Pod consume a ConfigMap?#

Two common methods:

Environment variables
       OR
Mounted files

Q5. How can a Pod consume a Secret?#

Again:

Environment variables
       OR
Mounted files

Q6. Should passwords be stored in ConfigMaps?#

No.

Use Secrets or, preferably for many production environments, an integrated external secret-management system.

Q7. Does changing a ConfigMap automatically restart Pods?#

No.

Especially when consumed as environment variables, existing Pods retain their existing environment until recreated/restarted.


🧠 Chapter 9 Cheat Sheet#

ConfigMap
   ↓
Non-sensitive configuration
 
Secret
   ↓
Sensitive configuration
 
Deployment
   ↓
envFrom
   ↓
ConfigMap / Secret
   ↓
Container
   ↓
process.env

Remember:

ConfigMap = configuration Secret = sensitive configuration

And the most important security lesson:

Base64 is encoding, not encryption.


Your Kubernetes architecture so far#

                         CLUSTER
                            │
              ┌─────────────┴─────────────┐
              │                           │
             DEV                        PROD
              │                           │
        ┌─────┴─────┐               ┌─────┴─────┐
        │           │               │           │
   Deployment    Service       Deployment    Service
        │                           │
   ReplicaSet                   ReplicaSet
        │                           │
      Pods                         Pods
        │                           │
   Containers                   Containers
        ↑                           ↑
   ConfigMap                    ConfigMap
   Secret                       Secret

You now understand how an application is deployed and how configuration reaches it.

Next → Chapter 10: Volumes & Persistent Storage#

We'll solve another major container problem:

"What happens to my data when the Pod dies?"

You'll learn:

Volumes → emptyDir → PersistentVolume → PersistentVolumeClaim → StorageClass → dynamic provisioning → Stateful applications like PostgreSQL.

Finished this chapter?

Mark it as complete to track your mastery.

Previous ChapterChapter 8 — Kubernetes NamespacesNext ChapterChapter 10 — Volumes & Persistent Storage
PrevNext