> For the complete documentation index, see [llms.txt](https://docs.ionos.com/cloud/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ionos.com/cloud/home/containers/managed-kubernetes/how-tos/configure-node-pool-taints.md).

# Configure Taints and Tolerations

Configure taints and tolerations on IONOS CLOUD Managed Kubernetes node pools to control pod scheduling with the DCD, IONOS CLOUD API, Terraform, or kubectl.

Taints allow you to repel pods from specific nodes. A node with a taint does not accept any pod that does not explicitly tolerate that taint. Tolerations are applied to pods and allow the scheduler to place those pods on tainted nodes.

Use taints and tolerations together to:

* Reserve nodes for specific workloads, such as memory-heavy batch processing or high-priority services.
* Isolate nodes for compliance or security requirements.
* Control which workloads run on which node pools in your cluster.

For more information about taint components, taint effects and system taints, see [<mark style="color:blue;">Taints and tolerations</mark>](/cloud/home/containers/managed-kubernetes/overview/taints-and-tolerations.md).

{% hint style="info" %}
**Prerequisites:** Before you begin, ensure you have the following:

* An <code class="expression">space.vars.ionos\_cloud</code> Managed Kubernetes cluster. For more information, see [<mark style="color:blue;">Set Up a Kubernetes Cluster</mark>](/cloud/home/containers/managed-kubernetes/how-tos/cluster_management.md).
* At least one node pool configured in your cluster. For more information, see [<mark style="color:blue;">Manage Node Pools</mark>](/cloud/home/containers/managed-kubernetes/how-tos/management-of-node-pools.md).
* `kubectl` installed and configured to access your cluster.
* Depending on the method you use to configure node pool taints:
  * **DCD:** Access to the [<mark style="color:blue;">Data Center Designer (DCD)</mark>](https://dcd.ionos.com).
  * **IONOS CLOUD API:** A valid API token, and `ionosctl` v6.9.9 or later installed to look up your cluster and node pool IDs.
  * **Terraform:** The `ionoscloud` Terraform provider v6.7.37 or later.
* `ionosctl` v6.10.5 and later can set node pool taints: `ionosctl compute k8s nodepool create` takes `--taints`, and `ionosctl compute k8s nodepool update` takes `--taints`, `--add-taints`, and `--remove-taints`.
  {% endhint %}

## Add a taint

A node without taints accepts any pod that the scheduler assigns to it. Adding a taint is the first step in controlling workload placement. The taint keeps pods without a matching toleration away from the node. You can add a taint at two levels:

* **Node pool level:** The taint is part of the node pool specification and applies to all nodes in that pool. Use this level for lasting workload placement rules.
* **Individual node level:** The taint applies only to a single node and is lost when the node is replaced. Use this level for temporary changes or testing.

After you add a taint, add a matching toleration to the workloads that must run on the tainted nodes. For more information, see [<mark style="color:blue;">Add tolerations to a workload</mark>](#add-tolerations-to-a-workload).

### Add a taint to a node pool

You can add taints to an <code class="expression">space.vars.ionos\_cloud</code> Managed Kubernetes node pool through the DCD, the <code class="expression">space.vars.ionos\_cloud\_api</code>, or Terraform. Taints set at the node pool level are applied to all nodes in that pool.

{% tabs %}
{% tab title="DCD" %}
You can configure taints when creating or updating a node pool through the **Advanced settings** section in the [<mark style="color:blue;">Data Center Designer (DCD)</mark>](https://dcd.ionos.com). For more information, see [<mark style="color:blue;">Configure Advanced settings</mark>](/cloud/home/containers/managed-kubernetes/how-tos/management-of-node-pools.md#configure-advanced-settings).

{% stepper %}
{% step %}

#### Navigate to Managed Kubernetes

1. In the **DCD**, go to **Menu** > **Containers** > **Managed Kubernetes**.
2. Select a cluster from the list and go to the **Node pools in Cluster** tab.
3. Select the node pool you want to configure, or select **Add node pool** to create a new one.
   {% endstep %}

{% step %}

#### Configure Advanced settings

Scroll to the **Advanced settings** section and go to **Taints**. For each taint, enter the following details and select **Add**:

* **Key:** The taint identifier. Example: `workload`.
* **Value:** An optional label. Example: `batch`.
* **Effect:** Select `NoSchedule`, `PreferNoSchedule`, or `NoExecute`.

Each added taint is listed in the `key=value:Effect` format. Example: `workload=batch:NoSchedule`. Repeat these steps for each taint you want to add.

{% hint style="info" %}
**Note:** You cannot edit an existing taint. To change a taint, remove it and add a new one with the updated key, value, or effect. For more information, see [<mark style="color:blue;">Remove a taint from a node pool</mark>](/cloud/home/containers/managed-kubernetes/how-tos/remove-taint.md#remove-a-taint-from-a-node-pool).
{% endhint %}
{% endstep %}

{% step %}

#### Save changes

Select **Edit node pool** (or **Create node pool** for a new pool). The node pool state changes to **Deploying** while the changes are applied. When the node pool reaches the **Available** state, the taints apply to all nodes in the pool. Adding or removing node pool taints updates the existing nodes in place. The nodes are not replaced.
{% endstep %}
{% endstepper %}
{% endtab %}

{% tab title="IONOS CLOUD API" %}
{% hint style="warning" %}
**Warning:** The `taints` array in the request replaces all existing taints on the node pool. To keep existing taints, include them in the array with the new taint.
{% endhint %}

1. Find your cluster ID and node pool ID:

   ```bash
   # List clusters
   ionosctl compute k8s cluster list

   # List node pools in your cluster
   ionosctl compute k8s nodepool list --cluster-id CLUSTER_ID
   ```
2. Add a taint to the node pool:

   ```bash
   curl -X PUT \
     "https://api.ionos.com/cloudapi/v6/k8s/CLUSTER_ID/nodepools/NODEPOOL_ID" \
     -H "Authorization: Bearer YOUR_API_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
       "properties": {
         "nodeCount": NODE_COUNT,
         "taints": [
           {
             "key": "workload",
             "value": "batch",
             "effect": "NoSchedule"
           }
         ]
       }
     }'
   ```

   Replace `CLUSTER_ID`, `NODEPOOL_ID`, `YOUR_API_TOKEN`, and `NODE_COUNT` with your values. `NODE_COUNT` is the current number of nodes in the node pool. The `nodeCount` property is required in every update request. To add more than one taint, include all taints in the `taints` array.

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p><strong>Note:</strong> Within a node pool, each taint must have a unique combination of key and effect. The API rejects duplicate key-effect pairs, even with different values, with HTTP <code>422</code> and error code <code>631</code>.</p></div>
3. Verify the taints are applied to nodes in the pool:

   ```bash
   kubectl get nodes -o custom-columns='NAME:.metadata.name,TAINTS:.spec.taints'
   ```

{% endtab %}

{% tab title="Terraform" %}
You can configure taints on a node pool using the `taints` block in the `ionoscloud_k8s_node_pool` resource. Ensure that you have a Terraform provider **v6.7.37 or later**.

```hcl
resource "ionoscloud_k8s_node_pool" "example" {
  # ... other node pool configuration ...

  taints {
    key    = "workload"
    value  = "batch"
    effect = "NoSchedule"
  }
}
```

Each `taints` block defines one taint, up to the limit of 50 taints per node pool. Each block supports:

* `key`: The taint key. Required. Follow the key format described in [<mark style="color:blue;">Understanding taints and tolerations</mark>](/cloud/home/containers/managed-kubernetes/overview/taints-and-tolerations.md#understanding-taints-and-tolerations).
* `value`: The taint value. Optional. Follow the value format described in [<mark style="color:blue;">Understanding taints and tolerations</mark>](/cloud/home/containers/managed-kubernetes/overview/taints-and-tolerations.md#understanding-taints-and-tolerations).
* `effect`: The taint effect. Required. Must be one of `NoSchedule`, `PreferNoSchedule`, or `NoExecute`.

For the full resource reference, see [<mark style="color:blue;">ionoscloud\_k8s\_node\_pool</mark>](https://registry.terraform.io/providers/ionos-cloud/ionoscloud/latest/docs/resources/k8s_node_pool).
{% endtab %}
{% endtabs %}

### Apply a taint to an individual node

You can apply a taint directly to a single node using `kubectl`, which is ideal for temporary changes or testing.

{% hint style="info" %}
**Note:** Taints that you add to a node with `kubectl` stay when <code class="expression">space.vars.ionos\_cloud</code> Managed Kubernetes applies the node pool settings again, for example after a node pool update. A node taint with the same key and effect as a node pool taint is then set back to the node pool value. If you change or remove a node pool taint with `kubectl`, the change lasts until the node pool settings are applied again. Taints added with `kubectl` are lost when the node is replaced.
{% endhint %}

1. List the nodes in your cluster:

   ```bash
   kubectl get nodes
   ```
2. Apply the taint:

   ```bash
   kubectl taint nodes NODE_NAME key=value:EFFECT
   ```

   For example, to mark a node as dedicated for batch workloads:

   ```bash
   kubectl taint nodes worker-node-1 workload=batch:NoSchedule
   ```
3. Verify the taint:

   ```bash
   kubectl describe node NODE_NAME | grep Taints
   ```

   Output:

   ```
   Taints: workload=batch:NoSchedule
   ```

## Add tolerations to a workload

To schedule a pod on a tainted node, add a `tolerations` block to the pod specification. The toleration must match the taint on the target node.

{% tabs %}
{% tab title="Pod" %}

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx
  tolerations:
  - key: "workload"
    operator: "Equal"
    value: "batch"
    effect: "NoSchedule"
```

{% endtab %}

{% tab title="Deployment" %}

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx
      tolerations:
      - key: "workload"
        operator: "Equal"
        value: "batch"
        effect: "NoSchedule"
```

{% endtab %}
{% endtabs %}

To apply the toleration and verify the pod placement, follow these steps:

1. Save the manifest to a file and apply it:

   ```bash
   kubectl apply -f FILE_NAME.yaml
   ```
2. Check which nodes the pods run on:

   ```bash
   kubectl get pods -o wide
   ```

   The `NODE` column shows the node for each pod. Pods with a matching toleration can run on the tainted nodes.

{% hint style="info" %}
**Note:** A toleration allows a pod to run on a tainted node but does not force it there. To keep a workload on a specific node pool, also add a `nodeSelector` that matches the node pool labels.
{% endhint %}

### Toleration operators

| **Operator** | **Behavior**                                         | `value` **required?** |
| ------------ | ---------------------------------------------------- | --------------------- |
| `Equal`      | The key and value must match the taint exactly.      | Yes                   |
| `Exists`     | Matches any taint with this key, whatever its value. | No                    |

### Tolerate a `NoExecute` taint with a grace period

If you add a `NoExecute` taint to a node, running pods without a matching toleration are evicted immediately. Add `tolerationSeconds` to delay eviction.

```yaml
tolerations:
- key: "maintenance"
  operator: "Equal"
  value: "scheduled"
  effect: "NoExecute"
  tolerationSeconds: 3600
```

This pod is evicted 3,600 seconds (1 hour) after the taint is applied to the node.

## Next steps

* [<mark style="color:blue;">Remove a Taint</mark>](/cloud/home/containers/managed-kubernetes/how-tos/remove-taint.md)
* [<mark style="color:blue;">Taints and tolerations overview</mark>](/cloud/home/containers/managed-kubernetes/overview/taints-and-tolerations.md)
* [<mark style="color:blue;">Kubernetes Documentation about Taints and Tolerations</mark>](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)
* [<mark style="color:blue;">Manage Node Pools</mark>](/cloud/home/containers/managed-kubernetes/how-tos/management-of-node-pools.md)
* [<mark style="color:blue;">Update a Node Pool</mark>](/cloud/home/containers/managed-kubernetes/how-tos/update-node-pool.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.ionos.com/cloud/home/containers/managed-kubernetes/how-tos/configure-node-pool-taints.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
