Provision Dedicated SKS Nodepools
In this guide, we will make use of your Dedicated Hypervisors to run Nodepools for an Exoscale Scalable Kubernetes Service (SKS) 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
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
- A 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 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:
exo api list-deploy-targets --zone=ch-gva-2 Example output
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"
}
]
}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
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:
exo compute security-group create sks-security-groupexo compute security-group rule add sks-security-group \
--description "NodePort services" \
--protocol tcp \
--network 0.0.0.0/0 \
--port 30000-32767exo compute security-group rule add sks-security-group \
--description "SKS kubelet" \
--protocol tcp \
--port 10250 \
--security-group sks-security-groupDepending 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
exo compute security-group rule add sks-security-group \
--description "Calico traffic" \
--protocol udp \
--port 4789 \
--security-group sks-security-groupThen 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.
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-61f2d84c3e55Example output
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 │
┼───────────────────┼──────────────────────────────────────────────────────────┼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
exo compute security-group rule add sks-security-group \
--description "Cilium (healthcheck)" \
--protocol icmp \
--icmp-type 8 \
--icmp-code 0 \
--security-group sks-security-groupexo compute security-group rule add sks-security-group \
--description "Cilium (vxlan)" \
--protocol udp \
--port 8472 \
--security-group sks-security-groupexo compute security-group rule add sks-security-group \
--description "Cilium (healthcheck)" \
--protocol tcp \
--port 4240 \
--security-group sks-security-groupThen, 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.
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-61f2d84c3e55Example output
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 │
┼───────────────────┼──────────────────────────────────────────────────────────┼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.
exo api get-deploy-target c9a64f12-3ba7-4c19-bd93-61f2d84c3e55 --zone=ch-gva-2Note
The instances starting with pool- are the ones that are part of our NodePool, we can see they have been spread across both Hypervisors.
Example output
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"
}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 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:
exo api list-deploy-targets --zone=ch-gva-2 Example output
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"
}
]
}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:
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
exo compute sks nodepool add fb9e942f-2709-42ab-bb83-493a0cb757ae dedicated-nodepool --deploy-target c9a64f12-3ba7-4c19-bd93-61f2d84c3e55 --zone ch-gva-2Example output
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 │
┼─────────────────────────┼──────────────────────────────────────┼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.
exo api get-deploy-target c9a64f12-3ba7-4c19-bd93-61f2d84c3e55 --zone=ch-gva-2Note
The instances starting with “pool-” are the ones that are part of our NodePool, we can see they have been spread across both Hypervisors.
Example output
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"
}Next Steps
Learn more about the Exoscale Dedicated Hypervisor architecture and concepts in the Overview. For advanced usage check the How-To section for other guides. Simple Kubernetes Service further Kubernetes guides.