---
title: Node placement
description: "How the OpenLM Platform chart decides which nodes run which pods: the openlm.com/role label, taints, and when to turn placement on."
product: OpenLM Platform
---

Turn placement on when you want to keep OpenLM Platform on its own nodes, for example to separate it from other workloads, or to give the data-processing jobs nodes of their own.

By default, Kubernetes runs a pod on any node with room for it. That's fine for most installations, and it's what this guide sets up: placement is **off**.

## How the chart does it

Every component belongs to one of two groups:

| Group | Label value | What's in it |
|---|---|---|
| Services and UIs | `main` | Almost everything: about 100 components |
| Data processing | `spark` | The jobs that prepare reporting data: `sparkmongo`, `sparkmssql`, `licenseconcurency`, `officetimecalculation`, `denialsaggregation` and a few optional ones |

With placement on, each pod **requires** a node with the label `openlm.com/role` set to its group, and **tolerates** a taint with the same key and value:

```yaml
# what the chart adds to every pod when placement is on (component in group "main")
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        - matchExpressions:
            - { key: openlm.com/role, operator: In, values: [main] }
tolerations:
  - { key: openlm.com/role, operator: Equal, value: main, effect: NoSchedule }
```

The two switches are independent:

| Setting | What it does |
|---|---|
| `global.affinity.enabled: true` | Pods run **only** on nodes labeled `openlm.com/role=main` (or `=spark`). |
| `global.taints.enabled: true` | Pods **can** run on nodes tainted `openlm.com/role=main:NoSchedule` (or `spark`). Other workloads are kept off those nodes by the taint. |

The usual combination is both on: dedicated nodes that only OpenLM Platform uses.

:::danger[Label the nodes before you turn affinity on]
With `global.affinity.enabled: true`, a pod waits in `Pending` forever if no node carries its label. Label at least one node per group first. Both groups, `main` and `spark`, need nodes.
:::

## Turn placement on

To turn placement on:

1. Label (and, if you want exclusive nodes, taint) the nodes:

   ```bash
   kubectl label node <node> openlm.com/role=main
   kubectl taint node <node> openlm.com/role=main:NoSchedule      # optional: keep other pods off
   kubectl label node <spark-node> openlm.com/role=spark
   kubectl taint node <spark-node> openlm.com/role=spark:NoSchedule
   ```

   On managed clusters, set labels and taints on the **node group or node pool** instead, so new nodes get them automatically. See [EKS](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/kubernetes/platforms/eks#node-groups) and [AKS](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/kubernetes/platforms/aks#node-pools).

2. Turn both switches on in `openlm-values.yaml`:

   ```yaml
   global:
     affinity: { enabled: true }
     taints:   { enabled: true }
   ```

3. Apply the change with the same `helm upgrade --install` command as in [step 6](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/kubernetes/install/step-6-install).

:::warning[The label values are exactly `main` and `spark`]
Values such as `main-workload` or `reporting` don't work. Node groups created from other templates often use different values. Check with `kubectl get nodes -L openlm.com/role`.
:::

## Your data services and placement

The placement settings apply only to the OpenLM Platform components. If you run MongoDB, Kafka or Redis inside the cluster, place them with their own charts' settings. The following table shows a common layout:

| Node group | Label | Runs |
|---|---|---|
| Platform | `openlm.com/role=main` | OpenLM services and UIs, API gateway |
| Data processing | `openlm.com/role=spark` | Reporting data jobs |
| Infrastructure | your own label | MongoDB, Kafka, Redis, ingress controller |

## When you can't label nodes

On certain managed or shared clusters, for example a namespace on a shared OpenShift cluster, you don't have permission to label nodes. Leave both settings `false`. OpenLM Platform runs fine without placement.
