ConfigMaps and Secrets

ConfigMaps and Secrets

Configuration lives in the environment, not in the image. The same image runs in dev and in prod - only the ConfigMap differs.

graph LR CM[ConfigMap app-cfg] -->|env var| P[Pod] SEC[Secret db-cred] -->|env var| P CM -->|mounted file| P
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-cfg
data:
  DATACENTER: dc01
  app.properties: |
    color=blue

Two ways to consume it:

env:                                   # 1 - one key as a variable
  - name: DATACENTER
    valueFrom:
      configMapKeyRef: { name: app-cfg, key: DATACENTER }

volumes:                               # 2 - whole ConfigMap as files
  - name: cfg
    configMap: { name: app-cfg }

Mounted files update by themselves (within a minute or so, when the kubelet syncs). Environment variables do not - they are set once at container start, so the Pod must be restarted: kubectl rollout restart deploy/....

Secret

Same shape, different intent. Values are base64 in the manifest, which is encoding, not encryption - anyone who can read the Secret sees the value.

kubectl create secret generic db-cred \
  --from-literal=username=app --from-literal=password=S3cret
kubectl get secret db-cred -o jsonpath='{.data.password}' | base64 -d
envFrom:
  - secretRef: { name: db-cred }

Use stringData when writing one by hand. Never commit a real Secret to Git - use sealed-secrets, SOPS or an external store. Protection comes from RBAC and encryption at rest, not from the encoding.

References