Node Affinity & Anti-Affinity with Elastic/Kibana📜
Affinity and scheduling constraints are exposed through the values.yaml options for this package. To schedule your pods onto specific nodes, you can utilize the nodeSelector field for simple constraints or the affinity field for more complex logic.
For a deep dive into how Kubernetes handles these rules, refer to the official Kubernetes documentation on scheduling.
Simple Node Selection (nodeSelector)📜
The nodeSelector is the simplest form of node selection constraint. It requires the node to have labels that match every key-value pair specified.
Example: Scheduling pods to nodes labeled with a specific node-type.
kibana:
nodeSelector:
node-type: kibana
elasticsearch:
master:
nodeSelector:
node-type: elastic-master
data:
nodeSelector:
node-type: elastic-data
Advanced Node Affinity (nodeAffinity)📜
Use nodeAffinity for more expressive rules, such as logical OR operators or “soft” preferences that allow pods to schedule elsewhere if the preferred nodes are full.
Note: The example below uses
requiredDuringSchedulingIgnoredDuringExecution(Hard Affinity). If the labels do not match, the pods will remain in a Pending state.
kibana:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values:
- "kibana"
elasticsearch:
master:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values:
- "elastic-master"
data:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values:
- "elastic-data"
Pod Anti-Affinity📜
Pod Anti-Affinity ensures that pods are not co-located on the same node (or rack). This is critical for high availability in Elasticsearch to ensure that master or data replicas are distributed across different physical hardware.
Example: Using topologyKey: "kubernetes.io/hostname" to ensure no two identical component pods land on the same node.
kibana:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: "kubernetes.io/hostname"
labelSelector:
matchLabels:
# Matches the label assigned to the component pods
dont-schedule-with: kibana
elasticsearch:
master:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: "kubernetes.io/hostname"
labelSelector:
matchLabels:
dont-schedule-with: elastic-master
data:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: "kubernetes.io/hostname"
labelSelector:
matchLabels:
dont-schedule-with: elastic-data
Best Practices & High Availability📜
- Quorum Protection: Always use Anti-Affinity for Elasticsearch master nodes. Losing multiple master nodes due to a single host failure can cause a cluster-wide outage.
- Soft Anti-Affinity: For larger clusters where you might have more pods than nodes (e.g., horizontal scaling), consider using
preferredDuringSchedulingIgnoredDuringExecution. This allows the cluster to stay online even if optimal distribution isn’t possible. - Resource Isolation: Use
nodeSelectorornodeAffinityto keep Elasticsearch data pods on nodes with high-performance SSD/NVMe storage for better I/O performance.