Question 16 · Section 14

What is the Difference Between ConfigMap and Secret?

For regular settings:

Language versions: English Russian Ukrainian

Junior Level

Simple Explanation

ConfigMap and Secret are Kubernetes objects for storing application settings separately from code. The difference is that ConfigMap is for regular settings, while Secret is for passwords and sensitive data.

Simple Analogy

  • ConfigMap — like a sticky note on the monitor with settings (server address, port)
  • Secret — like a safe with passwords and keys

ConfigMap

For regular settings:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DB_HOST: "postgres.default.svc.cluster.local"
  DB_PORT: "5432"
  APP_ENV: "production"

Secret

For passwords and keys:

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  DB_PASSWORD: cGFzc3dvcmQxMjM=    # base64 of "password123"
  API_KEY: c2VjcmV0LWtleQ==        # base64 of "secret-key"

Important: base64 is not encryption! It is just encoding. Anyone can decode it.

How to Use in a Pod?

As environment variables:

containers:
- name: app
  image: myapp
  env:
  - name: DB_HOST
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: DB_HOST
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: app-secret
        key: DB_PASSWORD

As files (volume):

volumes:
- name: config-volume
  configMap:
    name: app-config
- name: secret-volume
  secret:
    secretName: app-secret

Comparison

  ConfigMap Secret
Data Plain text Base64
Purpose Settings Passwords, keys
Security Low Medium (needs RBAC)

What a Junior Developer Should Remember

  • ConfigMap — for regular settings, Secret — for passwords
  • Secrets are stored in base64 (this is not encryption!)
  • Both can be used as environment variables or as files
  • Files from ConfigMap/Secret are updated without Pod restart
  • Do not store secrets in git — use external secrets

When NOT to Use ConfigMap/Secret

Do NOT store in ConfigMap: large files (>1MB limit), binary files. Do NOT store in Secret: external system secrets (third-party API keys) — use Vault instead.


Middle Level

Data Storage

ConfigMap:

  • Data in plain text in etcd
  • Size limit: 1 MB (etcd limitation)

Secret:

  • Data in base64 (NOT encryption! base64 is easily decoded). For encryption, use EncryptionConfiguration or external solution (Vault, Sealed Secrets).
  • Secrets are stored in etcd in plain text (unless EncryptionConfiguration is enabled). Access to etcd = access to all Secrets.
  • For real protection, you need to enable Encryption at Rest in etcd

Two Ways to Use

1. Environment Variables

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

Pro: simple Con: not updated “on the fly” without Pod restart

2. Volumes (file mounting)

volumeMounts:
- name: config-volume
  mountPath: /etc/config
  readOnly: true

Pro: updated automatically (Kubelet updates files) Con: application must be able to re-read config

Immutable ConfigMap/Secret

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: "production"
immutable: true    # Cannot be modified after creation

Advantages:

  • Protection from accidental changes
  • Reduces load on kube-apiserver
  • Kubelet doesn’t monitor for changes

External Secrets

For large projects, use External Secrets Operator:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
spec:
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: db-credentials-secret
  data:
  - secretKey: DB_PASSWORD
    remoteRef:
      key: prod/db/password

Synchronizes secrets from HashiCorp Vault, AWS Secrets Manager, Azure Key Vault.

What a Middle Developer Should Remember

  • Secret in base64 ≠ encryption. Needs additional configuration.
  • Env vars are not updated, volumes — updated automatically
  • Immutable objects protect from accidental changes
  • External Secrets Operator — production standard
  • RBAC: restrict access to Secrets

Senior Level

Secret Storage Architecture

Without Encryption at Rest:

etcd stores: DB_PASSWORD: cGFzc3dvcmQxMjM=
Anyone with access to etcd can decode.

With Encryption at Rest:

# kube-apiserver configuration
encryption-provider-config:
  kind: EncryptionConfiguration
  resources:
  - resources: ["secrets"]
    providers:
    - aescbc:
        keys:
        - name: key1
          secret: <base64-encoded-key>
    - identity: {}

