Configuring Pod Topology Spread Constraints
1. Understanding Topology Spread
| Field | Description | Example |
|---|---|---|
| maxSkew | Maximum number of pods allowed across topology domains | 1 |
| whenUnsatisfiable | How to handle unsatisfiable constraints | DoNotSchedule or ScheduleAnyway |
| labelSelector | Selector to identify pods for spreading | |
| topologyKey | Node label key to use for topology domain | kubernetes.io/hostname |
Example: Basic Topology Spread Constraint
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
topologySpreadConstraints:
- maxSkew: 1
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: frontend
topologyKey: kubernetes.io/hostname
Note:
maxSkew ensures pods are distributed evenly across nodes.Warning: Setting
whenUnsatisfiable: DoNotSchedule prevents scheduling if constraints can't be met.2. Setting Maximum Skew
| Field | Description | Values | Notes |
|---|---|---|---|
| maxSkew | Maximum skew allowed between the number of pods scheduled on different topology domains | 1, 2, etc. |
Default is 1. Must be a positive integer |
Example: Setting maxSkew to 2
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
topologySpreadConstraints:
- maxSkew: 2
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: my-app
3. Configuring When Unsatisfiable
| Field | Description | Values | Notes |
|---|---|---|---|
| maxSkew | Maximum skew allowed between topology zones | 1, 2, etc. |
Default is 1 |
| whenUnsatisfiable | How to handle cases where constraints cannot be satisfied | DoNotSchedule, ScheduleAnyway |
Default is DoNotSchedule |
Example: Setting whenUnsatisfiable to ScheduleAnyway
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
topologySpreadConstraints:
- maxSkew: 1
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: my-app
topologyKey: kubernetes.io/hostname
Note: When
whenUnsatisfiable is set to ScheduleAnyway, the Pod will be scheduled even if it cannot meet the topology spread constraints, potentially leading to uneven distribution.
4. Using Topology Keys
| Key | Description | Example |
|---|---|---|
| topologyKey | Specifies the node label key whose values are used to group pods | topology.kubernetes.io/zone |
| whenUnsatisfiable | How to handle pods when no matching topology is available | DoNotSchedule or ScheduleAnyway |
Example: Pod with Topology Key
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
affinity:
podTopologySpread:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: my-app
Note: The
topologyKey must match a label present on the nodes in your cluster.
Warning: Using
whenUnsatisfiable: ScheduleAnyway may lead to uneven distribution.
5. Configuring Label Selectors
| Field | Description | Values | Notes |
|---|---|---|---|
| labelSelector | Defines the label selector to match pods | null or object with matchLabels and/or matchExpressions |
Used to select pods based on labels for topology spread constraints |
| matchLabels | Map of key-value pairs to match pod labels | Object with label keys and their values | Simple key-value matching for labels |
| matchExpressions | List of expressions to match pod labels | Array of objects with key, operator, and values |
Advanced matching using operators like In, NotIn, Exists, DoesNotExist |
Example: Using labelSelector in Pod Topology Spread Constraints
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: web
version: v1
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: web
Note: The
labelSelector field is optional and defaults to selecting all pods if not specified.
Warning: If
labelSelector is not properly configured, the topology spread constraint may apply to unintended pods.
6. Setting Match Label Keys
| Field | Description | Values | Notes |
|---|---|---|---|
| matchLabelKeys | Defines the set of keys that should be matched | ["key1", "key2"] |
Keys must exist in pod labels |
Example: Match Label Keys Configuration
apiVersion: v1
kind: Pod
metadata:
labels:
env: production
region: us-west
spec:
topologySpreadConstraints:
- maxSkew: 1
minDomains: 2
matchLabelKeys:
- env
- region
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
7. Using Min Domains
| Field | Description | Values | Notes |
|---|---|---|---|
| minDomains | Minimum number of topology domains | int |
Ensures at least this many domains are used for spreading |
Example: Setting minDomains in Pod Spec
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
topologySpreadConstraints:
- maxSkew: 1
minDomains: 2
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
Note:
minDomains ensures that at least the specified number of topology domains are considered when spreading pods, even if it results in a skew that exceeds maxSkew.
8. Combining Multiple Constraints
Example: Pod Topology Spread Constraints with Multiple Selectors
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
topologySpreadConstraints:
- maxSkew: 1
minDomains: 2
overTerminationPolicy: DoNotTerminate
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: web
- maxSkew: 1
minDomains: 2
overTerminationPolicy: DoNotTerminate
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: web
| Field | Description | Values |
|---|---|---|
| maxSkew | Maximum skew between the number of pods in any two topology domains | 1 |
| minDomains | Minimum number of topology domains to consider for spreading | 2 |
| overTerminationPolicy | How to handle over-termination when constraints are violated | DoNotTerminate, Terminate |
| topologyKey | Key identifying the topology domain (e.g., hostname, zone) | kubernetes.io/hostname, topology.kubernetes.io/zone |
| whenUnsatisfiable | Action to take if constraints cannot be satisfied | ScheduleAnyway, DoNotSchedule |
| labelSelector | Label selector to identify pods to spread | matchLabels, matchExpressions |
Note: When combining multiple constraints, each constraint is evaluated independently. The scheduler will attempt to satisfy all constraints simultaneously.
Warning: If multiple constraints conflict, the scheduler will prioritize
whenUnsatisfiable: DoNotSchedule over ScheduleAnyway.Best Practices for Combining Constraints
- Use
maxSkewto control distribution across domains - Set
minDomainsto ensure sufficient topology diversity - Combine constraints with different
topologyKeyvalues for granular control - Use
labelSelectorto scope constraints to specific workloads - Consider
overTerminationPolicyfor graceful handling of pod termination
9. Understanding Node Inclusion Policy
| Policy | Description | Behavior | Notes |
|---|---|---|---|
| NodeInclusionPolicy | Controls whether to include or exclude nodes based on topology | Can be set to UseDefault, IgnoreUnreadyNodes, or IncludeUnreadyNodes |
Default is UseDefault, which includes ready nodes only |
Example: NodeInclusionPolicy in Pod Spec
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
topologySpreadConstraints:
- maxSkew: 1
minDomains: 1
nodeInclusionPolicy: IncludeUnreadyNodes
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
Note: Setting
nodeInclusionPolicy to IncludeUnreadyNodes allows scheduling on nodes that are not ready, which can be useful in maintenance scenarios.10. Troubleshooting Spread Issues
Example: Misconfigured Topology Spread Constraint
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: web
| Issue | Description | Solution |
|---|---|---|
| maxSkew too restrictive | When maxSkew is set too low, pods may not schedule due to lack of suitable nodes. |
Increase maxSkew or adjust topologyKey to allow more flexibility. |
| Incorrect topologyKey | Using a topologyKey that doesn't exist or is not populated on nodes. |
Verify topologyKey matches labels set on nodes (e.g., kubernetes.io/zone). |
| Label selector mismatch | Pods don't match the labelSelector, causing constraints to be ignored. |
Ensure labelSelector matches labels on pods and nodes. |
Note: Use
kubectl describe pod <pod-name> to view scheduling events and constraints.Warning: Setting
whenUnsatisfiable: DoNotSchedule can prevent pods from scheduling if constraints cannot be met.Workflow: Diagnose Spread Constraint Issues
- Check pod status with
kubectl get pods - Describe the pod to see events:
kubectl describe pod <pod-name> - Verify node labels:
kubectl get nodes -L <label-key> - Check if
maxSkewallows for distribution across available zones. - Adjust constraints if needed to allow scheduling.