✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes Topology Spread Placement

Kubernetes Topology Spread Placement distributes workloads across nodes using constraints, improving resource efficiency and fault tolerance in clusters.

Kubernetes Topology Spread Placement is a scheduling mechanism, expressed through spec.topologySpreadConstraints, that evenly distributes a group of related Pods across a specified topology dimension — nodes, zones, regions, or any custom node label — with fine-grained, quantitative control over how much imbalance is tolerated. Where pod anti-affinity expresses spreading as a pairwise "avoid this other Pod" relationship, topology spread constraints express it as a direct, numerical balancing goal: keep the difference in Pod count between the most-loaded and least-loaded topology domain within a specified bound, making it the more precise and purpose-built tool specifically for even distribution.

Each constraint is defined by a topology key identifying the dimension to spread across, a maximum allowed skew, a label selector identifying which Pods are counted as part of the same spreading group, and a policy for what to do when the constraint cannot be satisfied.


The maxSkew Calculation

Defining Skew

Skew is the difference between the number of matching Pods in the topology domain with the most and the domain with the least, among domains that currently host at least one matching Pod (or all eligible domains, depending on minDomains configuration).

skew = max domain ( countdomain ) min domain ( countdomain )

maxSkew sets the ceiling this calculated value must not exceed after the new Pod is placed — a maxSkew of 1 means no topology domain may end up with more than one more matching Pod than the least-loaded domain.

topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: "kubernetes.io/hostname"
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: codartium-api

whenUnsatisfiable Policies

DoNotSchedule

A hard constraint: the scheduler will not place a Pod anywhere that would violate the maxSkew bound, potentially leaving the Pod unschedulable if every domain is already at or above the balanced threshold relative to the least-loaded one.

ScheduleAnyway

A soft constraint: the scheduler prefers placements that keep skew within bounds, scoring nodes accordingly, but will still schedule the Pod somewhere even if every option violates maxSkew, rather than leaving it Pending.


Multiple Constraints Combined

Layered Spreading Across Dimensions

Multiple topologySpreadConstraints entries can be specified together, each targeting a different topology key — for example, spreading across zones as a hard requirement while also spreading across individual nodes within each zone as a softer preference, giving layered control over both coarse and fine-grained distribution simultaneously.

topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: "topology.kubernetes.io/zone"
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: codartium-api
  - maxSkew: 2
    topologyKey: "kubernetes.io/hostname"
    whenUnsatisfiable: ScheduleAnyway
    labelSelector:
      matchLabels:
        app: codartium-api

minDomains

Guarding Against Too Few Domains

minDomains specifies the minimum number of eligible topology domains that must exist for the constraint's balancing goal to be meaningfully satisfied — if fewer domains exist than minDomains (for example, a cluster with only two zones when three are expected), the scheduler treats the missing domains as having zero matching Pods for skew calculation purposes, which can influence placement to actively favor filling in the "missing" domains conceptually, though this only applies when using DoNotSchedule.


Topology Spread vs. Pod Anti-Affinity

When to Prefer Topology Spread Constraints

For a single workload's replicas needing even, quantitatively bounded distribution, topology spread constraints are generally the more precise tool, offering direct control over acceptable imbalance (maxSkew) that anti-affinity has no equivalent for — anti-affinity can express "avoid" but not "spread evenly within a tolerance of N."

When Anti-Affinity Remains More Suitable

For relationships between different workloads (this Pod should avoid that other, differently labeled Pod entirely) rather than even distribution within a single workload's own replica set, pod anti-affinity remains the more natural expression.


Example

apiVersion: apps/v1
kind: Deployment
metadata:
  name: codartium-api
spec:
  replicas: 6
  selector:
    matchLabels:
      app: codartium-api
  template:
    metadata:
      labels:
        app: codartium-api
    spec:
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: "topology.kubernetes.io/zone"
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: codartium-api
      containers:
        - name: api
          image: codartium/api:latest