Handbooks / Kubernetes / Chapter 3

ConfigMaps and Secrets

7 pages · ~5 min✓ Reviewed

Builds on Services and Ingress. Next up: Storage.

KubernetesPage 1

ConfigMaps and Secrets: The Mental Model

1. What They Are

ConfigMapSecret
Holdsplain configsensitive data
Shapekey/value, strings or filessame
Scopenamespacednamespaced
Extranonetmpfs on node, redacted in describe
Storedetcdetcd

2. Encoded, Not Encrypted

  • base64 is reversible encoding, no key
  • Anyone who can read the Secret can decode it
bash
echo -n 'pw' | base64
echo cHc= | base64 -d
output
cHc=
pw

3. Write and Protect

  • data: = base64 values
  • stringData: = plain text, converted on write, never returned
  • Pods consume both without an image rebuild
  • At rest: EncryptionConfiguration on the API server (etcd)
  • RBAC: restrict get/list on secrets
  • Size limit 1 MiB per object
KubernetesPage 2

Env Vars vs Mounted Files

1. Two Ways In

  • One key: env.valueFrom.configMapKeyRef or secretKeyRef
  • All keys: envFrom; value is fixed at container start
  • Volume: each key becomes a file under mountPath
yaml
envFrom:
- configMapRef: {name: app}
volumeMounts:
- {name: sec, mountPath: /etc/db}
volumes:
- name: sec
  secret: {secretName: db, defaultMode: 0400}

mount secrets as files, mode 0400

2. Updates and Trade-offs

Env varMounted file
Live updatenever, restart podyes, kubelet, up to ~1 min
ExceptionsnonesubPath, immutable: true
Best forsimple, 12-factorsecrets, big or multi-line, reload
Leaks viakubectl exec env, crash dumpsfile mode
Config changed?

Env needs kubectl rollout restart deploy/app; files refresh alone.

3. Interview Point

  • Env or volume for a DB password? Volume: out of env dumps, 0400
  • Running pod sees a ConfigMap change? Files yes, env no
  • What does subPath break? Automatic file refresh
  • Roll pods after a change? kubectl rollout restart deploy/app
KubernetesPage 3

Namespaces: Scoping and Isolation

1. Namespace Basics

  • Namespace = virtual cluster partition; scopes names
  • Defaults: default, kube-system, kube-public, kube-node-lease
  • List cluster-scoped kinds: kubectl api-resources --namespaced=false
NamespacedCluster-scoped
ConfigMap, SecretNode
Pod, Service, RolePersistentVolume
ServiceAccountNamespace, ClusterRole, StorageClass

2. Crossing Namespaces

  • Pod reads ConfigMap/Secret only from its own namespace
  • Needed elsewhere: copy or recreate the object per namespace
  • Cross-namespace DNS: svc.namespace.svc.cluster.local

3. Not a Boundary

NeedAdd
Block trafficNetworkPolicy
Cap team usageResourceQuota, LimitRange
Limit accessRBAC
  • Set default: kubectl config set-context --current --namespace=dev

4. Interview Point

  • Cluster-scoped? Node, PV, Namespace, ClusterRole, StorageClass
  • Pod in ns A mounts Secret from ns B? No; copy it into A
  • Namespace isolates traffic? No; add NetworkPolicy
  • Limit a team's resources? ResourceQuota plus LimitRange
KubernetesPage 4

RBAC and Service Accounts Basics

1. Roles and Bindings

  • Additive allow-only: no deny rules
  • Rule = apiGroups, resources, verbs
  • Verbs: get list watch create update patch delete
  • A binding grants a Role or ClusterRole to a User, Group or ServiceAccount
ObjectScope
Roleone namespace
ClusterRolecluster-wide
RoleBindingONE namespace
ClusterRoleBindingcluster-wide

