Workloads with no CPU or memory requests set
What does ZopNight detect here?
A container without CPU and memory requests gives the scheduler nothing to place it with. ZopNight reads the pod spec across Deployments, StatefulSets and DaemonSets (3 workload kinds), and names every offending container. There is no metric here; it is a pure configuration read.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1700 · RC-1800 · RC-1900 · RC-1701 · RC-1801 · RC-1901 · RC-1702 · RC-1802 · RC-1902 |
| Category | reliability |
| Severity | high |
| Metric | none — pure configuration read |
| Source | internal/rules/k8s/workload_no_requests.go |
Where it applies
Requests are what the scheduler actually uses
A request is a reservation. The scheduler sums the requests already placed on each node and puts your pod where the remainder fits. A container with no request contributes zero to that sum, so the scheduler treats it as free and will keep packing the node.
Limits are a different thing entirely, a ceiling enforced at runtime. Setting limits without requests is common and does not help placement at all.
What goes wrong without them
Nodes get oversubscribed. Pods land wherever there is nominal room, then contend for CPU and memory that was never reserved.
OOM kills arrive under load. A node running several request-less containers has no accounting for what they will actually consume, so memory pressure appears suddenly rather than being prevented at scheduling time.
Eviction order works against you. Kubernetes assigns Quality of Service from requests and
limits. A pod with neither is BestEffort, the first class evicted when a node comes under
pressure, regardless of how important the workload is.
That last point is the one teams find surprising: the workload you cared most about is the one the kubelet kills first, purely because nobody set a request on it.
No metric, no window
This rule reads the discovered pod spec and nothing else. There is no utilisation threshold and no lookback: a container either declares both requests or it does not.
It abstains when the workload metadata carries no containers at all, and it requires an explicit present value: a missing field is treated as missing, not as zero.
Filtering containers with empty requests fields
kubectl get deploy,statefulset,daemonset -A -o json | jq -r ' .items[] | . as $w | .spec.template.spec.containers[] | select((.resources.requests.cpu // "") == "" or (.resources.requests.memory // "") == "") | "\($w.kind) \($w.metadata.namespace)/\($w.metadata.name): \(.name)"'Setting sensible values
Run the Vertical Pod Autoscaler in recommend mode for a week and read its suggestions rather
than guessing. Then add a LimitRange to the namespace so future workloads inherit defaults
instead of shipping with nothing.