Skip to main content
Ankra supports provisioning fully managed Kubernetes clusters on DigitalOcean. You can create clusters with configurable control planes, workers, and networking then scale workers up or down as needed.

Prerequisites

Before creating a DigitalOcean cluster, you need two credentials:

DigitalOcean API Credential

A DigitalOcean personal access token with read/write permissions. See DigitalOcean Credentials.

SSH Key Credential

An SSH public key for server access. You can provide your own or let Ankra generate one. See SSH Key Credentials.

Creating a DigitalOcean Cluster

Via the Platform UI

1

Navigate to Clusters

Go to Clusters in the Ankra dashboard and click Create Cluster.
2

Select DigitalOcean

Choose DigitalOcean as the provider.
3

Select Credentials

Pick your DigitalOcean API credential and SSH key credential from the dropdowns. You can also create new credentials directly from the wizard.
4

Choose Region

Select a DigitalOcean region (e.g., nyc3, fra1, lon1). Each region shows the location and country.
5

Configure Nodes

Set your cluster topology:
  • Bastion - Droplet size for the SSH bastion host (e.g., s-1vcpu-1gb)
  • Control Plane - Count (1 or 3) and size (e.g., s-2vcpu-4gb)
  • Workers - Count and size (e.g., 2× s-2vcpu-4gb)
The wizard shows vCPUs, RAM, and monthly cost for each size to help you choose.
6

Choose Distribution

Pick the Kubernetes distribution: k3s Lightweight Kubernetes with a user-selectable CNI (default). kubeadm Vanilla upstream Kubernetes bootstrapped with kubeadm and containerd. kubeadm clusters always use Cilium CNI and optionally support an external etcd topology with dedicated etcd droplets.See Kubernetes Distribution for details.
7

Create & Track Progress

Click Create to start provisioning. A live progress view tracks credential setup, VPC creation, SSH key deployment, bastion provisioning, droplet creation, Kubernetes installation (k3s or kubeadm), and Ankra Agent setup. The cluster appears with an offline state until provisioning completes, then transitions to online.

Via the CLI

# Create credentials first
ankra credentials digitalocean create --name my-do-token  # securely prompts for token
ankra credentials digitalocean ssh-key create --name my-ssh-key --generate

# List regions and sizes for your credential
ankra cluster digitalocean regions --credential-id <digitalocean-credential-id>
ankra cluster digitalocean sizes --credential-id <digitalocean-credential-id> --region nyc3 --available-only

# Create the cluster
ankra cluster digitalocean create \
  --name my-cluster \
  --credential-id <digitalocean-credential-id> \
  --ssh-key-credential-id <ssh-key-credential-id> \
  --region nyc3 \
  --control-plane-count 1 \
  --control-plane-size s-2vcpu-4gb \
  --worker-count 2 \
  --worker-size s-2vcpu-4gb

Via the API

curl -X POST https://platform.ankra.app/api/v1/clusters/digitalocean \
  -H "Authorization: Bearer $ANKRA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-cluster",
    "credential_id": "<digitalocean-credential-id>",
    "ssh_key_credential_id": "<ssh-key-credential-id>",
    "region": "nyc3",
    "control_plane_count": 1,
    "control_plane_size": "s-2vcpu-4gb",
    "node_groups": [
      {"name": "default", "instance_type": "s-2vcpu-4gb", "count": 2}
    ],
    "distribution": "k3s"
  }'

Cluster Configuration Options

ParameterDefaultDescription
namerequiredUnique cluster name
credential_idrequiredDigitalOcean API credential ID
ssh_key_credential_idrequiredSSH key credential ID
regionrequiredDigitalOcean region slug
network_ip_range10.0.0.0/16Private VPC IP range
bastion_sizes-1vcpu-1gbDroplet size for the bastion host
control_plane_count1Number of control plane nodes (1 or 3)
control_plane_sizes-2vcpu-4gbDroplet size for control planes
worker_count1Number of worker nodes (legacy, use node_groups instead)
worker_sizes-2vcpu-4gbDroplet size for workers (legacy, use node_groups instead)
node_groupsArray of node group definitions (see Node Groups)
distributionk3sKubernetes distribution (k3s or kubeadm)
kubernetes_versionlatest stableKubernetes version (optional)
cniflannel (k3s)CNI plugin. kubeadm clusters always use cilium
cni_featuresall offAdvanced CNI feature toggles, fixed at creation. Cilium: kube_proxy_replacement, hubble, wireguard_encryption. Calico: ebpf_dataplane. See Advanced CNI features
etcd_topologystackedkubeadm only. stacked (etcd on control planes) or external (dedicated etcd droplets)
etcd_node_count3kubeadm external topology only. Number of dedicated etcd droplets (3 or 5)
etcd_sizes-2vcpu-4gbkubeadm external topology only. Droplet size for dedicated etcd nodes
include_ingressfalseDeploy Traefik + cert-manager for ingress

DigitalOcean Regions

