Skip to content

Chapter 4 of 7

Scheduling, Scaling, and Resource Management

Kubernetes offers fine-grained control over where Pods run and how many resources they consume. The scheduler selects an optimal node for each new Pod based on resource requests, affinity and anti-affinity rules, taints and tolerations, node selectors, and topology spread constraints. Taints applied to nodes repel Pods that lack matching tolerations, with effects NoSchedule for hard rejection, PreferNoSchedule for soft preference, and NoExecute for evicting already-running Pods. Node affinity constrains scheduling via node labels, with requiredDuringSchedulingIgnoredDuringExecution as a hard requirement and preferredDuringSchedulingIgnoredDuringExecution as a soft preference weighted numerically. Pod anti-affinity keeps replicas of the same workload spread across nodes or zones, while topology spread constraints generalize this idea by distributing Pods across failure domains defined by a topologyKey such as topology.kubernetes.io/zone, capped by a maxSkew value.

Scaling happens at two levels. The Horizontal Pod Autoscaler adjusts the replica count of a Deployment or ReplicaSet based on observed CPU, memory, or custom metrics, while the Vertical Pod Autoscaler tunes the CPU and memory requests and limits of individual containers using Off, Auto, or Initial modes. Because VPA may restart Pods to apply changes, it should not be used on the same CPU/memory metrics as HPA. The Cluster Autoscaler operates one level higher, adding or removing worker nodes when Pods cannot be scheduled or when nodes are underutilized. Resource requests and limits are central to all of this: requests drive scheduling decisions and must fit on a node, while limits drive runtime enforcement, with exceeded CPU limits causing throttling and exceeded memory limits triggering OOMKill. CPU is measured in millicores, where 1000m equals one vCPU.

Each Pod's combined settings give it a Quality of Service class: Guaranteed when every container's requests equal its limits, Burstable when some are set, and BestEffort when none are, with kubelet eviction preferring to kill BestEffort Pods first under node pressure. PriorityClass assigns a numeric priority to Pods so the scheduler can preempt lower-priority Pods when the cluster is full, with built-in classes such as system-node-critical and system-cluster-critical for system components. PodDisruptionBudgets complement replica counts by capping how many Pods of an application can be simultaneously unavailable during voluntary disruptions such as node drains, using either minAvailable or maxUnavailable. Throughout all of this, labels and selectors are the connective tissue: equality-based selectors like app=nginx and set-based selectors like env in (prod, staging) let Services, Deployments, ReplicaSets, and other controllers target the right Pods, while annotations carry non-identifying metadata that selectors cannot use but external tools can read.

All chapters
  1. 1Pods, Containers, and Workloads
  2. 2Services, Networking, and Traffic Management
  3. 3Configuration, Storage, and Packaging
  4. 4Scheduling, Scaling, and Resource Management
  5. 5Cluster Architecture and Components
  6. 6Security, Access Control, and Policies
  7. 7Operating Kubernetes with kubectl and Tooling

Drill it

Reading is not remembering. These come from the Kubernetes Orchestration deck:

Q

What is a Pod in Kubernetes?

A Pod is the smallest deployable unit in Kubernetes. It represents a single instance of a running process and can contain one or more containers that share:The...

Q

Why would you run multiple containers in a single Pod?

Multiple containers in a Pod share the same network and storage, making them ideal for tightly coupled processes. Common patterns include:Sidecar – adds functio...

Q

What is an init container?

An init container runs before the main application containers start. It runs to completion and must succeed before the next init container (or main container) s...

Q

What is the sidecar pattern in Kubernetes?

The sidecar pattern places a helper container alongside the main application container within the same Pod. The sidecar extends or enhances the main container's...