Explanation Document: Pod Anti-Affinity Configuration for PostgreSQL Cluster
Introduction
This document explains the pod anti-affinity configuration used in the PostgresCluster resource to ensure that the master and replica pods are scheduled on different nodes. It also delves into why role-based anti-affinity might not work and provides insights into the current working configuration.
Current Working Configuration
The following affinity configuration ensures that no two pods from the same PostgreSQL cluster are scheduled on the same node:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
postgres-operator.crunchydata.com/cluster: alice
postgres-operator.crunchydata.com/instance-set: cluster
topologyKey: kubernetes.io/hostname
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: db
operator: In
values:
- enabled
Key Components of the Configuration
1. podAntiAffinity
- Purpose: Ensures that no two pods with the specified labels are scheduled on the same node.
- Configuration:
matchLabels:postgres-operator.crunchydata.com/cluster: alice: Matches all pods belonging to thealicecluster.postgres-operator.crunchydata.com/instance-set: cluster: Matches all pods in theclusterinstance set.
topologyKey: kubernetes.io/hostname: Ensures that the anti-affinity rule is applied based on the node’s hostname.
2. nodeAffinity
- Purpose: Restricts scheduling to nodes with the
db=enabledlabel. - Configuration:
matchExpressions:key: db: Matches nodes with thedblabel.operator: In: Ensures the node’s label value is in the specified list.values: enabled: Matches nodes where thedblabel is set toenabled.
Why This Configuration Works
- Cluster-Wide Anti-Affinity:
- By targeting the cluster name (
postgres-operator.crunchydata.com/cluster: alice) and instance set (postgres-operator.crunchydata.com/instance-set: cluster), the anti-affinity rule applies to all pods in the cluster, including the master and replicas. - This ensures that no two pods from the same cluster are scheduled on the same node.
- By targeting the cluster name (
- Node Affinity:
- The
nodeAffinityrule ensures that pods are only scheduled on nodes with thedb=enabledlabel, providing additional control over pod placement.
- The
- Simplicity:
- This configuration avoids the complexity of role-based anti-affinity and ensures consistent behavior across all pods in the cluster.
Why Role-Based Anti-Affinity Might Not Work
1. Incorrect or Missing Labels
- Issue: The
postgres-operator.crunchydata.com/rolelabel (e.g.,masterorreplica) might not be applied correctly or consistently to the pods. - Solution:
- Verify the labels applied to the pods:
1
kubectl get pods -n db-ns -o yaml | grep -A 5 labels:
- Ensure the
postgres-operator.crunchydata.com/rolelabel is present and correct.
- Verify the labels applied to the pods:
2. Role Assignment Timing
- Issue: The role (master or replica) might be assigned after the pod is scheduled. If the anti-affinity rule is based on the role, it won’t be enforced during initial scheduling.
- Solution:
- Use cluster-wide anti-affinity (as in the current configuration) to ensure proper scheduling regardless of role assignment timing.
3. Insufficient Nodes
- Issue: If there are not enough nodes available with the
db=enabledlabel, Kubernetes might ignore the anti-affinity rules and schedule pods on the same node. - Solution:
- Ensure there are enough nodes with the
db=enabledlabel:1
kubectl get nodes -l db=enabled
- Add the
db=enabledlabel to additional nodes if necessary:1
kubectl label node <node-name> db=enabled
- Ensure there are enough nodes with the
4. Misconfigured Anti-Affinity Rules
- Issue: The anti-affinity rules might be targeting the wrong labels or topology.
- Solution:
- Double-check the
matchLabelsandtopologyKeyin thepodAntiAffinityconfiguration. - Use cluster-wide anti-affinity to avoid role-specific issues.
- Double-check the
5. Role Changes During Runtime
- Issue: If the role of a pod changes during runtime (e.g., from replica to master), the anti-affinity rules might not be re-evaluated.
- Solution:
- Use cluster-wide anti-affinity to ensure consistent behavior regardless of role changes.
Advantages of the Current Configuration
- Simplicity:
- The configuration is straightforward and avoids the complexity of role-based anti-affinity.
- Consistency:
- Ensures that all pods in the cluster are evenly distributed across nodes, regardless of their roles.
- Reliability:
- Works even if the role labels are missing, incorrect, or assigned after scheduling.
- Scalability:
- Easily scales to clusters with multiple replicas, ensuring no two pods are scheduled on the same node.
Conclusion
The current configuration using cluster-wide anti-affinity is the most reliable and effective way to ensure that master and replica pods are scheduled on different nodes. It avoids the pitfalls of role-based anti-affinity and provides consistent behavior across the cluster.
If you encounter further issues, ensure that:
- The correct labels are applied to the pods.
- There are enough nodes with the
db=enabledlabel. - The
podAntiAffinityandnodeAffinityrules are correctly configured.