ConfigMap and Secret solve a basic but important problem: how do you keep images immutable while still changing configuration and credentials across environments?

The short answer is simple: regular configuration goes in ConfigMaps, sensitive data goes in Secrets. The operational details are where most teams get into trouble.

What each one is for

  • ConfigMap: non-sensitive configuration such as feature flags, log levels, and app settings.
  • Secret: sensitive data such as passwords, API tokens, and certificates.

Both are namespace-scoped and both are consumed by workloads, but they should not be treated with the same risk model.

Why this matters

If you bake environment-specific values into images, every configuration change becomes an image rebuild. That slows release flow and makes secret rotation awkward.

ConfigMaps and Secrets let you separate deployment artifacts from runtime configuration.

Minimal examples

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  LOG_LEVEL: "info"
---
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
stringData:
  DB_PASSWORD: "changeme"

How workloads consume them

There are two main patterns.

Environment variables

Good for:

  • small configuration values
  • app frameworks that read env directly
  • simple deployment patterns

But remember: environment variables are usually only read at process start, so updates often require restart.

File mounts

Good for:

  • config files
  • certificates and keys
  • applications that can reload file-based config

Mounted files can update on disk, but your app still has to notice and reload them.

Environment variable example

envFrom:
  - configMapRef:
      name: app-config
  - secretRef:
      name: db-secret

Or specific keys:

env:
  - name: LOG_LEVEL
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: LOG_LEVEL
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: db-secret
        key: DB_PASSWORD

File mount example

volumes:
  - name: config
    configMap:
      name: app-config
  - name: secret
    secret:
      secretName: db-secret
volumeMounts:
  - name: config
    mountPath: /etc/app/config
    readOnly: true
  - name: secret
    mountPath: /etc/app/secret
    readOnly: true

Config changes and rollout behavior

This is where many teams get surprised.

  • mounted files can update without recreating the Pod
  • env vars usually require Pod restart
  • applications may still need reload support even if files update underneath

That is why many teams use checksum annotations on Deployments to trigger controlled rollouts when config changes.

ConfigMap vs Secret: what not to do

Do not treat Secret as encrypted by default

Secrets are base64-encoded, not meaningfully protected by that encoding alone. Encryption at rest and access control still matter.

Do not dump large blobs into ConfigMaps

ConfigMaps are not object storage. Large artifacts belong somewhere else.

Do not make every workload read every Secret

That turns compromise of one Pod into access to far more sensitive data than necessary.

Namespace and scoping behavior

ConfigMaps and Secrets are namespace-scoped. The Pod and the referenced object need to be in the same namespace unless you build a higher-level sync mechanism yourself.

This sounds obvious, but cross-namespace assumptions cause a lot of quiet failures.

Security habits worth adopting early

  • enable encryption at rest for Secrets
  • restrict access with RBAC
  • keep Secret scope narrow
  • avoid committing Secrets to git
  • prefer external secret managers for mature production setups

Secret hygiene is not just about secrecy. It is also about reducing blast radius.

Debugging sequence

Start here:

kubectl describe pod <pod-name>
kubectl get configmap app-config -o yaml
kubectl get secret db-secret -o yaml
kubectl exec -it <pod-name> -- ls -l /etc/app/config
kubectl exec -it <pod-name> -- ls -l /etc/app/secret

Then ask:

  1. Is the object in the right namespace?
  2. Are the key names correct?
  3. Is the Pod consuming env vars or mounted files?
  4. Does the app reload config automatically or require restart?

When to choose external secret management

Move beyond native Secrets when:

  • you need stronger auditability
  • you rotate secrets frequently
  • you want central policy and lease control
  • multiple clusters need a shared secret workflow

Native Kubernetes Secrets are a good starting point, not always the final answer.

FAQ

Q: Should every secret live in Kubernetes? A: Not necessarily. Kubernetes Secrets are convenient, but external secret systems may be a better fit for higher-security or multi-cluster environments.

Q: Why did my ConfigMap change not affect the app? A: Because the app may only read config at startup, or it may not watch the mounted files for reload.

Q: When should I prefer file mounts over env vars? A: Prefer file mounts for certificates, richer config files, and applications that support file-based reload behavior.

Next reading

  • Continue with kubernetes-quickstart-probes.md for rollout-safe behavior.
  • Read kubernetes-quickstart-declarative-config.md for safer config workflows.
  • For RBAC and production safety, continue into the tips series.

Wrap-up

ConfigMap and Secret are simple on paper, but operationally they touch rollout behavior, security boundaries, and debugging flow. Treat them as part of the workload contract, not as an afterthought.

References