Bare metal Control Planes

Hetzner Cloud uses dynamic provisioning, which means when Syself Autopilot needs to provision a new control plane node (during a rolling update, version upgrade, or a replacement triggered by health checks), it creates a new VM. If capacity in a region is temporarily exhausted, the operation can stall mid-flight. That can leave upgrades partially completed or recovery processes blocked while the cluster runs in a degraded state. Bare metal control planes eliminate this entirely: the server is never returned to a public pool, updates roll across existing inventory and health check remediations happen on the same host.

In order to use bare metal control planes set controlPlane.class to hetznerbaremetal in your cluster topology.

Prerequisites

Before creating a cluster with a baremetal control plane, ensure your HetznerBareMetalHost resources are registered and labeled appropriately.

See also: Adding baremetal servers to your cluster

Labeling your baremetal hosts

Each HetznerBareMetalHost should have labels that identify it. We recommend using:

  • A role label to indicate the node is for the control plane.
  • A cluster label to scope the host to a specific cluster.

For example:

yaml
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: HetznerBareMetalHost metadata: name: bm-1 labels: role: controlplane cluster: mycluster spec:

It is important to use at least two labels, this way your bare metal hosts can be divided properly between multiple clusters, and between control plane and worker node groups.

Creating a cluster with a baremetal control plane

Create your cluster with controlPlane.class as hetznerbaremetal and provide a host selector to match your HetznerBareMetalHost resources:

cluster.yaml yaml
apiVersion: cluster.x-k8s.io/v1beta1 kind: Cluster metadata: // [!code tooltip:mycluster:1:Use any meaningful name for your cluster] name: mycluster spec: clusterNetwork: services: cidrBlocks: ['10.128.0.0/12'] pods: cidrBlocks: ['192.168.0.0/16'] serviceDomain: 'cluster.local' topology: class: hetzner-apalla-1-34-v5 version: v1.34.6 controlPlane: class: hetznerbaremetal replicas: 3 variables: overrides: - name: controlPlaneHostSelectorBareMetal value: matchLabels: role: controlplane cluster: mycluster workers: machineDeployments: - class: workeramd64hcloud name: md-0 replicas: 1 failureDomain: nbg1 variables: overrides: - name: workerMachineTypeHcloud value: cpx42 variables: - name: region value: nbg1

Host selection

The controlPlaneHostSelectorBareMetal variable determines which HetznerBareMetalHost resources are used for the control plane.

Using matchLabels

Select hosts that have all the specified labels:

yaml
variables: overrides: - name: controlPlaneHostSelectorBareMetal value: matchLabels: role: controlplane cluster: mycluster

Using matchExpressions

For more flexible selection use matchExpressions . For example, you can select hosts for control-plane from a pool of hosts:

yaml
variables: overrides: - name: controlPlaneHostSelectorBareMetal value: matchExpressions: - key: role operator: In values: - controlplane-group-1 - controlplane-group-2

This is useful when you want the control plane to be provisioned on any server from a specific pool rather than requiring all labels to match exactly.

No host selector

If controlPlaneHostSelectorBareMetal is not set, an available HetznerBareMetalHost will be chosen randomly. Setting a host selector is recommended in production to ensure control plane nodes are provisioned on the intended servers.

Switching between HCloud and baremetal

The controlPlane.class field determines the control plane type:

ValueDescription
(not set)Uses HCloud by default
hcloud Explicitly uses HCloud VMs
hetznerbaremetal Uses Hetzner baremetal servers

To switch an existing cluster's control plane type, update the controlPlane.class field in the cluster topology.

warning

Switching the control plane type triggers a rolling replacement of all control plane nodes. Plan this when the cluster is in a healthy 3/3 state and during a maintenance window.