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

# Node Pools

> Create, scale, label, taint, upgrade, and delete LKS Node Pools on new or existing Servers

A Node Pool is a group of identical bare metal Nodes. Every Node in a Node Pool shares the same plan. A Cluster can have several Node Pools, letting you run different plans side by side (for example CPU and GPU Nodes) and target Workloads at specific Node Pools with Labels and Taints.

## Node Pool modes

Every Node Pool has a mode. You set it when you create the Node Pool, and it can't be changed afterward.

* **On-demand** (default): LKS provisions new Servers from a plan.
* **Allocated**: LKS runs the Node Pool on bare metal Servers you already have in the Cluster's project. Each Server is reinstalled with the Node image and joins the Cluster.

| | On-demand | Allocated |
| - | - | - |
| Nodes run on | New Servers provisioned from a plan. | Servers you already have in the Cluster's project. |
| Size | A plan and a Node count. | The Servers you select, all on one plan. |
| Change capacity | Scale the Node count. | Add or remove your Servers. |
| Upgrades | A new Node joins before an old one is removed. | Each Server is reinstalled, one at a time. |
| When a Node leaves | Its Server is destroyed. | Its Server is reinstalled with Ubuntu 24.04 and stays in your project. |
| Billing | Hourly [bare metal pricing](https://www.latitude.sh/pricing) per Node. | The Server keeps its existing billing. |

A Cluster can mix both modes. For example, an allocated Node Pool with Servers you already run and an on-demand Node Pool for extra capacity.

> [!WARNING]
>
> Adding a Server to an allocated Node Pool reinstalls it. Everything on the Server is lost, so back up any data you need before you select it.

## Server requirements for Allocated mode

A Server can join an allocated Node Pool when it:

* Is a bare metal Server in the Cluster's project and location.
* Was deployed as a [BGP-ready Server](https://www.latitude.sh/docs/networking/elastic-ips-bgp.md#deploy-a-bgp-ready-server). This is set when the Server is deployed and can't be turned on afterward.
* Isn't bonded onto a [public network](https://www.latitude.sh/docs/networking/public-networks.md) and has no [Firewall](https://www.latitude.sh/docs/networking/firewall.md) assigned.
* Isn't locked, scheduled for deletion, in [rescue mode](https://www.latitude.sh/docs/servers/rescue-mode.md), or still being deployed or reinstalled.
* Isn't already in a Node Pool of any Cluster.

All Servers in an allocated Node Pool must be on the same plan, and the Node Pool takes its plan from them.

The Server picker lists only Servers that can join. Servers you can't pick right now, such as one already selected for another Node Pool in the same form, show the reason next to their name.

### Why a Server can't join

When a Server can't join, the picker or the error message shows one of these reasons:

| Reason | What to do |
| - | - |
| Not found in this project | Use a Server in the Cluster's project, or [move the Server](https://www.latitude.sh/docs/servers/change-project.md) to it first. |
| In a different location | Use a Server in the Cluster's location. |
| Not a bare metal server | Use a bare metal Server. |
| Already in a Node Pool | Remove the Server from its current Node Pool first. |
| Locked | Unlock the Server. |
| Scheduled for deletion | [Cancel the scheduled deletion](https://www.latitude.sh/docs/servers/deleting-a-server.md#canceling-a-scheduled-deletion), or use another Server. |
| In rescue mode | Take the Server out of [rescue mode](https://www.latitude.sh/docs/servers/rescue-mode.md). |
| Being provisioned | Wait for the deploy or reinstall to finish. |
| Assigned to a Firewall | [Remove the Firewall assignment](https://www.latitude.sh/docs/networking/firewall.md#assigning-a-firewall-to-resources). |
| Attached to a public network | [Remove the Server from its public network](https://www.latitude.sh/docs/servers/network-bonding.md#removing-a-bond-teardown). |
| Network setup not supported | The Server's network setup can't run LKS Nodes. Use another Server. |
| Not deployed BGP-ready | Use a Server deployed as [BGP-ready](https://www.latitude.sh/docs/networking/elastic-ips-bgp.md#deploy-a-bgp-ready-server). An existing Server can't be made BGP-ready. |
| Different plan from the selected servers | Select Servers of a single plan. |
| Selected for another Node Pool | A Server can be in only one Node Pool. Clear it from the other Node Pool first. |

## Add a Node Pool

**1. Open the Node Pools tab**

Open your Cluster and go to the **Node Pools** tab. Click **Add Node Pool**.

**2. Choose a mode**

Under **Mode**, keep **On-demand** to provision new Servers, or select **Allocated** to use Servers you already have. See [Node Pool modes](#node-pool-modes).

**3. Choose the Nodes**

* **On-demand**: choose a **Plan** for every Node in the Node Pool, and how many **Nodes** to provision (at least 1).
* **Allocated**: under **Servers**, select at least one Server. The list shows the project's Servers at the Cluster's location that meet the [Server requirements](#server-requirements-for-allocated-mode).

**4. Configure the Node Pool**

Set:

* **Description** (optional): a short description of the Node Pool, up to 200 characters.
* **Max Pods per Node** (optional): the maximum number of Pods that can run on each Node. See [Max Pods per Node](#max-pods-per-node).
* **Labels** (optional): key-value pairs applied to every Node in the Node Pool.
* **Taints** (optional): rules that repel Pods from the Node Pool's Nodes unless the Pods tolerate them.

**5. Add the Node Pool**

Click **Add Node Pool**. An on-demand Node Pool provisions its Nodes; an allocated Node Pool reinstalls its Servers with the Node image. The Nodes then join the Cluster.

You can also add multiple Node Pools, in either mode, when you first [create a Cluster](https://www.latitude.sh/docs/lks/clusters.md#create-a-cluster).

## Max Pods per Node

Max Pods per Node sets the maximum number of Pods that can run on each Node in a Node Pool. You set it with the **Max Pods per Node** field when you create the Node Pool. It's optional and can't be changed after the Node Pool is created.

* Enter a whole number between **16 and 500**.
* Leave it blank to use the default of **110**.

The value is shown on the Node Pool's detail view; a Node Pool left at the default shows `110 (default)`.

## Node Pool status

The Node Pools table shows each pool's current state. These are separate from the [Cluster status](https://www.latitude.sh/docs/lks/clusters.md#cluster-status).

| Status | Meaning |
| - | - |
| Provisioning | The pool is being created and its Nodes are joining. |
| Active | The pool is ready. |
| Scaling | The pool's Node count is changing. |
| Updating | A change to the pool's Labels or Taints is being applied. |
| Upgrading | The pool's Kubernetes version is being upgraded. |
| Degraded | The pool is running with reduced health. |
| Paused | Paused by Latitude support; changes are blocked until it's unpaused. |
| Deleting | The pool is being removed. |
| Error | The last operation failed. |

## Scale an On-demand Node Pool

Open the **Node Pools** tab, open the Node Pool's actions menu, and click **Scale**. Set the new Node count and confirm. Scaling up provisions and joins new Nodes; scaling down drains and removes Nodes.

A Node Pool must always have at least one Node. You can't scale a Node Pool to 0 Nodes. To remove its capacity entirely, delete the Node Pool instead.

> [!NOTE]
>
> When a Node is removed (scaling down, upgrading a Node Pool, or deleting a Node Pool), LKS drains it first and gives its Pods up to 30 minutes to reschedule elsewhere. If a Pod can't be evicted within that window, for example because of a misconfigured PodDisruptionBudget, the Node is removed once the 30 minutes elapse.

## Scale an Allocated Node Pool

Allocated Node Pools scale by their Servers, not by a count. Open the **Node Pools** tab, open the Node Pool's actions menu, and click **Manage servers**. Select the Servers to add, clear the ones to remove, and click **Save changes**. The Node Pool shows **Scaling** while the changes are applied.

* Added Servers are reinstalled with the Node image and join the Cluster.
* Removed Servers are drained and returned to your project. See [When a Server leaves an Allocated Node Pool](#when-a-server-leaves-an-allocated-node-pool).

An allocated Node Pool must keep at least one Server. To return all of them, delete the Node Pool.

## Rename a Node Pool

You can rename a Node Pool after it's created. Open the Node Pool's actions menu and update its **Name**. This changes the display name only.

## Labels and Taints

Labels and Taints steer Workloads to the right Nodes.

* **Labels** are key-value pairs applied to every Node in the Node Pool. Use them as `nodeSelector` or affinity targets. See the Kubernetes guide to [Labels and Selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/).
* **Taints** repel Pods from the Node Pool's Nodes unless a Pod tolerates the Taint. Each Taint has a key, an optional value, and an effect: `NoSchedule`, `PreferNoSchedule`, or `NoExecute`. See the Kubernetes guide to [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/).

To change them on an existing Node Pool, open the Node Pool's actions menu and click **Edit Labels & Taints**.

### Rules

* A Node Pool can have up to 50 Labels and up to 50 Taints.
* Keys follow Kubernetes key syntax and may include an optional prefix (`prefix/name`).
* A Taint effect must be `NoSchedule`, `PreferNoSchedule`, or `NoExecute`. The same key can appear with different effects, but not twice with the same effect.
* These key prefixes are reserved and are rejected: `kubernetes.io`, `k8s.io`, `cluster.x-k8s.io`, and `lks.latitude.sh`, along with their subdomains. Keys without a prefix, such as `env` or `team`, are always allowed.

> [!WARNING]
>
> The `NoExecute` effect evicts running Pods that don't tolerate the Taint from the Node Pool's Nodes.

> [!WARNING]
>
> Keep at least one Node Pool, with at least one Node, free of `NoSchedule` and `NoExecute` Taints. LKS runs critical Pods such as the Cluster's DNS and load balancing on your Nodes. If every Node Pool carries a `NoSchedule` or `NoExecute` Taint, these Pods have nowhere to run and the Cluster can lose DNS and LoadBalancer functionality.

## Upgrade a Node Pool

A Node Pool runs its own Kubernetes version and can trail the Control Plane by at most one minor version. After you upgrade the Control Plane, upgrade each Node Pool to match.

Open the **Node Pools** tab. When a Node Pool is behind the Cluster version, its row shows **Upgrade available**. Open the Node Pool's actions menu and click **Upgrade version**.

> [!WARNING]
>
> Upgrading a Node Pool recreates its Nodes and can't be reversed. Run your Workloads with enough replicas to tolerate Nodes being replaced.

An allocated Node Pool gets no new Servers during an upgrade. LKS drains and reinstalls each Server in place, one at a time, so one Node at a time is out of service. A Node Pool with a single Server has no capacity while it upgrades; run at least two Servers to keep Workloads running.

## Node images and updates

Node operating system images are provided and owned by Latitude.sh. New images reach your Nodes when you upgrade a Node Pool, scale it, or add a new Node Pool. There's no in-place OS patching for you to run.

## Delete a Node Pool

Open the Node Pool's actions menu and click **Delete Node Pool**, then confirm.

> [!WARNING]
>
> Deleting a Node Pool destroys its Nodes. Workloads running on them are rescheduled to other Node Pools when capacity is available, or stop if it isn't.

Deleting an allocated Node Pool doesn't destroy its Servers. Each one is drained and returned to your project. See [When a Server leaves an Allocated Node Pool](#when-a-server-leaves-an-allocated-node-pool).

## Servers in Node Pools

### While a Server is a Node

Every Node runs on a bare metal Server in the Cluster's project. LKS manages the Server while it's a Node, so these actions are blocked until it leaves its Node Pool:

* Delete or schedule deletion.
* Reinstall or rescue mode.
* Power off.
* Lock.
* Change the hostname.
* Move to another project.
* Switch to yearly billing.

You can still reboot the Server and edit its tags.

In an allocated Node Pool, a Node that fails its health checks is repaired by reinstalling the same Server.

### Find the Server behind a Node

On the **Node Pools** tab, expand a Node Pool's row or switch to **Nodes** to list the Nodes. Click a Node to open **Node details**, which shows its **Server**. Click **View server** to open the Server.

### When a Server leaves an Allocated Node Pool

A Server leaves an allocated Node Pool when you remove it with **Manage servers**, delete its Node Pool, or delete the Cluster. In each case, LKS:

1. Drains the Node, giving its Pods up to 30 minutes to reschedule elsewhere.
2. Reinstalls the Server with Ubuntu 24.04, with no SSH keys or user data and a hostname based on its Server ID.
3. Returns the Server to your project.

The Server keeps its billing. To use it again, [reinstall it](https://www.latitude.sh/docs/servers/reinstalling-a-server.md) with your own SSH keys and settings.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.