Skip to main content

Find and Fix Kubernetes Pods Missing Resource Requests

List every container with no CPU or memory request, set values from observed usage, and add a namespace default so new ones cannot slip through.

A container with no resource requests tells kube-scheduler nothing about how much room it needs, so the scheduler can pack it onto a node that has no memory to spare. If no container in the Pod sets any request or limit, the Pod lands in the BestEffort QoS class, and BestEffort Pods are the first the kubelet evicts when a node runs out of resources. Missing limits cause the opposite problem: one container can take node memory its neighbours were counting on. The fix is mechanical, and this page walks through it.

What you need

  • kubectl with get across namespaces and patch on the Deployments, StatefulSets and DaemonSets you will change.
  • The metrics-server add-on, so kubectl top works.
  • jq.

1. List containers with no requests

Terminal window
kubectl get deployments,statefulsets,daemonsets -A -o json | jq -r '
.items[] | . as $w | .spec.template.spec.containers[]
| select((.resources.requests // {}) | (has("cpu") and has("memory")) | not)
| "\($w.kind)\t\($w.metadata.namespace)/\($w.metadata.name)\t\(.name)"' | column -t

Each row is a workload and container missing a CPU request, a memory request or both. Run a second pass with .resources.limits in place of .resources.requests to list containers with no memory limit.

To see the QoS class the running Pods ended up with:

Terminal window
kubectl get pods -A -o custom-columns=NS:.metadata.namespace,POD:.metadata.name,QOS:.status.qosClass \
| grep BestEffort

2. Measure what the container actually uses

Terminal window
kubectl top pods -n shop --containers

Sample through a representative period, not once. Base the CPU request on typical usage and the memory request on the observed peak, because the kernel enforces CPU limits by throttling, while a container that goes over its memory limit can be killed.

3. Set the values

Terminal window
kubectl set resources deployment checkout -n shop -c=app \
--requests=cpu=200m,memory=256Mi --limits=memory=512Mi
kubectl rollout status deployment/checkout -n shop

-c targets one container; drop it to apply the same values to every container in the Pod template. If you set only a limit and nothing else supplies a default request, Kubernetes copies the limit and uses it as the request. Apply the change in the source of truth too (Helm values, Kustomize overlay, GitOps repo), or the next deploy reverts it.

4. Give the namespace a default

A LimitRange injects default requests and limits into containers created without them, so the next workload that forgets is covered:

Terminal window
kubectl apply -n shop -f - <<'EOF'
apiVersion: v1
kind: LimitRange
metadata:
name: container-defaults
spec:
limits:
- type: Container
defaultRequest:
cpu: 100m
memory: 128Mi
default:
memory: 256Mi
EOF
kubectl describe limitrange container-defaults -n shop

Defaults apply at admission, so existing Pods keep their old spec until they are recreated. Adding a ResourceQuota for CPU and memory in the same namespace makes requests effectively mandatory, since the quota system can reject Pods that set none.

5. Confirm the fix

Re-run the query from step 1: fixed workloads drop off the list. The QoS check should now show Burstable (requests below limits) or Guaranteed (requests equal to limits for every container) instead of BestEffort.

In ZopNight

ZopNight scans EKS, GKE and AKS workloads and raises containers missing requests or limits as reliability recommendations, next to single-replica and degraded workloads and CPU over-provisioning. Each recommendation shows the evidence that triggered it and can be exported with the rest of the backlog. The remediation wizard can apply live Kubernetes manifest patches for rules on its allowlist, with a validate step after the change; on a read-only connection you get the findings without the write path. Pod resource requests and limits explains the scheduling mechanics in more depth, and reducing Kubernetes costs covers the over-requesting side.

Stop watching the waste.
Start cutting it.

See. Find. Fix. Automatic.

Connect your first cloud account in under 5 minutes. See your first remediation in under 7. No credit card required.

CDCR connect detect classify remediate
full audit every action traceable
read-only default access
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·