This guide covers machine-controller configuration for Hetzner Cloud.
cloudProviderSpec:
# API token
token: "<< HETZNER_API_TOKEN >>"
# Server type
serverType: "cx21"
# Location
location: "fsn1"
# Labels
labels:
kubernetesCluster: "my-cluster"
Create a secret:
kubectl create secret generic hcloud-credentials \
-n kube-system \
--from-literal=token=<YOUR_HETZNER_API_TOKEN>
Reference in MachineDeployment:
cloudProviderSpec:
token:
secretKeyRef:
name: hcloud-credentials
key: token
cloudProviderSpec:
# API token (required)
token: "<< HETZNER_API_TOKEN >>"
# Can also be set via HCLOUD_TOKEN env var
# Server type (required)
serverType: "cx21"
# Location (optional, use location OR datacenter)
location: "fsn1" # fsn1, nbg1, hel1, ash, hil
# Datacenter (optional, use location OR datacenter)
# datacenter: "fsn1-dc14"
# Image (optional, auto-selected based on OS)
# image: "ubuntu-24.04"
# Networks (optional)
networks:
- "my-private-network"
# Can use network name or ID
# Firewalls (optional)
firewalls:
- "worker-firewall"
# Placement group (optional, for spreading)
placementGroup: "workers-pg"
# Labels (for organization)
labels:
kubernetesCluster: "my-cluster"
environment: "production"
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: hcloud-ubuntu-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
name: hcloud-ubuntu-workers
template:
metadata:
labels:
name: hcloud-ubuntu-workers
spec:
providerSpec:
value:
cloudProvider: "hetzner"
cloudProviderSpec:
serverType: "cx21"
location: "fsn1"
token:
secretKeyRef:
name: hcloud-credentials
key: token
labels:
kubernetesCluster: "my-cluster"
operatingSystem: "ubuntu"
operatingSystemSpec:
distUpgradeOnBoot: false
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: hcloud-private-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
name: hcloud-private-workers
template:
metadata:
labels:
name: hcloud-private-workers
spec:
providerSpec:
value:
cloudProvider: "hetzner"
cloudProviderSpec:
serverType: "cx21"
location: "fsn1"
networks:
- "k8s-private-network"
token:
secretKeyRef:
name: hcloud-credentials
key: token
labels:
kubernetesCluster: "my-cluster"
operatingSystem: "ubuntu"
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: hcloud-performance-workers
namespace: kube-system
spec:
replicas: 2
selector:
matchLabels:
name: hcloud-performance-workers
template:
metadata:
labels:
name: hcloud-performance-workers
spec:
providerSpec:
value:
cloudProvider: "hetzner"
cloudProviderSpec:
serverType: "cpx51" # 16 vCPU, 32 GB RAM
location: "fsn1"
token:
secretKeyRef:
name: hcloud-credentials
key: token
labels:
kubernetesCluster: "my-cluster"
workload: "compute-intensive"
operatingSystem: "ubuntu"
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: hcloud-rocky-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
name: hcloud-rocky-workers
template:
metadata:
labels:
name: hcloud-rocky-workers
spec:
providerSpec:
value:
cloudProvider: "hetzner"
cloudProviderSpec:
serverType: "cx21"
location: "nbg1"
token:
secretKeyRef:
name: hcloud-credentials
key: token
labels:
kubernetesCluster: "my-cluster"
operatingSystem: "rockylinux"
versions:
kubelet: "<YOUR-KUBERNETES-VERSION>"
| Type | vCPUs | RAM | Disk | Network | Price/mo* |
|---|---|---|---|---|---|
| cx11 | 1 | 2 GB | 20 GB | 20 TB | ~€4 |
| cx21 | 2 | 4 GB | 40 GB | 20 TB | ~€6 |
| cx31 | 2 | 8 GB | 80 GB | 20 TB | ~€11 |
| cx41 | 4 | 16 GB | 160 GB | 20 TB | ~€18 |
| cx51 | 8 | 32 GB | 240 GB | 20 TB | ~€33 |
| Type | vCPUs | RAM | Disk | Network | Price/mo* |
|---|---|---|---|---|---|
| cpx11 | 2 | 2 GB | 40 GB | 20 TB | ~€5 |
| cpx21 | 3 | 4 GB | 80 GB | 20 TB | ~€9 |
| cpx31 | 4 | 8 GB | 160 GB | 20 TB | ~€16 |
| cpx41 | 8 | 16 GB | 240 GB | 20 TB | ~€29 |
| cpx51 | 16 | 32 GB | 360 GB | 20 TB | ~€53 |
*Prices are approximate and subject to change.
List available server types:
# Using hcloud CLI
hcloud server-type list
Available locations:
List locations:
hcloud location list
# Create network
hcloud network create \
--name k8s-private-network \
--ip-range 10.0.0.0/16
# Create subnet
hcloud network add-subnet k8s-private-network \
--type cloud \
--network-zone eu-central \
--ip-range 10.0.1.0/24
cloudProviderSpec:
networks:
- "k8s-private-network"
Servers with private networks still get a public IPv4/IPv6 address for outbound connectivity.
# Create firewall
hcloud firewall create --name worker-firewall
# Add rules
hcloud firewall add-rule worker-firewall \
--direction in \
--protocol tcp \
--port 22 \
--source-ips 0.0.0.0/0 \
--source-ips ::/0
hcloud firewall add-rule worker-firewall \
--direction in \
--protocol tcp \
--port 10250 \
--source-ips CONTROL_PLANE_IP/32
cloudProviderSpec:
firewalls:
- "worker-firewall"
Placement groups spread servers across different hosts for high availability:
# Create placement group
hcloud placement-group create \
--name workers-pg \
--type spread
Use in MachineDeployment:
cloudProviderSpec:
placementGroup: "workers-pg"
Deploy across multiple locations for geo-distribution:
---
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: workers-fsn1
namespace: kube-system
spec:
replicas: 2
template:
spec:
providerSpec:
value:
cloudProviderSpec:
location: "fsn1"
---
apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
name: workers-nbg1
namespace: kube-system
spec:
replicas: 2
template:
spec:
providerSpec:
value:
cloudProviderSpec:
location: "nbg1"
# Check machine events
kubectl describe machine <machine-name> -n kube-system
# Common issues:
# - Invalid API token
# - Server type not available in location
# - Rate limit exceeded
# - Quota/limit reached
# Using hcloud CLI
hcloud server list
# Check specific server
hcloud server describe <server-id>
Hetzner Cloud has API rate limits (3600 requests/hour). If hitting limits:
Install the CLI for management:
# Install
brew install hcloud # macOS
# or download from https://github.com/hetznercloud/cli/releases
# Configure
hcloud context create my-project
# List resources
hcloud server list
hcloud network list
hcloud firewall list