2. Service Accounts

  • ServiceAccount = pod identity; one default per namespace
  • Set spec.serviceAccountName
  • Short-lived projected token at /var/run/secrets/kubernetes.io/serviceaccount
  • No API calls: automountServiceAccountToken: false

3. Example: Read ConfigMaps in dev

bash
kubectl create role cm-reader --verb=get,list --resource=configmaps -n dev
kubectl create rolebinding rb --role=cm-reader --serviceaccount=dev:app-sa -n dev
kubectl auth can-i get secrets --as=system:serviceaccount:dev:app-sa -n dev
output
role.rbac.authorization.k8s.io/cm-reader created
rolebinding.rbac.authorization.k8s.io/rb created
no
Least privilege

Avoid the default SA and cluster-admin. list on secrets returns every value, so grant it rarely.

KubernetesPage 5

Everyday Commands and Common Mistakes

1. Create and Inspect

  • --from-literal sets one key; --from-file loads a file as a key
  • .data holds base64, so decode it with base64 -d
bash
kubectl create configmap app --from-literal=K=V --from-file=app.properties
kubectl create secret generic db --from-literal=pw=s3cret
kubectl get secret db -o jsonpath='{.data.pw}' | base64 -d

2. Silent Failures

  • echo 'pw' | base64 adds a trailing newline: password never matches
  • Use echo -n, or stringData
  • Env vars never update in a running pod
  • Missing key or object gives CreateContainerConfigError; optional: true tolerates it
SymptomCheckFix
CreateContainerConfigErrorkubectl describe pod eventsCreate key/object, or optional: true
Old config in podPod started before changekubectl rollout restart deploy/app
403 Forbiddenkubectl auth can-iAdd a narrow Role + RoleBinding

3. Security Mistakes

  • Secret YAML committed to Git: base64 hides nothing
  • Default SA left over-privileged
  • cluster-admin or * verbs to silence Forbidden
Remember

Fix Forbidden with the narrowest Role. Create Secrets in the cluster, never from YAML in Git.

KubernetesPage 6

Cheat Sheet: Config, Secrets, Namespaces, RBAC

1. Config and Consume

  • ConfigMap = plain config; Secret = base64, not encrypted
  • Add etcd encryption + RBAC on secrets
  • data base64, stringData plain
  • Size limit 1 MiB
Env varVolume
SyntaxvalueFrom, envFromfiles in mountPath
Updatesstatic until restartauto, not subPath or immutable
Secretsvisible in envdefaultMode: 0400

2. Scope and RBAC

KindObjects
NamespacedConfigMap, Secret, Role, RoleBinding, ServiceAccount
Cluster-scopedClusterRole, Node, PV
One namespaceRole + RoleBinding
All namespacesClusterRole + ClusterRoleBinding
  • Least privilege; no deny rules
bash
kubectl get cm -n dev
kubectl get cm -A
kubectl config set-context --current --namespace=dev
kubectl auth can-i get secrets --as=system:serviceaccount:dev:app-sa -n dev

3. Interview Point

  • 30 seconds: Secret mounted as 0400 file, ServiceAccount with a Role for that secret only, etcd encrypted
  • Config unreadable? 1) same namespace, key exists 2) pod events: CreateContainerConfigError 3) can-i as the SA
KubernetesPage 7

Check yourself

A Secret was made from echo 'pw' | base64, and the app rejects the password. Why?
  • echo adds a trailing newline, so the stored value decodes to pw plus a newline.
  • Use echo -n, or write plain text under stringData.
You edit a ConfigMap that feeds a pod through envFrom. Does the running pod see it?
  • No. Env vars are fixed at container start.
  • Run kubectl rollout restart deploy/app. A mounted file would refresh, unless it uses subPath.
app-sa has a RoleBinding to Role cm-reader (get, list configmaps) in dev. What does can-i get configmaps -n prod print?
  • no. A RoleBinding grants access in one namespace only.
  • Nothing grants it in prod, and RBAC has no deny rules.