Skip to content

Phase 3: Configuration and State

Time: week 3. Goal: everything you currently do with environment:, .env, and volumes:.

ConfigMap

Non-secret configuration, consumed two ways:

  • As environment variables (envFrom / valueFrom).
  • As mounted files (a ConfigMap key becomes a file in the container).

Secret

Same mechanics as ConfigMap, different intent. Two things to know:

  • Base64 is NOT encryption. It's encoding. Anyone with read access to the Secret reads the value.
  • Real clusters layer something on top: encryption at rest, or external managers (Vault, cloud secret stores, External Secrets Operator). Awareness only for now.

Volumes

  • emptyDir: scratch space, dies with the pod.
  • hostPath: a directory on the node. Almost never in real clusters - pods move between nodes.
  • The real model: PersistentVolume (the disk), PersistentVolumeClaim (a request for a disk), StorageClass (how disks get provisioned automatically). In practice you write a PVC, the StorageClass dynamically provisions the PV, and you mount the claim.

Probes

The feature compose barely has, and it matters enormously:

  • Readiness probe: gates traffic. Failing readiness means the Service stops sending requests to this pod. Use it for "I'm up but my DB connection isn't ready yet".
  • Liveness probe: restarts wedged containers. Use sparingly - a bad liveness probe causes restart storms.
  • Startup probe: for slow-booting apps, disables the other probes until first success.

Resource requests and limits

  • Requests drive scheduling: the scheduler places pods on nodes with enough unreserved capacity.
  • Limits drive throttling (CPU) and OOM kills (memory).

Most production incidents trace back to getting these wrong. No requests means the scheduler packs blindly; too-low memory limits mean random OOMKilled pods.

StatefulSet

When Deployments aren't enough: stable network identity (db-0, db-1), ordered startup, one PVC per replica. Databases and queues live here - if you run them in-cluster at all.

The honest take: for production databases, a managed service outside the cluster is usually the boring, correct answer. Run Postgres in k8s for dev/test; think hard before doing it in prod.

Exercise

Full playbook with complete manifests (Postgres + Adminer): Lab 3.

Deploy an app + Postgres pair:

  1. App config via ConfigMap (env vars).
  2. DB password via Secret, referenced by both app and DB.
  3. Postgres data on a PVC.
  4. Readiness probe on the app so it only receives traffic once it can reach the DB.
  5. Kill the Postgres pod and verify data survives (the PVC reattaches).

Checkpoint

  • You can explain the difference between readiness and liveness, and what happens when each fails.
  • You can explain requests vs limits in one sentence each.
  • You know why base64 secrets are not "secure" and what people do about it.

Next: Phase 4: Traffic from the Outside World

A VineLab lab. Released under the MIT License.