← All insights
ENGINEERING JOURNAL / Kubernetes Operations

Topology Spread and Anti-Affinity: Explain Pending Pods

Investigate a Pending Pod by combining topology labels, spread selectors and anti-affinity rules. Check all placement constraints before relaxing policy.

Topology Spread and Anti-Affinity: Explain Pending PodsTopology Spread and Anti-Affinity: Explain Pending Pods — conceptual 3D-style vector showing Incoming Pod, Spread constraint, Anti-affinity, Eligible nodes, Zone A, Zone B.. Conceptual teaching illustration; connections show the investigation flow rather than a vendor deployment topology.CLOUVENIX / KUBERNETES OPERATIONSTopology Spread and Anti-Affinity: Explain Pending Pods01Incoming Pod02Spread constraint03Anti-affinity04Eligible nodes05Zone A06Zone BConceptual investigation flow / Topology Spread and Anti-Affinity: Explain Pending Pods
Topology Spread and Anti-Affinity: Explain Pending Pods — conceptual 3D-style vector showing Incoming Pod, Spread constraint, Anti-affinity, Eligible nodes, Zone A, Zone B.

Context

Topology spread constraints and Pod anti-affinity both influence placement, but they ask different questions. Spread constraints control how evenly matching Pods are distributed across topology domains. Anti-affinity can prevent placement beside selected Pods. A cluster with free memory can still have no node satisfying both rules.

Start with the Pending Pod, namespace, intended failure-domain policy, and permission to read Pods and node labels. Do not change scheduling rules during the first pass. You need to determine whether the policy is internally inconsistent, whether domain labels are missing, or whether eligible capacity has changed.

1. Read the actual scheduling rejection

kubectl -n shop describe pod catalog-pending
kubectl -n shop get pod catalog-pending -o yaml
kubectl get nodes -L topology.kubernetes.io/zone,kubernetes.io/hostname

Read all relevant scheduling event reasons, not just the first one. Resource requests, taints, node affinity, storage constraints, spread rules, and anti-affinity can combine. The scheduler needs an intersection of eligible nodes. Solving one reason does not guarantee placement if a different constraint still excludes those nodes.

2. Reconstruct the domains and selected Pods

kubectl -n shop get pods -l app=catalog -o wide
kubectl -n shop get deployment catalog -o yaml

Check topologyKey, labelSelector, maxSkew, and whenUnsatisfiable in each spread constraint. Compare the selector with both existing Pod labels and the incoming Pod. Count matching Pods by eligible domain using the observed node labels. A typo in the topology label or selector can make your mental model differ from the scheduler's view.

For required anti-affinity, identify which existing Pods create exclusions and across which topology key. A hostname-level exclusion means something different from a zone-level exclusion. Missing topology labels also deserve explicit attention because they affect which domains the scheduler can reason about.

3. Evaluate a concrete placement

For an explicitly illustrative example, three replicas must be spread across two zones while required hostname anti-affinity prevents two replicas sharing a node. Zone B has only one eligible node, already occupied by a matching Pod, and the remaining nodes are in zone A. Spare capacity in zone A does not prove that another replica can satisfy the combined spread and exclusion rules.

Evaluate each candidate node against every constraint. With DoNotSchedule, the spread rule can reject a placement that exceeds its allowed imbalance. ScheduleAnyway expresses a preference instead, while other hard requirements can still prevent scheduling. Changing that setting is a reliability decision, not merely a troubleshooting shortcut.

Use a placement evidence table

EvidenceLikely issueCorrection to review
Eligible node lacks topology labelIncomplete domain inventoryCorrect managed node labeling
Selected Pod count differs from expectedSelector mismatchAlign workload and spread labels
Required anti-affinity excludes the last domainPolicy and capacity conflictAdd eligible capacity or redesign policy
Spread is satisfied but Pod remains PendingAnother hard constraintRe-read every scheduler reason

Review policy changes with the owner of the failure-domain requirement. Increasing skew or converting a requirement into a preference can reduce resilience during a zone or node failure. Adding suitable capacity may preserve the intended protection better than relaxing the rule.

Verify and keep the policy reviewable

After the approved correction, inspect the assigned node and count the resulting distribution. Repeat the check during a controlled rolling update, when old and new Pods coexist. Confirm the application still has the required failure-domain coverage.

Keep a scheduling SOP with domain labels, matching selector, intended replica distribution, and minimum eligible capacity. Monitor prolonged Pending conditions alongside missing topology labels and capacity changes. Review this contract whenever replicas, taints, node pools, or rollout surge settings change.

Explore Clouvenix containers kubernetes for implementation and operational handover.

Technical reference

Topology spread constraints and Pod affinity and anti-affinity.