Kubernetes Fundamentals · Module 07 of 14

ConfigMaps and Secrets

Separate environment-specific configuration and sensitive values from container images, while understanding the security limits of Kubernetes Secrets.

Learning objectives

By the end of this module, you should be able to:

  • Use ConfigMaps as environment variables or files.
  • Use Secrets without putting credentials directly in manifests or images.
  • Explain why a Secret object is not automatically equivalent to encrypted-at-rest secret management.

ConfigMaps decouple configuration

ConfigMaps store non-confidential key/value or file-like configuration. Pods can consume them through environment variables, command arguments or mounted volumes.

Secrets are for confidential data

Secrets are a distinct API object for passwords, tokens and keys. Base64 encoding in YAML is encoding, not encryption. Kubernetes documentation warns that Secret data is stored unencrypted in etcd by default unless encryption at rest is configured.

Delivery method affects update behavior

Environment variables are captured when the container starts. Mounted ConfigMap/Secret volumes can update eventually, but applications must be able to reread changed files. Immutable rollout patterns are often easier to reason about.

Worked examples

See the idea in practice.

Create configuration safely

kubectl -n gnu-k8s-fundamentals create configmap app-config --from-literal=APP_MODE=training
kubectl -n gnu-k8s-fundamentals create secret generic app-secret --from-literal=API_TOKEN=demo-token
  • ConfigMap is for non-secret configuration.
  • Secret is a separate object; production secret management still needs RBAC, encryption and careful access controls.
Hands-on lab

Lab — Inject config and a secret

Goal: Create configuration objects, consume them in one Pod, verify the values, then clean them up.

Before you start

  • kubectl is installed and can reach the lab cluster.
  • Use the dedicated gnu-k8s-fundamentals namespace unless a step explicitly says otherwise.
STEP 1

Create ConfigMap and Secret

kubectl -n gnu-k8s-fundamentals create configmap cfg-demo --from-literal=APP_MODE=training
kubectl -n gnu-k8s-fundamentals create secret generic secret-demo --from-literal=API_TOKEN=demo-token
STEP 2

Create the Pod

cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: config-demo
  namespace: gnu-k8s-fundamentals
spec:
  containers:
  - name: app
    image: busybox:1.36
    command: ["sh","-c","echo mode=$APP_MODE; echo token-present=${API_TOKEN:+yes}; sleep 3600"]
    env:
    - name: APP_MODE
      valueFrom:
        configMapKeyRef:
          name: cfg-demo
          key: APP_MODE
    - name: API_TOKEN
      valueFrom:
        secretKeyRef:
          name: secret-demo
          key: API_TOKEN
EOF
STEP 3

Wait and inspect safe output

kubectl -n gnu-k8s-fundamentals wait --for=condition=Ready pod/config-demo --timeout=90s
kubectl -n gnu-k8s-fundamentals logs config-demo
STEP 4

Clean up

kubectl -n gnu-k8s-fundamentals delete pod config-demo
kubectl -n gnu-k8s-fundamentals delete configmap cfg-demo
kubectl -n gnu-k8s-fundamentals delete secret secret-demo

Verify

  • APP_MODE is read from the ConfigMap.
  • The Secret value is injected but the example log does not print the secret itself.

Expected outcome

  • Logs show mode=training and token-present=yes.

If it fails

  • If a referenced key/name is wrong, describe the Pod and inspect Events.
  • Avoid kubectl get secret -o yaml in shared terminals because base64 values are trivially reversible.
Real-world connection

Configuration separation allows the same image to be promoted across environments while runtime settings change independently.

Avoid these traps

Common mistakes

  • Committing real secrets to Git because their YAML uses base64.
  • Printing secrets to logs during verification.
  • Expecting environment-variable consumers to see ConfigMap updates without a restart.
Knowledge check

Can you explain it without looking back?

Open each answer only after you have tried to answer the question yourself.

1Is base64-encoded Secret data encrypted?

No. Base64 is encoding, not encryption.

2What should hold non-confidential application configuration?

A ConfigMap is designed for that purpose.

3Why might a Pod fail to start after a ConfigMap name is changed?

Its env/volume references may point to an object or key that no longer exists.