Baremetal Control Planes

By default, control plane nodes run on Hetzner Cloud VMs. HCloud uses dynamic provisioning i.e. when CAPI needs a new control plane node (during a rolling update, version upgrade, or MachineHealthCheck replacement), it creates a new VM. If HCloud cannot fulfill that request due to regional capacity constraints, the operation stalls. For upgrades this means the rollout blocks mid-flight; for failure recovery it means the cluster stays degraded until capacity returns. Baremetal control planes eliminate this entirely. The server is never returned to a pool, updates roll across existing inventory and MachineHealthCheck remediates on the same host.

In order to use baremetal 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:

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-v3 version: v1.34.5 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.