RegionLocation
nyc3New York 3, United States
sfo3San Francisco 3, United States
ams3Amsterdam 3, Netherlands
sgp1Singapore 1, Singapore
lon1London 1, United Kingdom
fra1Frankfurt 1, Germany
Available regions and sizes depend on your account. Use ankra cluster digitalocean regions and ankra cluster digitalocean sizes to list what your credential can deploy.

Common Droplet Sizes

SizevCPUsRAMTypical use
s-1vcpu-1gb11 GBBastion
s-1vcpu-2gb12 GBSmall workers
s-2vcpu-4gb24 GBControl plane, general workers
s-4vcpu-8gb48 GBLarger workloads

Kubernetes Distribution

DigitalOcean clusters can be provisioned with either k3s (default) or kubeadm.
k3skubeadm
KubernetesLightweight, single-binary distributionVanilla upstream Kubernetes
CNIUser-selectable (Flannel default)Cilium (fixed, cannot be changed after creation)
etcdEmbeddedstacked (on control planes) or external (dedicated droplets)
Version formatv1.35.1+k3s1v1.31.0 (plain upstream tag)
kubeadm clusters always use Cilium CNI (eBPF-based networking, L7 policies, Hubble observability). The CNI cannot be changed after creation.

Advanced CNI features

k3s clusters can enable advanced CNI features at creation time via cni_features (also available as toggles in the create wizard). Features are fixed once the cluster is created.
FeatureCNIWhat it does
kube_proxy_replacementCiliumReplaces kube-proxy with Cilium’s eBPF dataplane
hubbleCiliumDeploys Hubble relay and UI for network flow observability
wireguard_encryptionCiliumEncrypts pod-to-pod traffic between nodes with WireGuard (UDP/51871 must be open node-to-node)
ebpf_dataplaneCalicoRuns Calico in eBPF mode, bypassing kube-proxy
kube_proxy_replacement and ebpf_dataplane pin the CNI’s API-server endpoint to the first control plane, so on k3s they require a single control plane. Creation and control-plane scaling both enforce this. Flannel accepts no feature toggles.

External etcd topology (kubeadm)

By default kubeadm runs etcd stacked on the control plane nodes. For larger clusters you can run etcd on dedicated droplets by setting etcd_topology to external:
curl -X POST https://platform.ankra.app/api/v1/clusters/digitalocean \
  -H "Authorization: Bearer $ANKRA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-cluster",
    "credential_id": "<digitalocean-credential-id>",
    "ssh_key_credential_id": "<ssh-key-credential-id>",
    "region": "nyc3",
    "control_plane_count": 3,
    "control_plane_size": "s-2vcpu-4gb",
    "node_groups": [
      {"name": "default", "instance_type": "s-2vcpu-4gb", "count": 2}
    ],
    "distribution": "kubeadm",
    "etcd_topology": "external",
    "etcd_node_count": 3,
    "etcd_size": "s-2vcpu-4gb"
  }'
The equivalent CLI flags are --distribution kubeadm, --etcd-topology external, --etcd-node-count 3, and --etcd-size s-2vcpu-4gb.

Node Groups

Node groups let you organize worker nodes into logical groups with independent droplet sizes, counts, labels, and taints. Manage node groups from Settings > Nodes in the dashboard, or via the API.

Node Group API Reference

EndpointMethodDescription
/api/v1/clusters/digitalocean/{id}/node-groupsGETList all node groups
/api/v1/clusters/digitalocean/{id}/node-groupsPOSTAdd a node group
/api/v1/clusters/digitalocean/{id}/node-groups/{name}/scalePUTScale a node group (0-100)
/api/v1/clusters/digitalocean/{id}/node-groups/{name}/instance-typePUTChange droplet size
/api/v1/clusters/digitalocean/{id}/node-groups/{name}/labelsPUTUpdate labels
/api/v1/clusters/digitalocean/{id}/node-groups/{name}/taintsPUTUpdate taints
/api/v1/clusters/digitalocean/{id}/node-groups/{name}DELETEDelete a node group
For detailed usage examples, see Hetzner Node Groups - the API is identical across all providers.

Legacy Worker Scaling

The legacy scale-workers and worker-count endpoints still work for backward compatibility.
ankra cluster digitalocean workers <cluster_id>
ankra cluster digitalocean scale <cluster_id> 4
curl https://platform.ankra.app/api/v1/clusters/digitalocean/<cluster_id>/worker-count \
  -H "Authorization: Bearer $ANKRA_API_TOKEN"

curl -X POST https://platform.ankra.app/api/v1/clusters/digitalocean/<cluster_id>/scale-workers \
  -H "Authorization: Bearer $ANKRA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"worker_count": 4}'
For new clusters, prefer using Node Groups for more granular control.

Upgrading Kubernetes Version

You can upgrade the Kubernetes version on all nodes in a DigitalOcean cluster. Upgrades are applied to control plane nodes first, then workers. Both k3s and kubeadm clusters are supported.
  • Both k3s and kubeadm clusters are supported for version upgrades, including kubeadm clusters with an external etcd topology: the dedicated etcd members are upgraded first, one at a time, each saving a pre-upgrade snapshot before its static pod rolls to the etcd image matching the target Kubernetes version.
  • Use the matching version format for the target: v1.35.1+k3s1 for k3s, or a plain v1.31.0 upstream tag for kubeadm.
  • Downgrades are not supported - downgrades require an etcd snapshot restore.
  • You can only upgrade one minor version at a time (e.g., v1.33.x to v1.34.x, not v1.33.x to v1.35.x).
  • The cluster must be online with no active operations.