Now secrets are encrypted in etcd.

Security: Deep Analysis

Level Protection Description
Base64 only None Anyone with etcd/API access can read
RBAC Partial Restricts API access
Encryption at Rest Good Encrypts data in etcd
External KMS Best Encryption keys outside the cluster

RBAC for Secrets

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list"]
  resourceNames: ["app-secret"]  # only specific secret

Comparison: Env vs Volume

Aspect Env Vars Volumes
Update Requires Pod restart Automatic
Size Good for simple values Good for files
Security Visible in kubectl describe pod Only via exec into container
Hot reload No Yes (application must re-read)

Spring Boot + ConfigMap/Secret

ConfigMap as application.properties:

apiVersion: v1
kind: ConfigMap
metadata:
  name: spring-config
data:
  application.properties: |
    spring.datasource.url=jdbc:postgresql://db:5432/mydb
    spring.jpa.hibernate.ddl-auto=validate
volumeMounts:
- name: config
  mountPath: /config
  readOnly: true
env:
- name: SPRING_CONFIG_LOCATION
  value: "file:/config/application.properties"

Secret Management: Evolution

Level 0: Secrets in git (anti-pattern)
Level 1: Kubernetes Secrets (base64)
Level 2: Secrets + Encryption at Rest
Level 3: External Secrets Operator + Vault/KMS
Level 4: Service Mesh (mTLS) + SPIFFE/SPIRE (identity)

Immutable Objects: When to Use

immutable: true

Use when:

  • Configuration does not change between deployments
  • You want additional protection from changes
  • Reducing API server load (large ConfigMaps)

Do not use when:

  • Settings change dynamically
  • A/B testing with different configs

Troubleshooting

Secret not mounting:

kubectl describe pod myapp
# Warning: Couldn't find secret app-secret in namespace default

Causes:

  1. Secret not created
  2. Secret in a different namespace
  3. Typo in the name

ConfigMap updated but Pod doesn’t see changes:

  • Volume update delay: Kubelet updates files with a delay (syncPeriod, default 1 min)
  • Application doesn’t re-read the file — needs hot reload mechanism

Summary for Senior

  • ConfigMap for configs, Secret — for passwords.
  • Secret is not secure by default without Encryption at Rest or external KMS.
  • Prefer file mounting for hot reload.
  • External Secrets Operator + Vault/KMS — production standard.
  • RBAC: restrict Secret access on the principle of least privilege.
  • Immutable objects: protection from changes + reduced API server load.
  • Spring Boot: mount ConfigMap as application.properties for dynamic configuration.

Interview Cheat Sheet

Must know:

  • ConfigMap — regular settings (text), Secret — sensitive data (base64)
  • Base64 ≠ encryption! Anyone can decode; needs Encryption at Rest
  • Both can be used as env vars (not updated without restart) or volumes (auto-update)
  • Size limit: 1 MB (etcd limitation)
  • Immutable ConfigMap/Secret — protection from changes + reduced API server load
  • External Secrets Operator + Vault/KMS — production standard
  • RBAC: restrict Secret access on the principle of least privilege

Common follow-up questions:

  • “Are Secrets stored securely?” — No by default (base64 in etcd); needs EncryptionConfiguration
  • “Env vars vs volumes?” — Volumes are updated automatically, env vars require Pod restart
  • “What is External Secrets Operator?” — Synchronizes secrets from Vault, AWS Secrets Manager, Azure Key Vault
  • “When to use immutable?” — When config doesn’t change between deployments (protection + performance)

Red flags (DO NOT say):

  • “Secrets are encrypted in K8s” (only base64; need to enable Encryption at Rest)
  • “I store secrets in git in base64” (this is not encryption, anyone can decode)
  • “ConfigMap for passwords” (use Secret)
  • “Env vars are updated without restart” (only volumes auto-update)

Related topics:

  • [[What is Kubernetes and why is it needed]] — K8s objects
  • [[What is Ingress in Kubernetes]] — TLS secrets
  • [[How to monitor applications in Kubernetes]] — configuration monitoring