Intermediate · Kubernetes fundamentals · topic 23 of 53 · 35 min
Namespaces, ConfigMaps, Secrets, resources and probes
Explanation
Namespaces
A namespace is a named section of a cluster. Object names must be unique inside a namespace, but two namespaces can each have a Service called api. Teams use namespaces to separate apps or environments, and to set permissions (RBAC) and quotas per namespace. A new cluster has default, kube-system (the cluster's own components) and a few others.
kubectl create namespace payments
kubectl get pods -n payments
kubectl config set-context --current --namespace=payments # make it your defaultConfigMaps: settings outside the image
You build one image and run it in dev, staging and production. What changes is configuration: the log level, a feature switch, another service's URL. A ConfigMap stores such non-secret settings as key-value pairs, and pods read them as environment variables or as files.
apiVersion: v1
kind: ConfigMap
metadata:
name: payments-config
data:
LOG_LEVEL: info
BANK_API_URL: https://bank-sandbox.example.com
limits.json: |
{"dailyLimitRupees": 100000}
---
# in the Deployment's pod template:
spec:
containers:
- name: api
image: registry.example.com/payments-api:1.4.2
envFrom:
- configMapRef:
name: payments-config # every key becomes an env variable
volumeMounts:
- name: config
mountPath: /etc/payments # limits.json appears as a file here
volumes:
- name: config
configMap:
name: payments-configEnvironment variables are read once when the container starts, so after changing a ConfigMap you must restart the pods: kubectl rollout restart deployment/payments-api. Mounted files are updated after a short delay, but only if your app re-reads them.
Secrets: base64 is not encryption
A Secret looks like a ConfigMap but is meant for passwords, tokens and keys. Its data values are base64-encoded. Base64 is an encoding, a way to write any bytes as plain letters; it is not encryption. Anyone who can read the Secret can decode it in one command.
echo -n 'S3cure#Pass' | base64 # UzNjdXJlI1Bhc3M=
kubectl create secret generic db-credentials --from-literal=password='S3cure#Pass'
kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -dSo protect Secrets properly:
- RBAC (role-based access control): allow get and list on Secrets only to the people and service accounts that need them.
- Encryption at rest: configure the API server (or turn on the option in your managed cluster) so Secrets are encrypted in etcd, ideally with a cloud KMS key.
- External secret managers: keep the real values in AWS Secrets Manager, Azure Key Vault, Google Secret Manager or HashiCorp Vault, and sync them into the cluster with a tool such as the External Secrets Operator or the Secrets Store CSI driver.
- Never commit a plain Secret YAML to Git. If you must keep it in Git, encrypt it first with a tool such as Sealed Secrets or SOPS.
Requests and limits
A request is what the scheduler reserves for a container: it only places the pod on a node with that much free. A limit is the most the container may use. CPU is measured in cores: 1 means one full vCPU and 250m (250 millicores) means a quarter of one. Memory is measured in bytes with suffixes: Mi is a mebibyte (1,048,576 bytes) and Gi a gibibyte; M and G are the decimal versions (1,000,000 and 1,000,000,000).
Going over the CPU limit only slows the container down (throttling). Going over the memory limit gets the container killed, and kubectl describe shows the reason OOMKilled (out of memory), usually with exit code 137. Kubernetes then restarts it, and if it keeps happening you see CrashLoopBackOff.
| QoS class | When | Under memory pressure on the node |
|---|---|---|
| Guaranteed | Every container has CPU and memory requests equal to its limits | Evicted last |
| Burstable | At least one request or limit set, but not Guaranteed | In between |
| BestEffort | No requests or limits at all | Evicted first |
Probes: alive, ready, started
| Probe | Question it asks | What happens when it fails |
|---|---|---|
| liveness | Is the app stuck? | The kubelet restarts the container |
| readiness | Can it take traffic right now? | The pod is removed from Service endpoints until it passes again; no restart |
| startup | Has a slow app finished starting? | Liveness and readiness checks wait until it passes; if it never passes, the container is restarted |
containers:
- name: api
image: registry.example.com/payments-api:1.4.2
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
memory: 512Mi
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
startupProbe:
httpGet: { path: /healthz, port: 8080 }
failureThreshold: 30
periodSeconds: 2 # allow up to 60 seconds to start
livenessProbe:
httpGet: { path: /healthz, port: 8080 }
periodSeconds: 10
readinessProbe:
httpGet: { path: /ready, port: 8080 }
periodSeconds: 5Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Namespaces, ConfigMaps, Secrets, resources and probes · 1/8
In this lesson you will learn how to configure apps on Kubernetes and keep them healthy.
Prefer a video by a teacher? Find free videos on “kubernetes configmap secret resource requests limits probes tutorial” on YouTube ↗
In real life: A hospital appointment system in Chennai
A hospital group runs its appointment system in three namespaces: dev, staging and prod. The same image runs everywhere; a ConfigMap in each namespace sets the SMS gateway URL and log level. The database password lives in HashiCorp Vault and is synced into a Secret by the External Secrets Operator, and only the prod service account can read it. After the morning OPD rush caused OOMKilled restarts, the team checked kubectl top pod, raised the memory limit from 256Mi to 512Mi, and moved the database check from the liveness probe to the readiness probe so a slow database no longer restarts every pod.
kubectl describe pod appointments-7f9-abcde -n prod | grep -A3 "Last State"
# Last State: Terminated
# Reason: OOMKilled
# Exit Code: 137Practice (0/3 done)
A Secret's data map stores base64 strings. Write decode_secret(data) that returns a new dict with every value decoded to normal text, and encode_secret(values) that does the opposite. Use the base64 module. Example: decode_secret({"user": "YWRtaW4="}) returns {"user": "admin"}.
Write parse_cpu(q) that returns CPU cores as a float ("250m" gives 0.25, "1.5" gives 1.5, "2" gives 2.0), and parse_memory(q) that returns bytes as an int. Memory suffixes: Ki, Mi, Gi, Ti are powers of 1024 (Mi = 1024 ** 2); k, M, G, T are powers of 1000; no suffix means plain bytes. Example: parse_memory("512Mi") gives 536870912.
A container keeps restarting and kubectl describe shows "Reason: OOMKilled". What is the best first fix?
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Helm and KustomizeKubernetes fundamentals · same module
- Kubernetes securityDevSecOps
- Keeping secrets safeBackend Development · Backend security
- Environment variables and secretsFull-Stack Development · Deploying and running the app
- Running containers: ports, volumes, networks and limitsDocker
- Image and container securityDocker
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
How are values in a Kubernetes Secret protected by default?
Answer: Only base64-encoded, which anyone with read access can decode
Base64 is an encoding. Real protection comes from RBAC, encryption at rest and external secret managers.
What does cpu: 500m mean?
Answer: Half of one CPU core
m means millicores: 500m is 0.5 of a core.
A pod fails its readiness probe. What happens?
Answer: It is removed from Service endpoints until it passes again
Readiness controls traffic. Liveness controls restarts.
You changed a ConfigMap that a Deployment reads with envFrom. Why do the pods still see the old values?
Answer: Environment variables are read when the container starts, so the pods must be restarted
Run kubectl rollout restart deployment/<name> to start fresh pods with the new values.
Which pods are evicted first when a node runs out of memory?
Answer: BestEffort
BestEffort pods have no requests or limits and are the first to go.
Which object replaced PodSecurityPolicy (removed in Kubernetes 1.25) for enforcing Pod Security Standards?Related
Answer: Pod Security Admission, configured with namespace labels
The built-in Pod Security Admission controller enforces privileged, baseline or restricted per namespace.
From Kubernetes security
What do containers in the same pod share?Related
Answer: A network identity (one IP) and optionally volumes
Containers in a pod share the network namespace, so they reach each other on localhost, and can mount the same volumes.
A pod in namespace web calls Service "orders" in namespace shop. Which name works?Related
Answer: orders.shop
The pattern is service.namespace, with .svc.cluster.local optional at the end.
A Deployment wants 3 replicas. You delete one of its pods by hand. What happens?Related
Answer: A new pod is created to get back to 3
The ReplicaSet controller sees 2 of 3 and creates a replacement. That is self-healing.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “Kubernetes fundamentals” before its exam: Helm and Kustomize.
- Module 5 exam: Kubernetes fundamentals · 13 questions · 20 min, without help. 5 topics of this module still to finish first.
- Then the next module, CI/CD pipelines. 53 topics left in the course before the final exam.