This guide covers machine-controller configuration for DigitalOcean.
cloudProviderSpec:
# API token
token: "<< YOUR_DO_TOKEN >>"
# Region
region: "fra1"
# Droplet size
size: "s-2vcpu-4gb"
# Backups
backups: false
# IPv6
ipv6: false
# Private networking
private_networking: true
# Monitoring
monitoring: true
# Tags
tags:
- "kubernetes"
- "worker"
Create a secret:
kubectl create secret generic do-credentials \
-n kube-system \
--from-literal=token=<YOUR_DO_TOKEN>
Reference in MachineDeployment:
cloudProviderSpec:
token:
secretKeyRef:
name: do-credentials
key: token
cloudProviderSpec:
# API token (required)
token: "<< YOUR_DO_TOKEN >>"
# Can also be set via DO_TOKEN env var
# Region (required)
region: "fra1"
# Available: nyc1, nyc3, sfo3, sgp1, lon1, fra1, tor1, blr1, etc.
# Droplet size (required)
size: "s-2vcpu-4gb"
# Enable backups (default: false)
backups: false
# Enable IPv6 (default: false)
ipv6: false
# Enable private networking (default: true)
private_networking: true
# Enable monitoring agent (default: true)
monitoring: true
# VPC UUID (optional)
vpc_uuid: ""
# Tags (for organization)
tags:
- "kubernetes"
- "worker"
- "production"
# User data (optional, for additional customization)
# user_data: ""
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: do-ubuntu-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
name: do-ubuntu-workers
template:
metadata:
labels:
name: do-ubuntu-workers
spec:
providerSpec:
value:
cloudProvider: "digitalocean"
cloudProviderSpec:
region: "fra1"
size: "s-2vcpu-4gb"
backups: false
ipv6: false
private_networking: true
monitoring: true
token:
secretKeyRef:
name: do-credentials
key: token
tags:
- "kubernetes"
- "worker"
operatingSystem: "ubuntu"
operatingSystemSpec:
distUpgradeOnBoot: false
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: do-highmem-workers
namespace: kube-system
spec:
replicas: 2
selector:
matchLabels:
name: do-highmem-workers
template:
metadata:
labels:
name: do-highmem-workers
spec:
providerSpec:
value:
cloudProvider: "digitalocean"
cloudProviderSpec:
region: "fra1"
size: "s-4vcpu-8gb"
backups: false
private_networking: true
monitoring: true
token:
secretKeyRef:
name: do-credentials
key: token
tags:
- "kubernetes"
- "worker"
- "high-memory"
operatingSystem: "ubuntu"
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: do-backup-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
name: do-backup-workers
template:
metadata:
labels:
name: do-backup-workers
spec:
providerSpec:
value:
cloudProvider: "digitalocean"
cloudProviderSpec:
region: "fra1"
size: "s-2vcpu-4gb"
backups: true # Weekly backups
private_networking: true
monitoring: true
token:
secretKeyRef:
name: do-credentials
key: token
tags:
- "kubernetes"
- "worker"
operatingSystem: "ubuntu"
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: do-rocky-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
name: do-rocky-workers
template:
metadata:
labels:
name: do-rocky-workers
spec:
providerSpec:
value:
cloudProvider: "digitalocean"
cloudProviderSpec:
region: "fra1"
size: "s-2vcpu-4gb"
private_networking: true
monitoring: true
token:
secretKeyRef:
name: do-credentials
key: token
tags:
- "kubernetes"
- "worker"
operatingSystem: "rockylinux"
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
| Size | vCPUs | RAM | Disk | Transfer | Price/mo* |
|---|---|---|---|---|---|
| s-1vcpu-1gb | 1 | 1 GB | 25 GB | 1 TB | $6 |
| s-1vcpu-2gb | 1 | 2 GB | 50 GB | 2 TB | $12 |
| s-2vcpu-2gb | 2 | 2 GB | 60 GB | 3 TB | $18 |
| s-2vcpu-4gb | 2 | 4 GB | 80 GB | 4 TB | $24 |
| s-4vcpu-8gb | 4 | 8 GB | 160 GB | 5 TB | $48 |
| s-8vcpu-16gb | 8 | 16 GB | 320 GB | 6 TB | $96 |
| Size | vCPUs | RAM | Disk | Transfer | Price/mo* |
|---|---|---|---|---|---|
| c-2 | 2 | 4 GB | 25 GB | 4 TB | $42 |
| c-4 | 4 | 8 GB | 50 GB | 5 TB | $84 |
| c-8 | 8 | 16 GB | 100 GB | 6 TB | $168 |
| Size | vCPUs | RAM | Disk | Transfer | Price/mo* |
|---|---|---|---|---|---|
| m-2vcpu-16gb | 2 | 16 GB | 40 GB | 4 TB | $90 |
| m-4vcpu-32gb | 4 | 32 GB | 80 GB | 5 TB | $180 |
| m-8vcpu-64gb | 8 | 64 GB | 160 GB | 6 TB | $360 |
*Prices are approximate and subject to change.
List available sizes:
# Using doctl CLI
doctl compute size list
Available regions:
List regions:
doctl compute region list
# Create VPC
doctl vpcs create \
--name k8s-vpc \
--region fra1 \
--ip-range 10.10.0.0/16
cloudProviderSpec:
vpc_uuid: "uuid-from-vpc-creation"
private_networking: true
cloudProviderSpec:
monitoring: true
This installs the DigitalOcean monitoring agent for:
cloudProviderSpec:
backups: true
Weekly automatic backups:
# Create firewall
doctl compute firewall create \
--name worker-firewall \
--inbound-rules "protocol:tcp,ports:22,sources:addresses:0.0.0.0/0" \
--inbound-rules "protocol:tcp,ports:10250,sources:addresses:CONTROL_PLANE_IP" \
--outbound-rules "protocol:tcp,ports:all,destinations:addresses:0.0.0.0/0"
Apply to droplets using tags:
cloudProviderSpec:
tags:
- "worker" # Firewall rule targets this tag
For LoadBalancer services, add annotation:
apiVersion: v1
kind: Service
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/do-loadbalancer-name: "my-lb"
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: my-app
Deploy across multiple regions:
---
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: workers-fra1
namespace: kube-system
spec:
replicas: 2
template:
spec:
providerSpec:
value:
cloudProviderSpec:
region: "fra1"
---
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: workers-ams3
namespace: kube-system
spec:
replicas: 2
template:
spec:
providerSpec:
value:
cloudProviderSpec:
region: "ams3"
# Check machine events
kubectl describe machine <machine-name> -n kube-system
# Common issues:
# - Invalid API token
# - Droplet limit reached
# - Size not available in region
# - Rate limit exceeded
# Using doctl CLI
doctl compute droplet list
# Check specific droplet
doctl compute droplet get <droplet-id>
# View actions/events
doctl compute droplet-action list <droplet-id>
DigitalOcean has API rate limits (5000 requests/hour). If hitting limits:
Install and configure:
# Install
brew install doctl # macOS
# or download from https://github.com/digitalocean/doctl/releases
# Authenticate
doctl auth init
# List resources
doctl compute droplet list
doctl compute size list
doctl compute region list
doctl compute image list --public