Course contentsShow
← Docker, Kubernetes & CI/CD
Lesson 784 of 80211. Production Operations and ReliabilityFree lesson

Analyzing Resource Fragmentation and Bin Packing

Use node affinity and pod topology spread constraints to improve bin packing efficiency and minimize wasted capacity within your cluster.

In this lesson, you will learn how to optimize your cluster’s resource utilization by utilizing node affinity and pod topology spread constraints to prevent "Swiss cheese" fragmentation and improve bin packing efficiency.

Understanding Resource Fragmentation

Even with precise resource requests and a functioning Cluster Autoscaler, your cluster can suffer from resource fragmentation. This occurs when small, stranded chunks of CPU or memory remain on multiple nodes, but aren't large enough to accommodate new pods. Your cluster may appear to have sufficient aggregate capacity, but the scheduler cannot place a workload because the remaining resources are spread too thin across the infrastructure.

Optimizing with Bin Packing

To minimize wasted capacity, we use "bin packing"—the practice of filling nodes to capacity before spinning up new ones. However, aggressive bin packing can create reliability risks if all pods for a service land on a single failure domain. We balance these competing needs using two primary tools:

  1. Node Affinity: Use requiredDuringSchedulingIgnoredDuringExecution to force pods into specific node pools (e.g., high-memory instances) to ensure they are packed only where they are actually needed, preventing them from being scheduled onto mismatched hardware.
  2. Pod Topology Spread Constraints: This is your primary mechanism for balancing bin packing with high availability. By setting maxSkew and topologyKey, you can tell Kubernetes how to distribute pods across zones or nodes.

Consider this configuration:

topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: "kubernetes.io/hostname"
    whenUnsatisfiable: ScheduleAnyway
    labelSelector:
      matchLabels:
        app: backend

By defining a low maxSkew, you prevent the scheduler from bunching pods onto a single node too aggressively, while still allowing the scheduler to pack them tightly across the available topology. When used alongside the Cluster Autoscaler, this forces the scheduler to exhaust existing node capacity before triggering new node provisions, effectively eliminating the "stranded resource" problem.

Key Takeaway: By carefully configuring topology spread constraints alongside node affinity, you can force the scheduler to pack nodes densely while maintaining the distribution requirements necessary for production reliability.