✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes Scheduler Scoring Behavior

Kubernetes Scheduler Scoring Behavior determines node selection by evaluating resource availability, constraints, and affinity rules to schedule pods efficiently.

Kubernetes Scheduler Scoring Behavior is the detailed mechanics of how the scheduler ranks feasible nodes — those that survived the filtering phase — against each other to select the single best placement for a Pod, using a configurable set of weighted scoring plugins that each contribute an independent signal to a combined, per-node total. Where filtering answers a binary question per node, scoring answers a comparative one across every feasible node simultaneously, and understanding how individual plugin scores combine into a final ranking explains placement outcomes that would otherwise seem arbitrary among several equally "valid" nodes.

Every scoring plugin returns a normalized score (typically 0-100) for each feasible node, which is then multiplied by that plugin's configured weight and summed across all active plugins to produce the node's final aggregate score.


Built-In Scoring Plugins

NodeResourcesFit

Scores nodes based on how well the Pod's resource requests align with the node's remaining allocatable capacity, using a configurable strategy — LeastAllocated (default in many configurations) favors nodes with more free capacity remaining, spreading load across the cluster, while MostAllocated favors nodes that are already more heavily utilized, which is useful for bin-packing strategies aiming to consolidate workloads onto fewer nodes to allow others to scale down or be reclaimed.

score = capacitynoderequestedtotal capacitynode × 100

InterPodAffinity

Scores nodes based on how well they satisfy preferredDuringSchedulingIgnoredDuringExecution pod affinity and anti-affinity terms, weighted by each term's own configured weight, summed across every matching preference.

NodeAffinity

Scores nodes based on satisfaction of preferredDuringSchedulingIgnoredDuringExecution node affinity terms, similarly weighted and summed per matching term.

TaintToleration

Scores nodes lower if they carry PreferNoSchedule taints the Pod does not tolerate, providing the soft-avoidance behavior that distinguishes PreferNoSchedule from the hard-filtering NoSchedule effect.

PodTopologySpread

Scores nodes based on how placing the Pod there would affect topology spread skew for any configured ScheduleAnyway topology spread constraints, favoring nodes that keep the distribution more balanced.

ImageLocality

Favors nodes that already have the Pod's container image cached locally, reducing image pull time and network transfer — a practical optimization especially relevant for large images or bandwidth-constrained environments.


Weighting Plugins

Default Weights

Each built-in plugin has a sensible default weight reflecting its typical importance relative to the others, but cluster operators can adjust these weights (or disable specific plugins entirely) through the scheduler's configuration, tailoring scoring behavior to their specific priorities — for example, weighting NodeResourcesFit more heavily in a cost-sensitive cluster prioritizing tight bin-packing.

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: default-scheduler
    plugins:
      score:
        enabled:
          - name: NodeResourcesFit
            weight: 5
          - name: InterPodAffinity
            weight: 2

The Combined Score

scoretotal = i=1 n weighti × scorei

The node with the highest combined total across every active, weighted plugin is selected, with ties broken through an internal randomization mechanism to avoid deterministically favoring the same node repeatedly under equal scores.


Scoring Only Applies After Filtering

No Rescue for Infeasible Nodes

Scoring never runs against a node that failed filtering — a node scoring poorly is still a viable placement target if it was among the feasible set, while a node that would have scored perfectly is never even considered if it failed a hard filter like insufficient resources or an untolerated taint. This ordering (hard filter first, soft scoring second) is fundamental to correctly reasoning about scheduler behavior.


Observing Scoring Decisions

kubectl get events --field-selector involvedObject.name=codartium-app,reason=Scheduled

Scheduler scoring decisions are not directly exposed via kubectl in granular per-plugin detail by default; deeper investigation into specific scoring behavior typically requires enabling verbose scheduler logging or scheduler framework tracing, reserved for genuinely puzzling placement decisions rather than routine troubleshooting.


Example

apiVersion: v1
kind: Pod
metadata:
  name: codartium-scoring-example
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 80
          preference:
            matchExpressions:
              - key: disktype
                operator: In
                values: ["ssd"]
  containers:
    - name: app
      image: codartium/app:latest