Kubernetes Node Candidate Evaluation
Kubernetes Node Candidate Evaluation assesses potential nodes for scheduling, ensuring optimal resource allocation, availability, and compliance with cluster requirements.
Kubernetes Node Candidate Evaluation is the filtering phase of the scheduler's decision flow in which every node in the cluster is checked against a Pod's hard requirements to determine the subset of nodes actually capable of hosting it — the "feasible" set that scoring will later rank. Candidate evaluation answers a strictly binary question for each node ("can this Pod run here at all?"), deferring any notion of "how well" a node fits to the separate scoring phase that follows once the candidate set has been narrowed down.
This phase is where the majority of Pending Pod failures actually originate, since a Pod with zero feasible nodes after evaluation cannot proceed to scoring or selection at all, making the specific checks performed during candidate evaluation the first place to look when diagnosing a scheduling failure.
Resource Fit Evaluation
Allocatable Capacity Comparison
For each node, the scheduler compares the sum of resource requests from the Pod being scheduled plus every already-scheduled Pod on that node against the node's allocatable CPU, memory, and ephemeral storage. A node whose remaining allocatable capacity cannot accommodate the new Pod's requests is eliminated from the candidate set immediately.
Extended Resources
Beyond CPU and memory, custom or extended resources (GPUs, specialized hardware advertised via device plugins) are evaluated the same way — a node lacking the specific extended resource a Pod requests (nvidia.com/gpu: 1) is filtered out regardless of how much ordinary CPU and memory it has free.
Constraint-Based Evaluation
Node Selector and Node Affinity
Nodes whose labels do not satisfy the Pod's nodeSelector or requiredDuringSchedulingIgnoredDuringExecution node affinity terms are eliminated outright — these are hard constraints, evaluated with no partial credit, unlike the soft preferredDuringSchedulingIgnoredDuringExecution variant, which only affects scoring.
Taints and Tolerations
A node carrying any taint the Pod does not tolerate is removed from the candidate set, regardless of how otherwise well-suited it might be, reflecting the taint mechanism's design as an opt-out-by-default filter rather than a scoring consideration.
Inter-Pod Affinity and Anti-Affinity
Required inter-pod affinity rules (this Pod must run in the same topology domain as Pods matching a given label selector) and anti-affinity rules (this Pod must not run alongside Pods matching a given selector) are evaluated by inspecting the Pods already running on or near each candidate node, filtering out any node that would violate the rule.
Volume and Topology Evaluation
Volume Binding Constraints
For Pods referencing PersistentVolumeClaims, the scheduler checks whether a node is compatible with the volume's topology constraints (a volume provisioned in a specific availability zone can only be used by Pods scheduled in that same zone), eliminating nodes outside the volume's accessible topology.
Pod Topology Spread Constraints
Hard topology spread constraints (whenUnsatisfiable: DoNotSchedule) filter out nodes whose selection would violate the configured maxSkew across the specified topology key, treating the spread requirement as a candidate-eliminating filter rather than merely a scoring preference.
Evaluation Order and Short-Circuiting
Cheapest Checks First
Internally, the scheduler orders its filtering checks to evaluate the least expensive conditions first (a simple label comparison) before more expensive ones (inter-pod affinity, which requires inspecting other Pods' placement), so that nodes failing on cheap criteria are eliminated quickly without incurring the cost of more expensive checks unnecessarily.
Nodes Are Evaluated Independently
Each node's candidacy is evaluated independently of every other node's outcome — a node's feasibility is never influenced by whether other nodes passed or failed, which keeps the filtering phase's logic simple and parallelizable across large node counts.
Interpreting Candidate Evaluation Failures
Reading the Aggregated Failure Summary
kubectl describe pod codartium-app
The FailedScheduling message aggregates how many nodes failed each specific filter (8 Insufficient cpu, 4 node(s) had taint...), giving a breakdown of exactly which checks are responsible for shrinking the candidate set to zero, which is the starting point for any remediation.
Distinguishing Zero Candidates from Poor Scoring
A Pod that does have at least one feasible node after evaluation will always be scheduled somewhere, even if that node scores poorly relative to others — poor scoring never prevents scheduling outright, it only influences which of the feasible nodes is chosen. Only a completely empty candidate set after evaluation results in a Pod remaining unscheduled.
kubectl get nodes -o wide
kubectl describe nodes | grep -E "Taints|Allocatable"
Example
apiVersion: v1
kind: Pod
metadata:
name: codartium-candidate-example
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values: ["linux"]
containers:
- name: app
image: codartium/app:latest
resources:
requests:
cpu: "500m"
memory: "512Mi"