The Limits of "Good Enough"
Imagine you're managing a fleet of delivery trucks. A naive dispatcher might just assign packages to whichever truck has the most space — but a smart dispatcher knows that refrigerated trucks should carry perishables, trucks near the airport should handle international shipments, and you should never put all your fragile packages in the same vehicle. Kubernetes' default scheduler is the naive dispatcher. It balances CPU and memory reasonably well, but it knows nothing about your business rules, physical infrastructure, or cost constraints.
By default, the Kubernetes scheduler sees nodes as interchangeable buckets of CPU and memory. It doesn't know that Node A is in Data Center 1 and Node B is in Data Center 2. It doesn't know that Node C has a $10/hour GPU that should never run a simple blog. It doesn't know that your compliance team requires EU customer data to stay on EU nodes. These are the gaps that advanced scheduling fills.
To build production-grade, highly available, and cost-efficient clusters, you give the scheduler explicit rules using three primary tools:
- Taints & Tolerations — Nodes repel Pods unless the Pod explicitly opts in.
- Node Affinity — Pods declare which nodes they prefer or require.
- Topology Spread Constraints — Pods declare how they should be distributed across failure domains.
These tools compose together. A real production workload often uses all three simultaneously. The rest of this lesson builds each tool from first principles, then shows how they combine.