Assigning Pods to Nodes
Use the targeting key in the Hydrolix spec to influence the Kubernetes scheduler.
How Kubernetes assigns pods to nodes⚓︎
The Kubernetes scheduler assigns pods to nodes based on resource availability and configurable placement constraints.
Available constraint mechanisms:
- Node name: Direct node selection using the
nodeNamefield. The pod runs only on the named node. - Node selector: A key-value label match. The scheduler places a pod only on nodes whose labels match the specified pairs.
- Node affinity: A more expressive constraint system that supports hard requirements (
requiredDuringSchedulingIgnoredDuringExecution) and soft preferences (preferredDuringSchedulingIgnoredDuringExecution). - Pod affinity: Constrains pod placement based on labels of pods already running on a node. For example, pod affinity can ensure that two frequently communicating services are scheduled in the same availability zone.
- Pod anti-affinity: Constrains pod placement to avoid co-locating certain pods on the same node or topology domain.
- Pod topology spread constraints: Controls how pods spread across failure domains such as regions, zones, and nodes.
For more detail, see Kubernetes: Assigning Pods to Nodes.
Use targeting in Hydrolix⚓︎
To make use of the Kubernetes scheduling mechanisms, use the spec.targeting key in the HydrolixCluster manifest.
Scope any mechanism using rules that apply to all pods, a service, or a pool. See Targeting priority for resolution of overlapping rules.
Automatic pod anti-affinity rules for availability
The Hydrolix operator automatically applies pod anti-affinity rules to several infrastructure components. These rules instruct the scheduler to spread pods across nodes, reducing the risk of a single node failure taking down an entire component.
Examples in this page demonstrate and explain the use of Kubernetes scheduling mechanisms in a Hydrolix cluster.
Node name⚓︎
| Configure Node Name | |
|---|---|
This example pins the query-head pod to a specific node by name. The pod is only scheduled on the node gke-hydrolix-demo-4a2b59be-clnb and remains pending if that node is unavailable.
See also Kubernetes: Node Name.
Node selector⚓︎
| Configure Node Selector | |
|---|---|
In this example, every pod must be scheduled on a node with the label node.kubernetes.io/instance-type: g6-dedicated-16. If there aren't enough nodes with the matching label, some pods remain in a pending state.
See also Kubernetes: Node Selector.
Node affinity⚓︎
| Configure Node Affinity | |
|---|---|
This example restricts all intake-head pods to nodes in the us-central1-f availability zone. Because this uses requiredDuringSchedulingIgnoredDuringExecution, pods remain pending if no nodes in that zone are available.
See also Kubernetes: Node Affinity.
Pod affinity⚓︎
| Configure Pod Affinity | |
|---|---|
This example requires that intake-head pods be scheduled in the same availability zone as pods with the label app: query-head. This is useful when two services communicate frequently and benefit from low-latency, same-zone placement.
See also Kubernetes: Pod Affinity.
Pod anti-affinity⚓︎
| Configure Pod Anti-affinity | |
|---|---|
This example expresses a soft preference to avoid scheduling postgres pods in the same availability zone as pods with the label security: S2. Because this uses preferredDuringSchedulingIgnoredDuringExecution with a weight, the scheduler tries to honor the constraint but can still co-locate the pods if necessary. See Pod Anti-affinity Rules for more information and additional examples.
See Kubernetes: Pod Anti-affinity
Pod topology spread constraints⚓︎
| Configure Pod Topology Spread Constraints | |
|---|---|
This example distributes batch-head pods evenly across availability zones, allowing a maximum skew of 1 pod between any two zones. If an even spread isn't possible, DoNotSchedule prevents the scheduler from placing additional pods.
See Kubernetes: Pod Topology Spread Constraints.
Targeting priority⚓︎
Targeting keys fall into three categories, applied in order of increasing priority:
- Default (
'*'): Global defaults applied to all services. Lowest priority. - Service name (for example,
intake-head): Overrides the global defaults for every pod belonging to that service, including all of its pools. - Pool name (for example,
pool:hydrologs-intake-head): Overrides both the global and service-level configuration for pods in that specific pool only. Highest priority.
When the operator reconciles a pooled service, it merges these entries with the highest priority winning. A value set at a more specific level replaces the same value from a less specific level.
The following example demonstrates targeting priority with intake-head services.
The intake-head entry schedules all intake-head pods, across every pool, into us-central1-f. The pool:hydrologs-intake-head entry overrides that for a single pool, placing its pods in us-central1-b. All other intake-head pools remain in us-central1-f.
Apply targeting to the operator⚓︎
The spec.targeting configuration is automatically applied to Hydrolix service workloads during the operator's reconciliation loop. However, the operator itself runs as a separate Kubernetes Deployment.
To apply the same targeting rules to the operator's own pod, pass the cluster configuration file when generating the operator manifests: