Skip to main content

Label nodes and assign roles

Inspect 1.36

Put a label on a worker pool, and every node that pool creates carries it. Pods then use nodeSelector or (a rule that attracts pods to nodes with a specific label) to target that pool.

Prerequisites

Add labels to a worker pool

Each worker pool is one entry under spec.topology.workers.machineDeployments.

Add a metadata.labels block

Add it to the pool, at the same level as name, replicas, and failureDomain:

cluster.yamlyaml
		apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
  name: mycluster
  namespace: my-org
spec:
  topology:
    classRef:
      name: hetzner-apalla-1-36-v6
    version: v1.36.4
    controlPlane:
      replicas: 3
    workers:
      machineDeployments:
        - class: workeramd64hcloud
          name: md-0
          replicas: 3
          failureDomain: fsn1
          metadata:
            labels:
              node-role.kubernetes.io/backend: ""
              node.cluster.x-k8s.io/environment: production
          variables:
            overrides:
              - name: workerMachineTypeHcloud
                value: cpx42
	
Note

Only add a metadata: block when you actually have labels to set. In v1beta2, do not add an empty metadata: {} placeholder.

Apply the Cluster resource

Apply it directly, or let GitOps sync it:

		$ kubectl apply -f cluster.yaml
	

Syself reads metadata.labels from each pool and writes them onto the matching node objects in the workload cluster, on top of the labels it sets on every node automatically. See for those system labels.

Confirm the label landed

		$ kubectl get nodes -l node-role.kubernetes.io/backend
	

This lists every node that carries the label, so you can check the pool reached the nodes you expect.

Which labels reach the node

Only labels in these domains reach the node:

Domain Example
node-role.kubernetes.io node-role.kubernetes.io/backend: ""
node-restriction.kubernetes.io node-restriction.kubernetes.io/location: fsn1
node.cluster.x-k8s.io node.cluster.x-k8s.io/environment: production

A label in any other domain, for example mycompany.com/tier: critical, does not reach the node. Syself does not report an error; the label is silently dropped.

Warning

Role labels under node-role.kubernetes.io/ use an empty-string value (""), not "true". A nodeSelector or affinity rule on a pod must match the exact key and value. A pod selecting node-role.kubernetes.io/backend: "true" does not match a node labelled node-role.kubernetes.io/backend: "".

Bare-metal pools also use host labels

A bare-metal pool uses a separate set of labels on HetznerBareMetalHost resources to determine which physical servers the pool can claim.

The pool uses workerHostSelectorBareMetal to select worker hosts, or controlPlaneHostSelectorBareMetal when selecting hosts for a bare-metal control plane.

See for instructions on labelling and selecting hosts. For an example of using both host and node labels in the same pool, see .

Multiple pools with different roles

Each machineDeployments entry is a separate pool with its own labels. Add several entries to give different groups of nodes different roles. Machine type and labels are independent settings, so a staging pool can use a smaller machine type while carrying its own label. This manifest declares a production pool and a staging pool side by side:

yaml
		workers:
  machineDeployments:
    - class: workeramd64hcloud
      name: md-production
      replicas: 3
      failureDomain: fsn1
      metadata:
        labels:
          node-role.kubernetes.io/backend: ""
          node.cluster.x-k8s.io/environment: production
      variables:
        overrides:
          - name: workerMachineTypeHcloud
            value: cpx42
    - class: workeramd64hcloud
      name: md-staging
      replicas: 2
      failureDomain: fsn1
      metadata:
        labels:
          node-role.kubernetes.io/backend: ""
          node.cluster.x-k8s.io/environment: staging
      variables:
        overrides:
          - name: workerMachineTypeHcloud
            value: cpx32
	

Each pool needs a unique name.

Tip

You can mix cloud and bare-metal pools in the same cluster: class: workeramd64hcloud for cloud, class: workeramd64baremetal for bare metal. Each pool gets its own metadata.labels. See .