Syself stamps its own labels and annotations onto a node at provisioning and join time. Here is each one, who writes it, and what reads it. The standard upstream labels the kubelet and the CCM already set, like `kubernetes.io/os` and `node.kubernetes.io/instance-type`, are left out. (CCM is the Cloud Controller Manager, the cloud provider's Kubernetes plugin.) ## Role labels | Label | Set by | On | What reads it | | --------------------------------------- | ------------------------------------------ | -------------- | ------------------------------------------------------------------------- | | `node-role.kubernetes.io/control-plane` | Syself at node join time | control planes | the host firewall, which gives control planes and workers different rules | | `node.kubernetes.io/worker` | kubelet `--node-labels` (worker bootstrap) | workers | conventional marker that this is a worker node | ## Topology labels (scheduling and storage) | Label | Set by | On | What reads it | | ------------------------------------------------ | ----------------------------------------------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `kubernetes.io/hostname` | kubelet | every node | the default topology spread (per-node axis) | | `topology.kubernetes.io/zone` | Hetzner CCM | every node | default topology spread (zone axis), CSI (Container Storage Interface, the Kubernetes standard for storage drivers) volume placement, failure-domain awareness. | | `topology.kubernetes.io/region` | Hetzner CCM | every node | region-level failure-domain awareness | | `instance.hetzner.cloud/is-root-server` = `true` | kubelet `--node-labels` (bare-metal worker bootstrap) | bare-metal (Robot) worker nodes | the CSI driver node affinity, to exclude bare metal (Hetzner Cloud volumes attach only to cloud servers) | ## Hardware labels Syself detects hardware at provisioning time and sets these labels at node registration. The `machine-type` label is always present. The capability labels appear only when the feature is detected, so the absence of a label means the node does not have that capability. | Label | Set by | On | What reads it | | ------------------------------------------------------------- | --------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------- | | `autopilot.syself.com/machine-type` = `baremetal` \| `hcloud` | Syself (detected at provisioning time via hypervisor detection) | every node | placement that must distinguish bare metal from cloud | | `autopilot.syself.com/gpu` = `true` | Syself, on nodes with an NVIDIA GPU | GPU nodes | Syself's GPU components: they deploy only on nodes with this label | | `autopilot.syself.com/virtualization` = `kvm` | Syself (hardware virtualization detected at provisioning time) | bare-metal nodes with hardware virtualization | schedules `secure` (Kata Containers) workloads onto nodes with hardware virtualization | | `autopilot.syself.com/tpm` = `true` | Syself (TPM device detected at provisioning time) | nodes with a TPM (a hardware security chip on the motherboard) | workloads or policy that require a TPM | > [!TIP] > A node gets `autopilot.syself.com/gpu=true` only when its PCI vendor:device id is on the provisioner's allowlist of the NVIDIA cards Hetzner ships: GTX 1080, GTX 1080 Ti, RTX 4000 SFF Ada, RTX 6000 Ada, and the three RTX PRO 6000 Blackwell variants. Any other NVIDIA display adapter is not recognized as a GPU and gets no GPU label. ## Bootstrap and rollout markers | Label / annotation | Set by | On | Meaning | | ------------------------------------------------------------ | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `bootstrap.syself.com/10-kubelet-local` (label) | Syself at first boot | control planes | marks the "repoint the control-plane kubelet to the local API server" step. Present while the step is pending; removed when done. Completion is recorded by the `-done-at` annotation. | | `bootstrap.syself.com/10-kubelet-local-done-at` (annotation) | Syself at first boot | control planes | the timestamp the step above completed | | `capi.syself.com/constant-bare-metal-hostname` = `true` | Syself, on the bare-metal worker MachineDeployment class in the ClusterClass | the MachineDeployment, MachineSet, Machine and HetznerBareMetalMachine, never the Node | keeps a constant hostname across a `maxSurge=0` rollout (the physical host is reprovisioned in place) | ## Annotations The health daemon publishes its report to the node under `autopilot.syself.com/`, one key per domain, refreshed every two minutes. Each key holds a self-contained JSON document for its domain. | Annotation | Set by | On | Contents | | ------------------------------- | ----------------- | ---------- | -------------------------------------------------- | | `autopilot.syself.com/storage` | the health daemon | every node | filesystem and LVM volume-group usage, as JSON | | `autopilot.syself.com/disks` | the health daemon | every node | per-disk health, as JSON | | `autopilot.syself.com/certs` | the health daemon | every node | node certificate expiry, as JSON | | `autopilot.syself.com/tamper` | the health daemon | every node | the tamper-detection result, as JSON | | `autopilot.syself.com/services` | the health daemon | every node | the state of the units the daemon watches, as JSON | Use these when a condition is set and you need the detail behind it. See [Node health conditions](/docs/hetzner/apalla/reference/node-health-conditions) for the full condition catalog. ## Not a node label `syself.com/image-type` is an annotation on the node OS image, not a label on a Node object. It is set at image build time, not from the state of a running node. You will not find it on a `kubectl get node` object. ## Related - [Node health conditions](/docs/hetzner/apalla/reference/node-health-conditions): what the health daemon sets and what triggers automatic replacement. - [Run GPU workloads](/docs/hetzner/apalla/workloads/specialized/run-gpu-workloads): how to schedule pods onto GPU-labelled nodes. - [Steer workload placement](/docs/hetzner/apalla/workloads/placement/steer-workload-placement): how topology labels drive default spread rules. - [Node and OS security](/docs/hetzner/apalla/security/node-and-os-security): the TPM and tamper signals. - [Storage](/docs/hetzner/apalla/concepts/internals/storage): why bare-metal nodes carry `instance.hetzner.cloud/is-root-server`.