Skip to main content
reliability · kubernetes

Deployments, StatefulSets and DaemonSets with containers missing CPU or memory requests

resource types
3
rule IDs covered
9
severity
high

What does ZopNight detect here?

Kubernetes schedules pods by summing container requests against node capacity, so a container with no CPU or memory request is invisible to that math. ZopNight flags Deployments, StatefulSets and DaemonSets on EKS, GKE and AKS whenever any main container lacks either request, and lists every offender by name.

Signal and threshold

How ZopNight evaluates Deployments, StatefulSets and DaemonSets with containers missing CPU or memory requests.
Field Value
Rule IDsRC-1700 · RC-1800 · RC-1900 · RC-1701 · RC-1801 · RC-1901 · RC-1702 · RC-1802 · RC-1902
Categoryreliability
Severityhigh
Metricnone — pure configuration read
Thresholdany container without a CPU or memory request
SourceZopNight
Permissions usedlist deployments.apps · list statefulsets.apps · list daemonsets.apps

Why an empty request breaks pod placement

A request is the amount of CPU and memory the kube-scheduler reserves for a container when it picks a node. The Kubernetes docs describe the scheduler comparing the sum of container requests with what each node can still offer. A container that declares nothing adds nothing to that sum, so the scheduler keeps placing pods on a node that is already busy in practice.

The failure shows up later, under load. CPU contention slows every pod on the node, and when memory runs short the kernel starts killing processes. Eviction adds a second penalty: pod QoS rules make a pod with no CPU or memory requests or limits BestEffort, the first class evicted when a node comes under pressure, and only pods using more than they requested are eviction candidates. With a request of zero, any usage at all qualifies.

Scanning Deployments, StatefulSets and DaemonSets for missing requests

This lists each container, with its workload, that has no CPU request or no memory request. It treats 0 as empty, the same value kubectl set resources uses to remove a request:

Terminal window
kubectl get deployments,statefulsets,daemonsets -A -o json | jq -r '
.items[] | .kind as $k | .metadata as $m
| .spec.template.spec.containers[]
| select(((.resources.requests.cpu // "0") == "0")
or ((.resources.requests.memory // "0") == "0"))
| "\($k) \($m.namespace)/\($m.name) \(.name)"'

One missing request is enough to flag a workload

The same check runs for each workload kind (Deployments, StatefulSets and DaemonSets) on each managed cluster type: EKS, GKE and AKS. It reads the containers in the workload spec ZopNight collected from the cluster and fires when any container has an empty or zero CPU request, or an empty or zero memory request. Missing either one is enough. There is no metric, threshold or lookback window involved: it is a configuration read, repeated on every evaluation.

The finding names every offending container, not only the first, so a pod with a sidecar and an app container that both lack requests gets one recommendation listing both.

Containers and workloads the check ignores

Init containers are out of scope. They run to completion before the app containers start and often have no requests of their own by design, so scanning them would flag workloads that are already configured correctly. A workload with no containers listed in its spec produces nothing, and a workload where every container sets both requests is silent.

Be aware of the two admission-time cases in the false-positive note: a limit with no request is copied into the request when the pod is created, and a namespace LimitRange can inject a defaultRequest. The pods then have requests even though the template does not say so.

Risk rather than a dollar figure

This is a reliability rule and carries no savings estimate. The cost is operational: unpredictable packing, OOM kills during traffic peaks, and critical workloads evicted ahead of noisy ones.

Adding requests without guessing

  1. Run the Vertical Pod Autoscaler with updateMode: "Off", which computes recommendations without touching pods, and read them with kubectl describe vpa.
  2. Apply the values to the template, for example kubectl set resources deployment api -c=app --requests=cpu=250m,memory=256Mi.
  3. Roll out and watch for pods stuck in Pending, which means the new requests exceed free node capacity.
  4. Add a LimitRange with defaultRequest to the namespace so new workloads start with a sensible floor.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

472 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

472 rule families documented
353 resource types covered
read-only default access level
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·