> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Node groups and scheduling

`orchestrator`, `ingest`, and `worker` each take `nodeSelector`, `tolerations`, `affinity`, and `podAnnotations`.

## Run on amd64

FineParser images are built for `linux/amd64` only. If your cluster can also run `arm64` nodes, pin every component:

```yaml fineparser-values.yaml theme={null}
orchestrator:
  nodeSelector:
    kubernetes.io/arch: amd64
ingest:
  nodeSelector:
    kubernetes.io/arch: amd64
worker:
  nodeSelector:
    kubernetes.io/arch: amd64
```

## Give workers their own nodes

A large pool can fill every node it is allowed on. Put workers on a dedicated, tainted node group, and keep the orchestrator and ingest elsewhere. For nodes labeled and tainted `fineparser.abbyy.com/pool=worker`:

```yaml fineparser-values.yaml theme={null}
worker:
  nodeSelector:
    kubernetes.io/arch: amd64
    fineparser.abbyy.com/pool: worker
  tolerations:
    - key: fineparser.abbyy.com/pool
      operator: Equal
      value: worker
      effect: NoSchedule
```

## Pre-pulling the worker image

When many workers start on a new node at once, their image pulls can hit the kubelet's pull rate limit and slow the burst. With `worker.prepull` enabled, workers wait until the node has pulled the image once.

```yaml fineparser-values.yaml theme={null}
worker:
  prepull:
    enabled: true
    taintKey: startup-taint.cluster-autoscaler.kubernetes.io/fineparser-image
```

Worker nodes must register with a `NoSchedule` taint whose key is `taintKey`. A DaemonSet pulls the image on each new node and then removes the taint.

* **Karpenter:** list the taint in the NodePool's `startupTaints`.
* **Cluster Autoscaler:** create the node group's nodes with the taint. The default key's prefix tells Cluster Autoscaler the taint is temporary.

`images.worker.pullPolicy` must be `IfNotPresent`, and `worker.tolerations` must not tolerate the taint. Enabling it creates a ClusterRole that can get and patch Nodes.

## Node drains and interruptions

A stopping worker finishes its current unit first, within a 600-second grace period. If your node autoscaler limits drain time, allow at least that long on worker nodes. A worker stopped mid-unit loses that unit, which another worker retries once the lease expires.

Workers can run on Spot or preemptible capacity on that basis. Run the orchestrator and ingest on regular capacity: the orchestrator holds the queue, and the API is unavailable while it restarts.
