Kubernetes - kube-scheduler
The kube-scheduler is the core Kubernetes control plane component responsible for watching newly created Pods with no assigned node (spec.nodeName == "") and assigning them to the most optimal Node in the cluster.
The Scheduling Cycle
For every unscheduled Pod, kube-scheduler selects an optimal node in a 2-phase decision cycle followed by binding:
Unscheduled Pod ──► [ 1. Filtering (Predicates) ] ──► [ 2. Scoring (Priorities) ] ──► [ 3. Binding ] ──► Assigned Node
1. Filtering Phase (Predicates)
Filters out nodes that cannot satisfy the Pod's operational requirements. If no nodes qualify, the Pod remains in Pending state.
PodFitsResources: Checks if the node has sufficient allocatable CPU, memory, and ephemeral storage.PodMatchNodeSelector: ChecksnodeSelectorandnodeAffinityconstraints.PodToleratesNodeTaints: Checks if the Pod has tolerations matching the node's taints (NoSchedule,PreferNoSchedule).NodeName: Checks if the Pod explicitly requests a specific node name.PodTopologySpread: Verifies zone/rack distribution rules.
2. Scoring Phase (Priorities)
Ranks all surviving candidate nodes on a scale of 0 to 100 using weighted scoring plugins. The node with the highest combined score is selected:
NodeResourcesBalancedAllocation: Favors nodes that yield a balanced ratio of CPU and memory usage after pod placement.NodeAffinityScoring: Awards higher scores to nodes satisfyingpreferredDuringSchedulingIgnoredDuringExecutionaffinity rules.ImageLocality: Awards higher scores to nodes that already have the required container image cached locally.TaintTolerationPriority: Prioritizes nodes with fewer un-toleratedPreferNoScheduletaints.
3. Binding Phase
The scheduler creates a Binding object that updates the Pod's spec.nodeName via kube-apiserver, triggering the target node's kubelet to pull images and start containers.
Scheduling Mechanisms & Customization
| Mechanism | Description | YAML Snippet |
|---|---|---|
nodeSelector |
Simple key-value matching against Node labels. | nodeSelector: { disktype: ssd } |
| Node Affinity | Advanced matching rules (In, NotIn, Exists, Gt, Lt). |
affinity.nodeAffinity.requiredDuringScheduling... |
| Pod (Anti-)Affinity | Co-locate or separate Pods based on labels of other Pods running in the topology. | affinity.podAntiAffinity.preferredDuringScheduling... |
| Taints & Tolerations | Allows nodes to repel a set of Pods unless the Pod explicitly tolerates the taint. | tolerations: [{ key: "gpu", effect: "NoSchedule" }] |
| Topology Spread Constraints | Distribute replicas evenly across failure domains (zones, regions, hosts). | topologySpreadConstraints: [{ maxSkew: 1, topologyKey: "topology.kubernetes.io/zone" }] |
| Priority & Preemption | Evicts lower-priority Pods from nodes when higher-priority Pods cannot fit. | priorityClassName: high-priority |
Deployment & High Availability
kube-scheduler typically runs as a static Pod managed by kubelet on control plane nodes:
apiVersion: v1
kind: Pod
metadata:
name: kube-scheduler
namespace: kube-system
spec:
containers:
- name: kube-scheduler
image: registry.k8s.io/kube-scheduler:v1.30.0
command:
- kube-scheduler
- --authentication-kubeconfig=/etc/kubernetes/scheduler.conf
- --authorization-kubeconfig=/etc/kubernetes/scheduler.conf
- --kubeconfig=/etc/kubernetes/scheduler.conf
- --bind-address=127.0.0.1
- --leader-elect=true
Leader Election (
--leader-elect=true): In multi-master HA topologies, multiple instances ofkube-schedulerrun concurrently, but only the active leader elected via a Lease lock inkube-systemperforms scheduling decisions.