# Provision Dedicated SKS Nodepools

In this guide, we will make use of your Dedicated Hypervisors to run [Nodepools]({{< ref "/product/compute/containers/overview/#nodepools" >}}) for an [Exoscale Scalable Kubernetes Service (SKS)]({{< ref "/product/compute/containers/" >}}) cluster, using your Dedicated Hypervisor. 

>[!NOTE]
> You need to have a Dedicated Hypervisor behind a Deployment target to proceed, if you are looking for SKS Nodepools on Shared Compute please follow [Nodepools]({{< ref "/product/compute/containers/overview/#nodepools" >}})

## Prerequisites

To interact with Exoscale SKS and the resulting Kubernetes cluster, the
following items are required:

* An Exoscale account with access to an organization where Dedicated Hypervisors have been provisioned
* The latest version of the Exoscale [CLI]({{< ref "/tools/command-line-interface/" >}})
* A [Deployment Target]({{< ref "/product/compute/dedicated-hypervisors/overview/#deployment-target" >}}) assigned to your organization. *Without this you will not be able to launch instances on your dedicated Hypervisor*.
* A Deployment Target in the same Zone where you plan to create the SKS cluster and its worker Nodepools

### Confirm deployment target

A [Deployment Target]({{< ref "/product/compute/dedicated-hypervisors/overview/#deployment-target" >}}) is a virtual abstraction layer that allows you to provision Compute Instances onto dedicated hypervisors.

Run the following command with valid credentials for the target account, be sure to use the correct [Zone]({{< ref "/platform/dc-zones/#building-around-the-zone-concept" >}}):

```bash
exo api list-deploy-targets  --zone=ch-gva-2 
```

  <details>

  <summary>Example output</summary>

  

  ```bash
  exo api list-deploy-targets  --zone=ch-gva-2 
  {
    "deploy-targets": [
    {
      "description": "dedicated resources group",
      "id": "c9a64f12-3ba7-4c19-bd93-61f2d84c3e55",
      "name": "Dedicated-ch-gva-coe",
      "type": "dedicated"
    }
  ]
  }

  ```

  </details>

> [!NOTE]
> Make note of the Deployment Target ID, you will need it to proceed with the next steps. 


## Creating a Cluster from the CLI

