· tech · 1 min read

Kubernetes Pod Scheduling: A Deep Dive

The Kubernetes scheduler is responsible for assigning newly created pods to nodes in the cluster. It does this through a two-phase process: filtering and scoring. Understanding these internals is critical when debugging why your pods are stuck in Pending.

Filtering Phase

During filtering, the scheduler eliminates nodes that cannot host the pod. Common filter predicates include:

  • NodePorts — checks for port conflicts
  • PodFitsResources — ensures enough CPU and memory
  • NodeSelector / NodeAffinity — matches labels
  • Taints and Tolerations — respects scheduling barriers

Scoring Phase

Surviving nodes are then scored across multiple priority functions. The node with the highest total score wins. A common scoring function is LeastRequestedPriority, which prefers less-utilized nodes to spread workload:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    resources:
      requests:
        memory: "256Mi"
        cpu: "500m"
      limits:
        memory: "512Mi"
        cpu: "1000m"

Custom Schedulers

When the default scheduler doesn’t fit your needs, you can run a secondary scheduler using the schedulerName field in a pod spec. This is common in batch-processing clusters where you need topology-aware or cost-optimized placement. Tools like Karpenter or Volcano build on this extension point to provide sophisticated, workload-specific scheduling.