Hetzner Provider
The Hetzner provider creates Kubernetes cluster nodes as Hetzner Cloud servers running Talos Linux. It provisions real cloud infrastructure with public IPs, private networking, load balancers, and persistent volumes â ideal for production-grade clusters and cloud testing.
When to Use the Hetzner Provider
Section titled âWhen to Use the Hetzner ProviderâThe Hetzner provider is ideal when you:
- Need production-grade Kubernetes on affordable European cloud infrastructure
- Want real cloud load balancers and persistent volumes (not emulated locally)
- Run performance or integration tests that require dedicated server resources
- Deploy Talos Linux clusters with high-availability placement groups
Prerequisites
Section titled âPrerequisitesâ- Hetzner Cloud account â Sign up at hetzner.com/cloud
- API token â Create one in the Hetzner Cloud Console â Project â Security â API Tokens (read/write permissions)
- Talos ISO â A Talos Linux ISO must be available in your Hetzner Cloud project (x86 default:
122630, ARM:122629â see Talos options) - Docker â Required locally for
ksailCLI operations
Configuration
Section titled âConfigurationâEnvironment Variable
Section titled âEnvironment VariableâExport the Hetzner Cloud API token so KSail can manage servers:
export HCLOUD_TOKEN=your-hetzner-api-tokenBy default, KSail reads from HCLOUD_TOKEN. To use a different environment variable name, set spec.cluster.hetzner.tokenEnvVar in ksail.yaml.
ksail.yaml Reference
Section titled âksail.yaml ReferenceâThe Hetzner provider is configured through spec.cluster.hetzner in ksail.yaml:
apiVersion: ksail.io/v1alpha1kind: Clustermetadata: name: my-hetzner-clusterspec: cluster: distribution: Talos provider: Hetzner hetzner: # Server types (default: cx23 for both) controlPlaneServerType: "cx23" workerServerType: "cx23" # Datacenter location (default: fsn1) location: "fsn1" # Private network settings networkCidr: "10.0.0.0/16" # networkName: "my-network" # defaults to <cluster>-network # Optional: SSH key for server access (Talos API is primary) # sshKeyName: "my-key" # Optional: override the default env var name (default: HCLOUD_TOKEN) # tokenEnvVar: "MY_CUSTOM_HCLOUD_TOKEN" # Placement group settings for HA placementGroupStrategy: "Spread" # or "None" # placementGroup: "my-placement" # defaults to <cluster>-placement # fallbackLocations: ["nbg1", "hel1"] # placementGroupFallbackToNone: false talos: controlPlanes: 1 workers: 2 # ISO image ID for Hetzner (default: 122630 for x86, use 122629 for ARM) iso: 122630| Field | Type | Default | Description |
|---|---|---|---|
hetzner.controlPlaneServerType | string | cx23 | Hetzner server type for control-plane nodes |
hetzner.workerServerType | string | cx23 | Hetzner server type for worker nodes |
hetzner.location | string | fsn1 | Datacenter location (fsn1, nbg1, hel1) |
hetzner.networkName | string | <cluster>-network | Private network name |
hetzner.networkCidr | string | 10.0.0.0/16 | Network CIDR block |
hetzner.sshKeyName | string | (empty) | SSH key for server access (optional) |
hetzner.tokenEnvVar | string | HCLOUD_TOKEN | Environment variable containing the API token |
hetzner.placementGroupStrategy | string | Spread | Spread (HA) or None (no placement group) |
hetzner.placementGroup | string | <cluster>-placement | Placement group name |
hetzner.fallbackLocations | list | ["nbg1", "hel1"] | Alternative locations if primary is unavailable |
hetzner.placementGroupFallbackToNone | bool | false | Fall back to no placement group on capacity issues |
Talos options for Hetzner clusters
Section titled âTalos options for Hetzner clustersâ| Field | Type | Default | Description |
|---|---|---|---|
talos.iso | int | 122630 | Hetzner Cloud ISO/image ID for Talos (use 122629 for ARM) |
Quick Start
Section titled âQuick StartâStep 1: Configure API Token
Section titled âStep 1: Configure API TokenâSet HCLOUD_TOKEN as described in the Configuration section above, then verify it is exported in your shell.
Step 2: Initialize Project
Section titled âStep 2: Initialize Projectâksail cluster init \ --name my-hetzner-cluster \ --distribution Talos \ --provider Hetzner \ --control-planes 1 \ --workers 2This creates ksail.yaml and a talos/ directory for Talos configuration patches.
Step 3: Create Cluster
Section titled âStep 3: Create Clusterâksail cluster createKSail creates Hetzner Cloud servers, boots them with Talos Linux, bootstraps Kubernetes, configures kubectl context, and installs the Hetzner Cloud Controller Manager and CSI driver.
Step 4: Verify Cluster
Section titled âStep 4: Verify Clusterâksail cluster infokubectl get nodes -o widekubectl get pods -n kube-systemStep 5: Cleanup
Section titled âStep 5: Cleanupâksail cluster deleteArchitecture
Section titled âArchitectureâKSail provisions Hetzner Cloud servers running Talos Linux, connected via a private network. The Hetzner Cloud Controller Manager provides native load balancer integration, and the Hetzner CSI Driver provisions persistent volumes backed by Hetzner Block Storage.
graph TB
subgraph "Your Machine"
KSAIL["ksail CLI"]
end
subgraph "Hetzner Cloud"
API["Hetzner Cloud API"]
NET["Private Network"]
LB["Cloud Load Balancer"]
subgraph "Servers"
CP["Control Plane (Talos)"]
W1["Worker Node 1 (Talos)"]
W2["Worker Node 2 (Talos)"]
end
end
KSAIL -->|"HCLOUD_TOKEN"| API
API --> CP
API --> W1
API --> W2
CP --- NET
W1 --- NET
W2 --- NET
LB -->|"traffic"| W1
LB -->|"traffic"| W2
CP -.->|"kubeconfig"| KSAIL
Installed Components
Section titled âInstalled ComponentsâWhen using the Hetzner provider, KSail automatically installs:
- Hetzner Cloud Controller Manager â Provisions Hetzner Cloud Load Balancers for
type: LoadBalancerservices - Hetzner CSI Driver â Provisions Hetzner Block Storage volumes for
PersistentVolumeClaimresources - Placement groups â Distributes servers across physical hosts for high availability (configurable)
Operations
Section titled âOperationsâList Clusters
Section titled âList Clustersâksail cluster listCluster Info
Section titled âCluster Infoâksail cluster infoDisplays Kubernetes control-plane and core service endpoints for the current context.
Update Cluster
Section titled âUpdate Clusterâksail cluster updateApplies in-place changes to components (CNI, GitOps engine, cert-manager, etc.). Node scaling changes for Talos are applied in-place. Changes to hetzner.location, hetzner.controlPlaneServerType, or hetzner.networkCidr require cluster recreation. See the Update Behavior table for details.
Deploy with LoadBalancer
Section titled âDeploy with LoadBalancerâkubectl create deployment web --image=nginx --replicas=3kubectl expose deployment web --port=80 --type=LoadBalancerkubectl get svc web --watchThe type: LoadBalancer service provisions a real Hetzner Cloud Load Balancer with a public IP.
Troubleshooting
Section titled âTroubleshootingâhcloud token is not set â The HCLOUD_TOKEN environment variable is missing or empty. Run echo $HCLOUD_TOKEN to check. Re-export if needed. If you use a custom variable name, verify it matches spec.cluster.hetzner.tokenEnvVar in ksail.yaml.
Server creation fails with resource unavailability â The selected location may be out of capacity for the requested server type. Configure spec.cluster.hetzner.fallbackLocations to try alternative datacenter locations automatically:
spec: cluster: hetzner: location: "fsn1" fallbackLocations: ["nbg1", "hel1"]Placement group errors â Hetzner limits spread placement groups to 10 servers per datacenter. Reduce your node count or set placementGroupStrategy: "None". For best-effort HA, set placementGroupFallbackToNone: true to fall back automatically when spread placement fails.
context deadline exceeded or connection errors â Verify HCLOUD_TOKEN is valid and has read/write permissions. Check connectivity with curl -sI https://api.hetzner.cloud/v1/servers -H "Authorization: Bearer $HCLOUD_TOKEN".
Cluster deletion leaves orphaned resources â If ksail cluster delete is interrupted, manually clean up in the Hetzner Cloud Console: delete servers, load balancers, networks, and placement groups associated with your cluster name.