Check Current Version

ankra cluster digitalocean k8s-version <cluster_id>
curl https://platform.ankra.app/api/v1/clusters/digitalocean/<cluster_id>/k8s-version \
  -H "Authorization: Bearer $ANKRA_API_TOKEN"

Upgrade Version

ankra cluster digitalocean upgrade <cluster_id> v1.35.1+k3s1
curl -X POST https://platform.ankra.app/api/v1/clusters/digitalocean/<cluster_id>/upgrade-k8s-version \
  -H "Authorization: Bearer $ANKRA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"target_version": "v1.35.1+k3s1"}'
For a kubeadm cluster, use a plain upstream tag instead:
ankra cluster digitalocean upgrade <cluster_id> v1.31.0

Deprovisioning

Deprovisioning deletes all DigitalOcean resources (droplets, VPC, SSH keys) and removes the cluster from Ankra.
This action is irreversible. All data on the cluster will be permanently deleted.
Clean up DigitalOcean resources before terminating. The DigitalOcean CCM and CSI driver create Load Balancers and Volumes in your account that Ankra does not track. Delete Kubernetes LoadBalancer services and PVCs using the do-block-storage StorageClass before deprovisioning, or remove orphaned resources in the DigitalOcean Control Panel.
ankra cluster digitalocean deprovision <cluster_id>
curl -X DELETE https://platform.ankra.app/api/v1/clusters/digitalocean/<cluster_id> \
  -H "Authorization: Bearer $ANKRA_API_TOKEN"

Architecture

A DigitalOcean cluster provisions the following infrastructure:
ComponentDescription
VPCPrivate network for inter-node communication
Bastion HostJump server for secure SSH access to cluster nodes
Control Plane(s)Kubernetes control plane droplets
Worker(s)Kubernetes worker droplets organized in node groups
etcd Node(s)Dedicated etcd droplets, only for kubeadm clusters with an external etcd topology
SSH KeysDeployed to all droplets for access
Cloud Provider StackDigitalOcean CCM and CSI for LoadBalancers and block storage
All nodes are deployed within a private VPC. The bastion host provides the only external SSH access point. Ankra automatically deploys a digitalocean-cloud-provider stack after the Ankra Agent is installed, including the DigitalOcean Cloud Controller Manager and CSI driver backed by your API credential.

Provider-native Managed Kubernetes (DOKS & UKS)

In addition to self-managed k3s or kubeadm on droplets, Ankra can provision and import provider-native managed Kubernetes services:
Provider kindServiceCredential
doksDigitalOcean Kubernetes (DOKS)DigitalOcean API token
uksUpCloud Managed Kubernetes (UKS)UpCloud API token
See Managed Kubernetes for the full guide covering live options and pricing, preflight checks, discovery and import, node pool autoscaling, and upgrades - across DOKS, UKS, GKE, OVHcloud MKS, AKS, and EKS. Create a managed cluster from the platform UI or via the API:
# DigitalOcean Kubernetes (DOKS)
curl -X POST https://platform.ankra.app/org/clusters/managed/doks \
  -H "Authorization: Bearer $ANKRA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-doks-cluster",
    "credential_id": "<digitalocean-credential-id>",
    "location": "nyc3",
    "node_pools": [
      {"name": "default", "size": "s-2vcpu-4gb", "count": 2}
    ]
  }'

# UpCloud Managed Kubernetes (UKS)
curl -X POST https://platform.ankra.app/org/clusters/managed/uks \
  -H "Authorization: Bearer $ANKRA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-uks-cluster",
    "credential_id": "<upcloud-credential-id>",
    "location": "fi-hel1",
    "node_pools": [
      {"name": "default", "size": "2xCPU-4GB", "count": 2}
    ]
  }'
Ankra provisions the cluster with the provider, stores kubeconfig securely, and installs the Ankra Agent so you can manage stacks and GitOps the same way as imported clusters.

Troubleshooting

Common Issues

IssueSolution
Cluster stuck in provisioningCheck API token permissions and account quota
Cannot scale workersEnsure cluster is online and no operations are running
Invalid API tokenRe-validate at DigitalOcean Control Panel - tokens are prefixed with dop_v1_
Droplet size unavailableTry a different region or size
LoadBalancer service stuck in PendingVerify the CCM is running in the digitalocean-cloud-provider namespace
PVCs stuck in PendingVerify the CSI driver is running and the do-block-storage StorageClass exists

DigitalOcean Account Quotas

DigitalOcean has default resource limits per account. If provisioning fails, check your quotas in the DigitalOcean Control Panel:
  • Droplets
  • VPCs
  • Load Balancers
  • Volumes
Contact DigitalOcean support to increase limits if needed.