Configure pod scheduling
The Camunda Helm chart exposes values that control where Kubernetes schedules component pods. Use these settings to place pods on specific nodes, tolerate node taints, or spread pods across failure domains such as availability zones.
Configure scheduling values
Each of the following components supports nodeSelector, tolerations, and affinity values that map directly to the corresponding Kubernetes pod spec fields:
orchestrationidentityoptimizeconnectorswebModeler.restapiwebModeler.websockets
global.nodeSelector applies a node selector to all components that don't set their own.
By default, the chart configures a hard podAntiAffinity rule for the Orchestration Cluster so that no two broker pods are scheduled on the same node.
Spread Orchestration Cluster pods across availability zones
The default podAntiAffinity rule ensures broker pods run on distinct nodes, but does not ensure those nodes are in different zones: if the cluster has more nodes than brokers, all brokers can still be scheduled into a single availability zone. Because broker persistent volumes are bound to a single zone on most cloud providers, a zonal outage can then take down the whole Orchestration Cluster.
With orchestration.topologySpreadConstraints, you can spread broker pods across zones. The value is a list of Kubernetes topology spread constraints applied to the Orchestration Cluster StatefulSet pods, and it is empty by default. Those pods run the Zeebe broker and gateway in the same process, so this value covers both. It does not affect separately deployed components such as Identity, Optimize, Connectors, or Web Modeler, which have no equivalent topology spread value in the current chart version — use their affinity values instead.
orchestration:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/component: zeebe-broker
Keep the following in mind when configuring topology spread constraints:
- Set a
topologyKeythat your nodes carry.topology.kubernetes.io/zoneis standard on managed cloud clusters, but bare-metal and local clusters often have no zone label. WithwhenUnsatisfiable: DoNotScheduleand no matching node label, no broker can be scheduled at all. - Prefer
whenUnsatisfiable: ScheduleAnyway. It provides best-effort spreading: Kubernetes does not guarantee an even distribution and does not rebalance existing brokers. A hard constraint (DoNotSchedule) combined with the default hardpodAntiAffinitycan leave broker pods permanentlyPendingwhen zones have uneven node counts, or stall a rolling update — use it only when every zone has enough spare capacity. - Broker volumes pin pods to a zone. With topology-constrained storage,
volumeBindingMode: WaitForFirstConsumerdelays volume binding or provisioning until the scheduler picks a node, so the volume matches that node's topology;Immediatebinds or provisions the volume without considering pod scheduling constraints. Once a broker's claim is bound to a single-zone volume, every replacement pod must run in that zone: a hard zone constraint that conflicts with the volume's zone leaves the podPending, and enabling spreading on an existing cluster does not relocate existing volumes. - The
labelSelectorcounts pods across the whole namespace. Pods with matching labels from all Helm releases in the namespace are counted together, not only the release you are configuring. To scope spreading to a single release, also matchapp.kubernetes.io/instance: <release-name>.
Topology spread constraints control where Kubernetes schedules broker pods. They do not control where the application places partition replicas among brokers — configure zone-aware clusters for that. Configure both together: topology spread constraints put each broker pod in the zone Kubernetes actually schedules it into, and zone awareness places partition replicas according to each broker's assigned zone.
For broader production hardening guidance, see the production installation guide.