With your Hetzner credentials stored in the management cluster, apply the Cluster manifest to provision a highly available Kubernetes cluster on Hetzner. ## Prerequisites - `kubectl` connected to the management cluster with the `hetzner` secret in place. Complete [Prepare your Hetzner account](/docs/hetzner/apalla/getting-started/prepare-your-hetzner-account) first. ## Step 1: Create the cluster Create a file named `cluster.yaml`. ```yaml vars title="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-v3 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](/docs/hetzner/apalla/reference/cluster-variables) for what every field controls. Apply the file: ```console $ 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: ```console $ 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. ```mermaid flowchart LR P["Pending
server not created yet"]:::platform --> V["Provisioning
Hetzner creates and boots it"]:::platform --> D["Provisioned
joining the cluster"]:::platform --> R["Running
healthy node"]:::platform ``` 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`: ```console vars 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 to stop watching. If a machine stays in `Provisioning` for more than a few minutes, something is wrong. See [Cluster creation fails](/docs/hetzner/apalla/clusters/troubleshooting/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](/docs/hetzner/apalla/getting-started/access-your-new-cluster) to fetch its kubeconfig and confirm the nodes are ready. ## Related - [Access your new cluster](/docs/hetzner/apalla/getting-started/access-your-new-cluster) - [Concepts: Cluster Stacks](/docs/hetzner/apalla/concepts/foundations/cluster-stacks) - [Concepts: declarative cluster management](/docs/hetzner/apalla/concepts/foundations/declarative-cluster-management) - [How to: upgrade within a version](/docs/hetzner/apalla/clusters/upgrades/update-within-a-version) - [Troubleshooting: cluster creation fails](/docs/hetzner/apalla/clusters/troubleshooting/cluster-creation-fails)