Keep Workloads Healthy: Namespaces, Resources, Quotas, and Probes
Share a cluster fairly with requests, limits, and quotas, and let Kubernetes detect unhealthy containers.
A cluster is a shared pool of CPU and memory. Without guardrails, one greedy workload can starve its neighbors, and a hung application can keep receiving traffic. This guide covers the tools for both: namespaces and quotas to divide the pool, requests and limits to describe what each container needs, and probes so Kubernetes can tell when a container is unhealthy.
Divide a cluster with namespaces
Namespaces split one cluster into separate areas for teams, applications, or environments:
kubectl create namespace demo
kubectl get pods -n demo
kubectl config set-context --current --namespace=demo
kubectl get pods -A
Your objects go into default unless you say otherwise, using -n NAME on a command or metadata.namespace in a manifest. The cluster’s own components live in kube-system. Most objects are namespaced (Pods, Services, ConfigMaps, Secrets), while some, like nodes and PersistentVolumes, are cluster-wide. Namespaces are the unit that quotas and access rules attach to, but by themselves they are an organizational boundary, not a strong security one. A common surprise is a Pod that seems to have vanished, when really you created it in another namespace. Check with kubectl get pods -A.
Set requests and limits
Each container can declare what it needs and the most it may use:
spec:
containers:
- name: web
image: nginx:1.25
resources:
requests:
cpu: 250m
memory: 64Mi
limits:
cpu: 500m
memory: 128Mi
- Requests are what the scheduler reserves. A Pod is only placed on a node with that much unclaimed capacity, and the container is guaranteed at least this much.
- Limits are a hard ceiling. A container that tries to use more CPU is throttled. One that exceeds its memory limit is killed (
OOMKilled) and restarted.
CPU is measured in cores, where 1000m (millicores) is one full core, so 250m is a quarter of one. A limit can’t be lower than its request. Both are set per container, not per Pod.
Watch usage with the metrics server
kubectl top reports live usage, but it needs the metrics server, which many fresh clusters lack. Without it you’ll see “Metrics API not available”. On minikube:
minikube addons enable metrics-server
kubectl top nodes
kubectl top pods -A
On other clusters, install metrics-server from its project page. It is a quick way to spot which Pods are using the most resources.
Enforce a budget with ResourceQuota and LimitRange
A ResourceQuota caps the total a namespace may request or use:
apiVersion: v1
kind: ResourceQuota
metadata:
name: demo-quota
namespace: demo
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
pods: "10"
kubectl describe resourcequota -n demo shows what is used against each limit. Once the total would be exceeded, new Pods are rejected at creation with an “exceeded quota” error. When a quota covers CPU or memory, every Pod in that namespace must also declare those requests and limits, or it is rejected. A LimitRange avoids that by supplying defaults for containers that don’t set their own:
apiVersion: v1
kind: LimitRange
metadata:
name: container-defaults
namespace: demo
spec:
limits:
- type: Container
defaultRequest:
cpu: 100m
memory: 64Mi
default:
cpu: 250m
memory: 128Mi
Add readiness and liveness probes
A running container isn’t necessarily a working one. Probes let Kubernetes check:
- A readiness probe decides whether the container should receive traffic. When it fails, the Pod is removed from its Services’ endpoints but is not restarted. Use it for slow starts or temporary overload.
- A liveness probe decides whether the container is still alive. After enough consecutive failures, the kubelet restarts the container.
- A startup probe holds off the other two while a slow application boots.
spec:
containers:
- name: web
image: nginx:1.25
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 2
periodSeconds: 5
timeoutSeconds: 1
failureThreshold: 3
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
The timing fields work the same for every probe. initialDelaySeconds is how long to wait after the container starts before the first check, periodSeconds is how often to check, timeoutSeconds is how long to wait for an answer, and failureThreshold is how many consecutive failures count as failed. Besides HTTP requests, probes can open a TCP connection (tcpSocket), run a command inside the container (exec), or use gRPC.
Keep liveness checks simple and about the process itself. If a liveness probe fails because a database is down, Kubernetes restarts healthy application containers for nothing and can make an outage worse. A readiness probe is the right place to reflect dependencies. Readiness also drives rolling updates: new Pods only count as available once they are ready.
You can see probe results in kubectl describe pod, where failures appear in the events, and in kubectl get pods, where a failing readiness probe shows as 0/1 in the READY column.
Popular Guides
-
What Kubernetes Is and the Problems It Solves Why containers alone stop scaling, and how Kubernetes turns a group of machines into one platform. -
How a Kubernetes Cluster Works: Control Plane and Nodes The components that make a cluster tick, and what happens between kubectl apply and a running container. -
Deployments: Scaling, Self-Healing, and Rolling Updates Run replicas of a Pod, update them without downtime, and roll back when a release goes wrong. -
Services: Stable Networking for Ephemeral Pods Give Pods a stable address, expose them inside and outside the cluster, and restrict who can talk to whom. -
Debug a Failing Pod: describe, logs, exec, and port-forward A repeatable checklist for finding out why a Pod is Pending, crashing, or not answering.