> [!NOTE]
> If you have a pre-existing SKS cluster already, you can skip to [Managing NodePools on Existing Clusters](#managing-nodepools-on-existing-sks-clusters)

Creating a cluster can be done with the `exo compute sks create`
command, which creates a control plane. By default, the CNI Calico is
deployed on the cluster. The Exoscale Cloud Controller Manager (CCM) is
automatically wired for interaction with Exoscale IaaS.

Because Kubernetes is a clustered application, the control plane and the nodes
need to communicate. Useful ingress ports to have open in your security group before starting:

* 30000 to 32767 TCP from all sources for NodePort and LoadBalancer services
* 10250 TCP with the security group as a source

To create a new group like the above, you can use the CLI:

```bash
exo compute security-group create sks-security-group
```

```bash
exo compute security-group rule add sks-security-group \
    --description "NodePort services" \
    --protocol tcp \
    --network 0.0.0.0/0 \
    --port 30000-32767
```

```bash
exo compute security-group rule add sks-security-group \
    --description "SKS kubelet" \
    --protocol tcp \
    --port 10250 \
    --security-group sks-security-group
```

Depending on which CNI plugin you want to use, you will also need to open additional ports.

If using **Calico as CNI plugin** (default), you need to open:

* 4789 UDP with the security group as a source for VXLAN communication between nodes

```bash
exo compute security-group rule add sks-security-group \
    --description "Calico traffic" \
    --protocol udp \
    --port 4789 \
    --security-group sks-security-group
```

Then you can initiate the cluster:

> [!NOTE]
> You will need to make use of your Deployment Target ID (--nodepool-deploy-target) to create the nodepool on your Dedicated Hypervisors
> In our example below, we have used Deployment Target ID c9a64f12-3ba7-4c19-bd93-61f2d84c3e55, which you must replace with your own.

```bash
exo compute sks create my-test-cluster \
    --zone ch-gva-2 \
    --service-level pro \
    --nodepool-name my-test-nodepool \
    --nodepool-size 3 \
    --nodepool-security-group sks-security-group
    --nodepool-deploy-target c9a64f12-3ba7-4c19-bd93-61f2d84c3e55
```

<details>

  <summary>Example output</summary>

  

  ```bash
  exo compute sks create my-test-cluster \
    --zone ch-gva-2 \
    --service-level pro \
    --nodepool-name my-test-nodepool \
    --nodepool-size 3 \
    --nodepool-security-group sks-security-group
 ✔ Creating SKS cluster "my-test-cluster"... 21s
 ✔ Adding Nodepool "my-test-nodepool"... 36s
┼───────────────────┼──────────────────────────────────────────────────────────┼
│    SKS CLUSTER    │                                                          │
┼───────────────────┼──────────────────────────────────────────────────────────┼
│ ID                │ 758c9820-d142-44df-a779-9e2c7e612423                     │
│ Name              │ my-test-cluster                                          │
│ Description       │                                                          │
│ Zone              │ ch-gva-2                                                 │
│ Creation Date     │ 2026-06-19 17:51:03 +0000 UTC                            │
│ Auto-upgrade      │ false                                                    │
│ Enable kube-proxy │ true                                                     │
│ Endpoint          │ 758c9820-d142-44df-a779-9e2c7e612423.sks-ch-gva-2.exo.io │
│ Version           │ 1.36.0                                                   │
│ Service Level     │ pro                                                      │
│ CNI               │ calico                                                   │
│ Add-Ons           │ exoscale-cloud-controller                                │
│                   │ metrics-server                                           │
│ Audit Enabled     │ false                                                    │
│ Feature Gates     │                                                          │
│ State             │ running                                                  │
│ Labels            │ n/a                                                      │
│ Nodepools         │ a3b84add-907a-4c20-8557-57644db1b8e0 | my-test-nodepool  │
┼───────────────────┼──────────────────────────────────────────────────────────┼

  ```

  </details>

If using **Cilium as CNI plugin**, you need to open:

* 8472 UDP with the security group as a source for VXLAN communication between nodes
* 4240 TCP with the security group as a source for network connectivity health API (health-checks)
* PING (ICMP type 8 & code 0) with the security group as a source for health checks

```bash
exo compute security-group rule add sks-security-group \
    --description "Cilium (healthcheck)" \
    --protocol icmp \
    --icmp-type 8 \
    --icmp-code 0 \
    --security-group sks-security-group
```

```bash
exo compute security-group rule add sks-security-group \
    --description "Cilium (vxlan)" \
    --protocol udp \
    --port 8472 \
    --security-group sks-security-group
```

```bash
exo compute security-group rule add sks-security-group \
    --description "Cilium (healthcheck)" \
    --protocol tcp \
    --port 4240 \
    --security-group sks-security-group
```

Then, you can initiate the cluster, specifying Cilium as CNI plugin using the `--cni` flag:

> [!NOTE]
> You will need to make use of your Deployment Target ID (--nodepool-deploy-target) to create the nodepool on your Dedicated Hypervisors
> In our example below, we have used Deployment Target ID c9a64f12-3ba7-4c19-bd93-61f2d84c3e55, which you must replace with your own.

```bash
exo compute sks create my-test-cluster-cilium \
    --zone ch-gva-2 \
    --cni cilium \
    --service-level pro \
    --nodepool-name my-test-nodepool \
    --nodepool-size 3 \
    --nodepool-security-group sks-security-group
    --nodepool-deploy-target c9a64f12-3ba7-4c19-bd93-61f2d84c3e55
```

<details>

  <summary>Example output</summary>

  

  ```bash
  exo compute sks create my-test-cluster-cilium \
    --zone ch-gva-2 \
    --service-level pro \
    --nodepool-name my-test-nodepool-cilium \
    --nodepool-size 3 \
    --nodepool-security-group sks-security-group
 ✔ Creating SKS cluster "my-test-cluster"... 21s
 ✔ Adding Nodepool "my-test-nodepool"... 36s
┼───────────────────┼──────────────────────────────────────────────────────────┼
│    SKS CLUSTER    │                                                          │
┼───────────────────┼──────────────────────────────────────────────────────────┼
│ ID                │ fb9e942f-2709-42ab-bb83-493a0cb757ae                     │
│ Name              │ my-test-cluster                                          │
│ Description       │                                                          │
│ Zone              │ ch-gva-2                                                 │
│ Creation Date     │ 2026-06-19 17:59:01 +0000 UTC                            │
│ Auto-upgrade      │ false                                                    │
│ Enable kube-proxy │ true                                                     │
│ Endpoint          │ fb9e942f-2709-42ab-bb83-493a0cb757ae.sks-ch-gva-2.exo.io │
│ Version           │ 1.36.0                                                   │
│ Service Level     │ pro                                                      │
│ CNI               │ calico                                                   │
│ Add-Ons           │ exoscale-cloud-controller                                │
│                   │ metrics-server                                           │
│ Audit Enabled     │ false                                                    │
│ Feature Gates     │                                                          │
│ State             │ running                                                  │
│ Labels            │ n/a                                                      │
│ Nodepools         │ e6fde5ab-26da-484b-835e-5f1e0cd90fa4 | my-test-nodepool2 │
┼───────────────────┼──────────────────────────────────────────────────────────┼

  ```

  </details>


This `exo compute sks create` command starts a fully dedicated Kubernetes cluster
in your organization in the **Geneva** zone with the service level
**pro** and with **3** nodes.


Run the following command to check the instances have landed on your dedicated hypervisors. 

```bash
exo api get-deploy-target c9a64f12-3ba7-4c19-bd93-61f2d84c3e55 --zone=ch-gva-2
```

> [!NOTE]
> The instances starting with pool- are the ones that are part of our NodePool, we can see they have been spread across both Hypervisors. 


<details>
<summary>Example output</summary>

```bash

exo api get-deploy-target c9a64f12-3ba7-4c19-bd93-61f2d84c3e55 --zone=ch-gva-2

{
  "allocation": [
    {
      "hypervisor": {
        "id": "b3c8f2a1-6d4e-419a-9e7b-c3f2b8a1d4e0",
        "name": "virt-hv416.gv2.p.exoscale.net"
      },
      "instances": [
        {
          "id": "d3a4b9e2-51c0-4f93-8a21-9e73b40cc36a",
          "name": "pool-78506-mwpf"
        },
        {
          "id": "3f92e591-209c-4dbd-ba0a-74d15682bc8a",
          "name": "pool-78506-tochd"
        },
        {
          "id": "c830db7f-5aef-4f11-942b-e01fa8c35921",
          "name": "prod-web-nyc-worker-005.internal.mock-corp.com"
        }
      ]
    },
    {
      "hypervisor": {
        "id": "f8e7d6c5-b4a3-4210-9f8e-7d6c5b4a3f2e",
        "name": "virt-hv731.gv2.p.exoscale.net"
      },
      "instances": [
        {
          "id": "50b601e3-ea11-4835-ad44-24f6a5bce904",
          "name": "pool-78506-nnxph"
        },
        {
          "id": "e29548a3-97df-4f06-bd51-7f394cceab1c",
          "name": "prod-web-nyc-worker-002.internal.mock-corp.com"
        }
      ]
    }
  ],
  "description": "dedicated resources group",
  "id": "c9a64f12-3ba7-4c19-bd93-61f2d84c3e55",
  "name": "Dedicated-ch-gva-2",
  "type": "dedicated"
}
```

</details>



## Managing Nodepools on existing SKS Clusters

You can create, delete, update, or scale SKS nodepools at any time.

The `--nodepool` options on `exo compute sks create` are optional. 

You also add nodepools to an existing cluster by using the `exo compute sks nodepool add` command, we will combine this with the Deployment Target to have this nodepool run on your Dedicated Hypervisor. 

### Confirm Deployment target

A [Deployment Target]({{< ref "/product/compute/dedicated-hypervisors/overview/#deployment-target" >}}) is a virtual abstraction layer that allows you to provision Compute Instances onto dedicated hypervisors.

Run the following command with valid credentials for the target account, be sure to use the correct [Zone]({{< ref "/platform/dc-zones/#building-around-the-zone-concept" >}}):

```bash
exo api list-deploy-targets  --zone=ch-gva-2 
```

  <details>

  <summary>Example output</summary>

  

  ```bash
  exo api list-deploy-targets  --zone=ch-gva-2 
  {
    "deploy-targets": [
    {
      "description": "dedicated resources group",
      "id": "c9a64f12-3ba7-4c19-bd93-61f2d84c3e55",
      "name": "Dedicated-ch-gva-coe",
      "type": "dedicated"
    }
  ]
  }

  ```

  </details>

> [!NOTE]
> Make note of the Deployment Target ID, you will need it to proceed! 


### Confirm target SKS Cluster ID

Run the following CLI Command and make note to the ID:

```bash
exo compute sks list

┼──────────────────────────────────────┼─────────────────┼──────────┼
│                  ID                  │      NAME       │   ZONE   │
┼──────────────────────────────────────┼─────────────────┼──────────┼
│ fb9e942f-2709-42ab-bb83-493a0cb757ae │ my-test-cluster │ ch-gva-2 │
┼──────────────────────────────────────┼─────────────────┼──────────┼
```

### Create a NodePool running on the Dedicated Hypervisors

Run the following CLI command, replacing sks-cluster-id and deploy-target with the IDs collected in the previous steps, nodepool-name should be replaced with a name of your choosing, the zone should be the zone there your deployment target is located.

exo compute sks nodepool add sks-cluster-id nodepool-name --deploy-target c9a64f12-3ba7-4c19-bd93-61f2d84c3e55 --zone ch-gva-2


```bash
exo compute sks nodepool add fb9e942f-2709-42ab-bb83-493a0cb757ae dedicated-nodepool --deploy-target c9a64f12-3ba7-4c19-bd93-61f2d84c3e55 --zone ch-gva-2
```

<details>

  <summary>Example output</summary>

  

  ```bash
  exo compute sks nodepool add fb9e942f-2709-42ab-bb83-493a0cb757ae dedicated-nodepool --deploy-target c9a64f12-3ba7-4c19-bd93-61f2d84c3e55 --zone ch-gva-2       
 ✔ Adding Nodepool "dedicated-nodepool"... 1m19s
┼─────────────────────────┼──────────────────────────────────────┼
│      SKS NODEPOOL       │                                      │
┼─────────────────────────┼──────────────────────────────────────┼
│ ID                      │ d2c2a882-ccf9-439c-a3ac-1fd399e119d3 │
│ Name                    │ dedicated-nodepool                   │
│ Description             │                                      │
│ Creation Date           │ 2026-06-19 18:20:56 +0000 UTC        │
│ Instance Pool ID        │ 1117b6ff-908b-475e-bc35-7b2e7d8b6f9a │
│ Instance Prefix         │ pool                                 │
│ Instance Type           │ standard.medium                      │
│ Template                │ sks-node-1.36.0-standard             │
│ Disk Size               │ 50                                   │
│ Public IP Assignment    │ inet4                                │
│ IPv6                    │ false                                │
│ Anti Affinity Groups    │ n/a                                  │
│ Security Groups         │ n/a                                  │
│ Private Networks        │ n/a                                  │
│ Version                 │ 1.36.0                               │
│ Size                    │ 2                                    │
│ State                   │ running                              │
│ Taints                  │ n/a                                  │
│ Labels                  │ n/a                                  │
│ Add Ons                 │ n/a                                  │
│ Image GC Min            │ 2m                                   │
│ Image Gc Low Threshold  │ 80                                   │
│ Image Gc High Threshold │ 85                                   │
┼─────────────────────────┼──────────────────────────────────────┼
  ```

  </details>

> [!NOTE]
> Each nodepool can have different characteristics - such as Security Groups, Private Networks, instance type, disk size, Anti-Affinity Groups and so on - depending on the applications you want to run on them and your requirements. 

### Check a NodePool running on Dedicated Hypervisors

Run the following command to check the instances have landed on your dedicated hypervisors. 

```bash
exo api get-deploy-target c9a64f12-3ba7-4c19-bd93-61f2d84c3e55 --zone=ch-gva-2
```
> [!NOTE]
> The instances starting with "pool-" are the ones that are part of our NodePool, we can see they have been spread across both Hypervisors.

<details>
<summary>Example output</summary>

```bash

exo api get-deploy-target c9a64f12-3ba7-4c19-bd93-61f2d84c3e55 --zone=ch-gva-2

{
  "allocation": [
    {
      "hypervisor": {
        "id": "b3c8f2a1-6d4e-419a-9e7b-c3f2b8a1d4e0",
        "name": "virt-hv416.gv2.p.exoscale.net"
      },
      "instances": [
        {
          "id": "5a1e2820-1922-49b4-8632-68936504726e",
          "name": "pool-78506-mwpfm"
        },
        {
          "id": "0a45a64d-d12f-4e1f-8248-abbecc1f5084",
          "name": "pool-1117b-hanhg"
        }
      ]
    },
    {
      "hypervisor": {
        "id": "f8e7d6c5-b4a3-4210-9f8e-7d6c5b4a3f2e",
        "name": "virt-hv731.gv2.p.exoscale.net"
      },
      "instances": [
        {
          "id": "948f9a30-3a76-459a-b73d-3dd228696ef7",
          "name": "pool-ec61e-lgtuu"
        }
      ]
    }
  ],
  "description": "dedicated resources group",
  "id": "c9a64f12-3ba7-4c19-bd93-61f2d84c3e55",
  "name": "Dedicated-ch-gva-2",
  "type": "dedicated"
}
```

</details>


## Next Steps 

Learn more about the Exoscale Dedicated Hypervisor architecture and concepts in the
[Overview]({{< ref "/product/compute/dedicated-hypervisors/overview" >}}). For advanced usage check the
[How-To]({{< ref "/product/compute/dedicated-hypervisors/how-to" >}}) section for other guides.
[Simple Kubernetes Service]({{< ref "/product/compute/containers/how-to" >}}) further Kubernetes guides.
