Create your first cluster
With your Hetzner credentials stored in the management cluster, apply the Cluster manifest to provision a highly available Kubernetes cluster on Hetzner.
Prerequisites#
kubectlconnected to the management cluster with thehetznersecret in place. Complete Prepare your Hetzner account first.
Step 1: Create the cluster#
Create a file named cluster.yaml.
apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
name: mycluster
spec:
clusterNetwork:
services:
cidrBlocks: ["100.96.0.0/16"]
pods:
cidrBlocks: ["100.64.0.0/11"]
serviceDomain: "cluster.local"
topology:
classRef:
name: hetzner-apalla-1-36-v4
version: v1.36.4
controlPlane:
replicas: 3
workers:
machineDeployments:
- class: workeramd64hcloud
name: md-0
replicas: 1
failureDomain: nbg1
variables:
overrides:
- name: workerMachineTypeHcloud
value: cpx42
variables:
- name: region
value: nbg1
- name: controlPlaneMachineTypeHcloud
value: cpx42
This example creates a cluster with three control plane nodes and one worker node in the nbg1 (Nuremberg) region. Three control plane nodes give you a highly available control plane: the cluster keeps running if one node fails.
Note
These nodes are servers on your own Hetzner account, and they bill for as long as they exist.
Tip
Worth changing for your setup: region, controlPlaneMachineTypeHcloud and workerMachineTypeHcloud (server sizes), and the worker replicas count. Leave clusterNetwork, controlPlane.replicas: 3, and the CIDR blocks (the internal IP address ranges pods and services use to talk to each other) at their defaults unless you have a specific reason to change them. They are tested together as a validated set; see Cluster variables for what every field controls.
Apply the file:
$ kubectl apply -f cluster.yaml
cluster.cluster.x-k8s.io/mycluster created
The command returns as soon as the manifest is stored. The real work starts now, in the background. Syself Autopilot orders the servers from Hetzner, boots each one from the node image, and joins them into one cluster. This takes five to ten minutes.
Step 2: Watch the servers come up#
Each server appears as a Machine object in the management cluster. Watch them:
$ kubectl get machines --watch
Every machine moves through the same phases:
Pending: the Machine object exists, the server is not created yet.Provisioning: Hetzner is creating and booting the server.Provisioned: the server is up and joining the cluster.Running: the node joined the cluster and is healthy.
flowchart LR P["Pending<br/>server not created yet"] --> V["Provisioning<br/>Hetzner creates and boots it"] --> D["Provisioned<br/>joining the cluster"] --> R["Running<br/>healthy node"]
The first control plane machine reaches Running first. The remaining control plane machines follow one at a time, and the worker joins once the control plane answers. A machine sitting in Pending while an earlier one provisions is normal, not a failure.
When the cluster is ready, all machines show Running:
NAME CLUSTER NODE NAME READY AVAILABLE UP-TO-DATE PHASE AGE VERSION
mycluster-abc12-xyz01 mycluster mycluster-abc12-xyz01 True True True Running 10m v1.36.4
mycluster-abc12-xyz02 mycluster mycluster-abc12-xyz02 True True True Running 9m v1.36.4
mycluster-abc12-xyz03 mycluster mycluster-abc12-xyz03 True True True Running 8m v1.36.4
mycluster-md-0-def34-xyz04 mycluster mycluster-md-0-def34-xyz04 True True True Running 7m v1.36.4
Press Ctrl+ C to stop watching.
If a machine stays in Provisioning for more than a few minutes, something is wrong. See Cluster creation fails for the checks, starting with the Hetzner secret and your project quota.
Next step#
Every machine shows Running: your highly available cluster is up. Continue with Access your new cluster to fetch its kubeconfig and confirm the nodes are ready.
Related#
Hetzner account preparation
Prepare your Hetzner account for Syself Autopilot - create a project and API token, upload an SSH key, and store the credentials as secrets in the management cluster.
Access your new cluster
Fetch the kubeconfig for a workload cluster you just created with Syself Autopilot, point kubectl at it, and confirm every node is Ready.