Hetzner Cloud is one of the most cost-effective platforms for self-managed Kubernetes. A full HA production setup — 3 control planes, 3 workers, 2 HAProxy LB nodes — costs around €63/month, compared to €400–800/month for equivalent managed Kubernetes on AWS EKS or GKE.
This guide covers the complete setup: infrastructure, networking, control plane bootstrapping, and storage.
Architecture
Internet
│
Floating IP (Keepalived VRRP)
│
HAProxy-1 ←→ HAProxy-2 (active/passive)
│
┌───┼───┐
CP1 CP2 CP3 (control plane, etcd)
│
Worker-1 Worker-2 Worker-3
The Floating IP provides a stable entry point that survives HAProxy node failures. Keepalived runs VRRP between the two HAProxy nodes and moves the IP automatically on failure.
Server Sizing
For a standard production cluster:
| Role | Type | Count | Cost |
|---|---|---|---|
| HAProxy / LB | cx23 (2vCPU/4GB) | 2 | €7.98/mo |
| Control Plane | cx33 (4vCPU/8GB) | 3 | €19.47/mo |
| Worker | cx43 (8vCPU/16GB) | 3 | €35.97/mo |
| Network | Private network + Floating IP | — | €5.99/mo |
Total: ~€69/month for a fully HA Kubernetes cluster.
Use the K8s Cluster Cost Calculator to price your specific configuration.
Step 1: Create the Infrastructure
Create a private network 10.0.0.0/16 in Hetzner, then create servers in the same network:
# Install hcloud CLI
brew install hcloud # or: apt install hcloud
# Authenticate
hcloud context create k8s-prod
# Create private network
hcloud network create --name k8s-net --ip-range 10.0.0.0/16
hcloud network add-subnet k8s-net --type cloud --ip-range 10.0.1.0/24 --network-zone eu-central
# Create servers (example for LB nodes)
hcloud server create --name lb-1 --type cx23 --image ubuntu-24.04 --network k8s-net
hcloud server create --name lb-2 --type cx23 --image ubuntu-24.04 --network k8s-net
# Create and assign Floating IP
hcloud floating-ip create --type ipv4 --home-location fsn1
hcloud floating-ip assign <floating-ip-id> lb-1
Step 2: Configure HAProxy and Keepalived
On both LB nodes, install HAProxy and Keepalived:
apt-get install -y haproxy keepalived
Generate your haproxy.cfg using the HAProxy Config Generator, then configure Keepalived for VRRP failover.
The key Keepalived configuration uses a notify script to reassign the Hetzner Floating IP via the hcloud API on failover:
# /etc/keepalived/notify.sh
#!/bin/bash
ROLE=$3
if [ "$ROLE" = "MASTER" ]; then
hcloud floating-ip assign <floating-ip-id> $(hostname)
fi
Step 3: Bootstrap the Control Plane
Generate a kubeadm config using the kubeadm Config Generator:
# On the first control plane node
kubeadm init --config kubeadm-config.yaml --upload-certs
The controlPlaneEndpoint must point to your Floating IP — this is the stable address all nodes use to reach the K8s API.
Step 4: Install a CNI
Flannel is the simplest option for Hetzner (no BGP required):
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
For NetworkPolicy support, use Calico instead (Flannel doesn't enforce policies).
Step 5: Add Worker Nodes
# Output from kubeadm init
kubeadm join 10.0.0.100:6443 \
--token <token> \
--discovery-token-ca-cert-hash sha256:<hash>
Step 6: Install Longhorn for Storage
helm repo add longhorn https://charts.longhorn.io
helm install longhorn longhorn/longhorn \
--namespace longhorn-system \
--create-namespace \
--set defaultSettings.defaultReplicaCount=3
Configure S3 backup to Hetzner Object Storage using the Longhorn S3 Backup Generator.
Cost vs Managed Kubernetes
| Platform | Equivalent Config | Monthly Cost |
|---|---|---|
| This setup (Hetzner) | 3 CP + 3 Workers HA | ~€69 |
| AWS EKS | 3 × m5.xlarge workers | ~€450 |
| GKE Autopilot | Equivalent compute | ~€380 |
| DigitalOcean DOKS | 3 × 4vCPU/8GB | ~€180 |
The tradeoff: you manage upgrades, cert renewal, and etcd backups yourself. Automate the etcd backups with the etcd Backup CronJob Generator.