// Module included in the following assemblies:
//
// assembly-scheduling.adoc

[id='affinity-{context}']
= Specifying affinity, tolerations, and topology spread constraints

Use affinity, tolerations and topology spread constraints to schedule the pods of kafka resources onto nodes.
Affinity, tolerations and topology spread constraints are configured using the `affinity`, `tolerations`, and `topologySpreadConstraint` properties in following resources:

* `Kafka.spec.kafka.template.pod`
* `Kafka.spec.zookeeper.template.pod`
* `Kafka.spec.entityOperator.template.pod`
* `KafkaConnect.spec.template.pod`
* `KafkaBridge.spec.template.pod`
* `KafkaMirrorMaker.spec.template.pod`
* `KafkaMirrorMaker2.spec.template.pod`

The format of the `affinity`, `tolerations`, and `topologySpreadConstraint` properties follows the Kubernetes specification.
The affinity configuration can include different types of affinity:

* Pod affinity and anti-affinity
* Node affinity

NOTE: On Kubernetes 1.16 and 1.17, the support for `topologySpreadConstraint` is disabled by default.
In order to use `topologySpreadConstraint`, you have to enable the `EvenPodsSpread` feature gate in Kubernetes API server and scheduler.

.Additional resources

* {K8sAffinity}
* {K8sTolerations}
* {K8sTopologySpreadConstraints}

[id='con-scheduling-based-on-other-pods-{context}']
== Use pod anti-affinity to avoid critical applications sharing nodes

Use pod anti-affinity to ensure that critical applications are never scheduled on the same disk.
When running a Kafka cluster, it is recommended to use pod anti-affinity to ensure that the Kafka brokers do not share nodes with other workloads, such as databases.

[id='con-scheduling-to-specific-nodes-{context}']
== Use node affinity to schedule workloads onto specific nodes

The Kubernetes cluster usually consists of many different types of worker nodes.
Some are optimized for CPU heavy workloads, some for memory, while other might be optimized for storage (fast local SSDs) or network.
Using different nodes helps to optimize both costs and performance.
To achieve the best possible performance, it is important to allow scheduling of Strimzi components to use the right nodes.

Kubernetes uses node affinity to schedule workloads onto specific nodes.
Node affinity allows you to create a scheduling constraint for the node on which the pod will be scheduled.
The constraint is specified as a label selector.
You can specify the label using either the built-in node label like `beta.kubernetes.io/instance-type` or custom labels to select the right node.

[id='con-dedicated-nodes-{context}']
== Use node affinity and tolerations for dedicated nodes

Use taints to create dedicated nodes, then schedule Kafka pods on the dedicated nodes by configuring node affinity and tolerations.

Cluster administrators can mark selected Kubernetes nodes as tainted.
Nodes with taints are excluded from regular scheduling and normal pods will not be scheduled to run on them.
Only services which can tolerate the taint set on the node can be scheduled on it.
The only other services running on such nodes will be system services such as log collectors or software defined networks.

Running Kafka and its components on dedicated nodes can have many advantages.
There will be no other applications running on the same nodes which could cause disturbance or consume the resources needed for Kafka.
That can lead to improved performance and stability.
