ConfigMaps & Secrets

Kubernetes Fundamentals

Chapter 7 · ConfigMaps & Secrets

Chapter 6 covered how pods communicate. This chapter covers how to give pods configuration and sensitive data without baking either into the container image itself — a genuinely important separation-of-concerns practice.

Why Externalize Configuration?

Baking configuration values directly into a container image means rebuilding the image every time a value changes, and makes the same image unusable across different environments (dev/staging/prod) without modification. The twelve-factor app principle states config should live in the environment, not in code or images — Kubernetes provides two first-class objects for exactly this: ConfigMaps and Secrets.

ConfigMaps — Non-Sensitive Configuration

A ConfigMap holds key-value configuration data — feature flags, URLs, non-sensitive settings. Created from literal values, files, or directories via kubectl, or declaratively via YAML. Genuinely important to state plainly: a ConfigMap is not encrypted or specially protected — a direct contrast with Secrets, covered next.

Secrets — Sensitive Configuration

Structurally very similar to ConfigMaps, but intended for sensitive data — passwords, API keys, tokens — directly echoing crypto1-11's key management material and pipelines1-5's "never commit credentials" rule, now applied at the Kubernetes object level. Secrets are base64-encoded by default, not encrypted — a critical, commonly misunderstood point worth its own dedicated section.

The Base64 Misconception — A Dedicated Warning

base64 ≠ encryption
Base64-encoding a value and storing it in a Secret does not make it secure by itself. Anyone with read access to the Secret object — or to etcd directly, per Chapter 2's own "etcd holds the entire cluster state" point — can trivially decode it back to plaintext. Base64 is an encoding, not encryption; it provides zero real confidentiality on its own.

Genuine protection requires additional measures: encryption at rest for etcd (crypto1-5/6, dbsec1-5's encryption-at-rest material), RBAC restricting who can read Secret objects at all (Course 2's own k8s2-4 covers this properly), and ideally an external secrets manager (cloud1-11's own KMS/secrets-manager material) for genuinely sensitive production secrets, rather than relying on raw Kubernetes Secrets alone.

Consuming ConfigMaps & Secrets — Two Methods

MethodBehavior
Environment variablesInjected at container startup; a running pod does not pick up a later change, since env vars are only read once
Mounted volumesAppears as files inside the container; updates automatically (with some delay) if the underlying ConfigMap/Secret changes, without restarting the pod
A genuinely practical distinction when designing config consumption
If an application needs to pick up config changes without a restart, mounted volumes are the right choice. If simplicity matters more and a restart-on-change is acceptable (or even desired, tied to a deliberate redeploy), environment variables are fine.

A Concrete Example — ConfigMap as Environment Variables

# ConfigMap apiVersion: v1 kind: ConfigMap metadata: name: app-config data: LOG_LEVEL: "debug" # Referenced in a Deployment's pod spec (Ch.5's own structure) containers: - name: web image: myapp:latest envFrom: - configMapRef: name: app-config

A Concrete Example — Secret as a Mounted Volume

volumes: - name: db-secret-volume secret: secretName: db-credentials containers: - name: web volumeMounts: - name: db-secret-volume mountPath: /etc/secrets

The application reads the database password from a file at /etc/secrets rather than an environment variable — genuinely a more common production pattern for secrets specifically, since environment variables can leak more readily than file contents (process listings, crash dumps, and logging tools frequently capture env vars, less often a file's contents).

A Note on GitOps & Secrets

Since Secrets are only base64-encoded, committing raw Secret YAML files to a git repository is genuinely risky, for exactly the same reason pipelines1-5 flags committing any credential to source control. Tools like Sealed Secrets or External Secrets Operator exist specifically to solve this — keeping genuinely encrypted secret material out of git while still supporting a GitOps workflow, a topic Course 2's k8s2-9 builds on directly.

Hands-On Exercises

Exercise 1

Explain why base64 encoding a Secret's value does not provide real security on its own, and name at least two additional measures that would provide genuine protection.

📄 View solution
Exercise 2

Explain the practical difference between consuming a ConfigMap as an environment variable versus as a mounted volume, specifically regarding what happens when the ConfigMap's value changes after the pod is already running.

📄 View solution
Exercise 3

Explain why committing a raw Kubernetes Secret YAML file to a git repository is risky, and name a category of tool that exists specifically to solve this problem for GitOps workflows.

📄 View solution

Chapter 7 Quick Reference

  • ConfigMaps — non-sensitive config, not encrypted or protected
  • Secrets — for sensitive data, but only base64-encoded, not encrypted; needs etcd encryption at rest + RBAC + ideally an external secrets manager for real protection
  • Env vars — simple, but read once at startup; a running pod won't pick up a later change
  • Mounted volumes — update automatically without a restart; also the safer default for secrets specifically (less prone to leaking than env vars)
  • Never commit a raw Secret YAML to git — Sealed Secrets/External Secrets Operator exist to solve this for GitOps (k8s2-9)
  • Next chapter: Storage in Kubernetes — Volumes, PersistentVolumes/PersistentVolumeClaims, StorageClasses