AWS EKS
A from-scratch tutorial for building an Amazon EKS Kubernetes cluster that's ready to run Supervisely. It covers creating the cluster, storage, ingress, and (optionally) GPU nodes. When the cluster is ready, you deploy Supervisely on it with the Helm chart — either the full platform or the Kubernetes agent.
If you already have a Kubernetes cluster, you can skip this page and go straight to those install guides.
The example uses this configuration:
AWS region:
us-east-1Cluster name:
supervisely-eksKubernetes version:
1.35One managed node group with
t3.largePublic worker nodes
NAT gateway disabled to reduce baseline cost
This is fine for testing and initial integration. For production, review node sizing, scaling, private networking, DNS, TLS, monitoring, and security.
What you'll build: install CLI tools → create an EKS cluster → add a storage class → install an ingress controller → (optionally) add GPU nodes → deploy Supervisely.
Prerequisites
An AWS account allowed to launch EC2 instances
AWS permissions for EKS, IAM, CloudFormation, EC2, VPC, Auto Scaling, and public SSM parameters
aws,kubectl,eksctl, andhelm(v3) installed locallyAWS credentials configured in your shell
Step 1. Verify required tools
If any command is missing, install the tool before proceeding.
Step 2. Configure AWS access
Configure AWS credentials using either an AWS profile or environment variables.
Example using environment variables in bash:
Verify access:
The command must return the active AWS identity.
Important: successful AWS authentication is not enough on its own. The AWS account must also be allowed to launch EC2 instances, otherwise EKS worker nodes will not start.
Step 3. Create the EKS cluster
Save the following as eksctl-supervisely-cluster.yaml. It creates the cluster, a node group, and the EBS CSI driver add-on (needed for persistent storage in Step 5):
Create the cluster:
Expected duration: 15 to 30 minutes.
This creates the EKS control plane, VPC networking, the IAM resources EKS needs, one managed node group, the EBS CSI driver add-on, and a local kubeconfig entry.
Step 4. Verify cluster access
Expected result:
At least one node is in
ReadystateThe API server responds to
kubectl
Immediately after control plane creation, kubectl get nodes may temporarily return No resources found while the node group is still provisioning. Wait a few minutes and retry.
Step 5. Set up a storage class
Supervisely stores data on persistent volumes, so the cluster needs a storage class that provisions them. Recent EKS versions (1.30+) don't mark any storage class as default and don't provision volumes until the EBS CSI driver is present — that's why Step 3 added the driver add-on. Here you create a gp3 class, make it the default, and use Retain so volumes aren't deleted by accident.
Save this as gp3-storageclass.yaml:
Apply it:
gp3 should be marked (default).
Step 6. Install an ingress controller
An ingress controller exposes Supervisely (and browser-based apps) outside the cluster. The Supervisely chart defaults to Traefik, so this example installs Traefik, which provisions an AWS load balancer on EKS:
Find the external address of the load balancer (you'll point your domain at it later):
GPU nodes (optional)
Most people add a Kubernetes cluster so Supervisely can run GPU tasks. To do that, create the cluster in Step 3 with a GPU node group instead of t3.large — use this managedNodeGroups block (for example, a g4dn.xlarge instance):
This uses the EKS Bottlerocket accelerated AMI (amiFamily: Bottlerocket), which ships the NVIDIA driver and device plugin pre-installed — so GPUs are exposed to Kubernetes as the nvidia.com/gpu resource with zero extra setup. (If you'd rather use the Amazon Linux 2023 GPU AMI, eksctl installs the NVIDIA device plugin for you automatically — same result.)
Once the GPU nodes are up, confirm they report GPUs:
Each GPU node should show its GPU count. Then enable GPU pod presets in the Supervisely values file — see Install full Supervisely or Install the Kubernetes agent.
If you don't need GPU, skip this section and keep the t3.large node group.
Step 7. Deploy Supervisely
The cluster is ready. Now install Supervisely on it with the Helm chart. Pick the mode that fits your case:
Run the whole platform on this cluster → Install full Supervisely. Use the ingress host from Step 6 and the
gp3storage class from Step 5.Connect this cluster as extra compute for an existing instance → Install the Kubernetes agent.
Both start by fetching the chart with supervisely k8s fetch-chart and installing it with supervisely k8s install.
Cleanup
Delete the cluster when it is no longer needed:
The example creates billable AWS resources. Remove the cluster after testing to avoid unnecessary charges. Note: with the Retain reclaim policy, EBS volumes created for Supervisely are not deleted automatically — remove any leftover volumes in the EC2 console if you no longer need the data.
Troubleshooting
aws sts get-caller-identity fails
The AWS credentials are missing or invalid. Reconfigure AWS access and retry.
RunInstances returns Blocked
An AWS account-level restriction. The IAM user may be valid, but the account is not currently allowed to launch EC2 instances. Resolve it with the AWS account owner or AWS Support before retrying.
Managed node group stays in CREATING
If the control plane is healthy but worker nodes do not appear, inspect the EKS node group status, Auto Scaling activities, and CloudFormation events for the node group stack. Common causes: EC2 quota limits, blocked EC2 launches, or account verification restrictions.
kubectl get nodes returns No resources found
The control plane may be ready while the node group is still provisioning. Wait a few minutes and retry.
kubectl get nodes fails after cluster creation
Refresh the kubeconfig entry and retry:
PersistentVolumeClaims stay Pending
Usually the storage class or the EBS CSI driver isn't ready. Confirm the gp3 class exists and is default (Step 5), and that the driver is running: kubectl -n kube-system get pods | grep ebs-csi.
The load balancer has no external address
On EKS the ingress controller's load balancer can take a couple of minutes to get an address. Re-run kubectl -n traefik get service traefik. If it never appears, check the controller pod logs and your subnet/role configuration.
GPU nodes don't report GPUs
Confirm you used a GPU instance type and a GPU-capable AMI. With Bottlerocket the driver and plugin run on the node itself. With the AL2023 GPU AMI, eksctl installs the device plugin — check its pods with kubectl get pods -A | grep nvidia-device-plugin.
Last updated
Was this helpful?