CRD Reference

API reference for the Machine custom resource.

API group: unbounded-cloud.io/v1alpha3

This document describes the custom resource definition shipped with the project: Machine.

Machine

PropertyValue
KindMachine
Pluralmachines
Short namemach
ScopeCluster
Status subresourceYes

Printer columns:

NameJSON PathDescription
Host.spec.ssh.hostSSH target address
Phase.status.phaseCurrent lifecycle phase
K8s Version.spec.kubernetes.versionDesired Kubernetes version
AgestandardTime since creation

spec.ssh

SSH connection details. When ssh is nil, the machina controller skips the Machine entirely.

FieldTypeRequiredDefaultDescription
sshSSHSpecNoSSH connection configuration.
ssh.hoststringYesHostname or IP, optionally with port (e.g. 1.2.3.4:2222). Port 22 is assumed when omitted.
ssh.usernamestringNo"azureuser"SSH username.
ssh.privateKeyRefSecretKeySelectorYesReference to a Secret containing the SSH private key. Must reside in the unbounded-kube namespace.
ssh.privateKeyRef.namestringYesSecret name.
ssh.privateKeyRef.namespacestringYesSecret namespace (must be unbounded-kube).
ssh.privateKeyRef.keystringNo"ssh-privatekey"Key within the Secret’s data map.
ssh.bastionBastionSSHSpecNoOptional jump host for the SSH connection.
ssh.bastion.hoststringYesBastion hostname or IP, optionally with port.
ssh.bastion.usernamestringNo"azureuser"Bastion SSH username.
ssh.bastion.privateKeyRef*SecretKeySelectorNoSame as ssh.privateKeyRefBastion SSH key. Falls back to the parent ssh.privateKeyRef when omitted.

spec.pxe

PXE boot configuration consumed by the metalman controller.

FieldTypeRequiredDefaultDescription
pxePXESpecNoPXE boot configuration.
pxe.imagestringYesOCI image reference containing netboot artifacts (e.g. "ghcr.io/azure/images/host-ubuntu2404:v1").
pxe.dhcpLeases[]DHCPLeaseNoStatic DHCP leases served during PXE boot.
pxe.dhcpLeases[].ipv4stringYesStatic IPv4 address to assign.
pxe.dhcpLeases[].macstringYesNIC MAC address (matched case-insensitively).
pxe.dhcpLeases[].subnetMaskstringYesSubnet mask.
pxe.dhcpLeases[].gatewaystringYesDefault gateway.
pxe.dhcpLeases[].dns[]stringNoDNS server addresses.
pxe.redfishRedfishSpecNoBMC access via the Redfish API.
pxe.redfish.urlstringYesRedfish endpoint URL.
pxe.redfish.usernamestringYesRedfish username.
pxe.redfish.deviceIDstringNo"1"Redfish system device ID.
pxe.redfish.passwordRefSecretKeySelectorYesSecret containing the Redfish password.
pxe.cloudInitCloudInitSpecNoOptional cloud-init customization for PXE-booted machines.
pxe.cloudInit.userDataConfigMapRefConfigMapKeySelectorNoReference to a ConfigMap containing custom cloud-init user-data.
pxe.cloudInit.userDataConfigMapRef.namestringYesConfigMap name.
pxe.cloudInit.userDataConfigMapRef.namespacestringYesConfigMap namespace.
pxe.cloudInit.userDataConfigMapRef.keystringNo"user-data"Key within the ConfigMap.

spec.kubernetes

Kubernetes join configuration.

FieldTypeRequiredDefaultDescription
kubernetesKubernetesSpecNoKubernetes join settings.
kubernetes.versionstringNoCluster versionDesired Kubernetes version (e.g. "v1.34.0"). A v prefix is added automatically if missing.
kubernetes.nodeRef*LocalObjectReferenceNoReference to the corresponding Node object. Set by the controller.
kubernetes.nodeLabelsmap[string]stringNoLabels to apply to the Node (not yet propagated by the machina controller).
kubernetes.bootstrapTokenRef.namestringYesName of the bootstrap token Secret in kube-system.

spec.operations

FieldTypeRequiredDefaultDescription
operations.rebootCounterint64No0Triggers a reboot when the spec value exceeds the status value.
operations.repaveCounterint64No0Triggers a PXE repave when the spec value exceeds the status value.

status

FieldTypeDescription
phasestringCurrent lifecycle phase (see table below).
messagestringHuman-readable status message.
ssh.fingerprintstringSSH host key fingerprint (not yet implemented).
redfish.certFingerprintstringBMC TLS certificate SHA-256 fingerprint. Set by metalman using TOFU.
tpm.ekPublicKeystringTPM endorsement key in PEM format. Set by metalman attestation using TOFU.
operations.rebootCounterint64Last-acted reboot counter value.
operations.repaveCounterint64Last-acted repave counter value.
conditions[]ConditionStandard Kubernetes conditions (see below).

Conditions

TypeSet ByDescription
SSHReachablemachinaTrue / False based on a TCP probe to the SSH port.
ProvisioningmachinaTrue while the install script is running over SSH. lastTransitionTime records when provisioning started, used to detect stale provisioning attempts (e.g. after a controller restart).
ProvisionedmachinaTrue after successful SSH provisioning. ObservedGeneration tracks the spec generation.
PoweredOffmetalmanTracks BMC power state during a reboot cycle. Removed after power-on completes. Not defined as a CRD type constant; set directly by the metalman redfish reconciler.
BootOrderConfigSupportedmetalmanSet to False when the BMC does not support boot order configuration. Not defined as a CRD type constant; set directly by the metalman redfish reconciler.
RepavedmetalmanFalse/Pending during repave; True/Succeeded after /pxe/disable. Stale False conditions are removed after a 30-minute timeout.

Phase lifecycle

The machina controller drives the following phases:

PhaseMeaningRequeue interval
PendingSSH is unreachable.30 s
ProvisioningInstall script is running over SSH.
JoiningProvisioned; waiting for a Node with the matching label.30 s
ReadyNode exists, or no kubernetes spec is present.5 min
FailedProvisioning encountered an error.60 s
RebootingReserved for metalman or provider controllers.

Labels and annotations

Labels:

LabelApplied toDescription
unbounded-cloud.io/machineNodeMaps the Node back to its Machine CR. Set during provisioning.
unbounded-cloud.io/siteMachineScopes a metalman instance to a subset of Machines.
unbounded-cloud.io/default-bootstrap-tokenSecretMarks a Secret as the default bootstrap token for auto-discovery.

Annotations:

AnnotationDescription
unbounded-cloud.io/providerAssociates a Machine with a provider controller (extension point).

Examples

Minimal SSH-only Machine:

apiVersion: unbounded-cloud.io/v1alpha3
kind: Machine
metadata:
  name: worker-01
spec:
  ssh:
    host: "10.0.0.50"
    privateKeyRef:
      name: ssh-key
      namespace: unbounded-kube
  kubernetes:
    version: v1.34.0
    bootstrapTokenRef:
      name: bootstrap-token-abc123

SSH with bastion:

apiVersion: unbounded-cloud.io/v1alpha3
kind: Machine
metadata:
  name: worker-02
spec:
  ssh:
    host: "192.168.1.100:2222"
    username: ubuntu
    privateKeyRef:
      name: ssh-key
      namespace: unbounded-kube
      key: id_ed25519
    bastion:
      host: "bastion.example.com"
      username: jump
  kubernetes:
    version: v1.34.0
    bootstrapTokenRef:
      name: bootstrap-token-abc123

PXE / bare-metal Machine:

apiVersion: unbounded-cloud.io/v1alpha3
kind: Machine
metadata:
  name: baremetal-01
  labels:
    unbounded-cloud.io/site: lab
spec:
  ssh:
    host: "10.0.0.60"
    privateKeyRef:
      name: ssh-key
      namespace: unbounded-kube
  pxe:
    image: ghcr.io/azure/images/host-ubuntu2404:v1
    dhcpLeases:
    - ipv4: "10.0.0.60"
      mac: "aa:bb:cc:dd:ee:ff"
      subnetMask: "255.255.255.0"
      gateway: "10.0.0.1"
      dns:
      - "8.8.8.8"
    redfish:
      url: "https://bmc-01.example.com"
      username: admin
      passwordRef:
        name: bmc-password
        namespace: unbounded-kube
    cloudInit:
      userDataConfigMapRef:
        name: my-cloud-init
        namespace: unbounded-kube
  kubernetes:
    version: v1.34.0
    bootstrapTokenRef:
      name: bootstrap-token-abc123

Netboot OCI Images

Netboot images are standard OCI container images built FROM scratch that contain all files needed for PXE booting a machine under /disk/. This follows the kubevirt containerDisk convention.

Files with a .tmpl suffix are Go templates rendered per-machine at serve time; other files are served verbatim. A metadata.yaml file provides image-level configuration (e.g. dhcpBootImageName).

Image layout

Netboot OCI image filesystem layout under /disk/: shimx64.efi, grubx64.efi, vmlinuz, initrd, init.cpio, unbounded-agent, metadata.yaml, grub/grub.cfg.tmpl, cloud-init templates

Template data

Templates receive the following data object:

FieldTypeDescription
.Machine*MachineThe Machine CR that initiated the request.
.ApiserverURLstringExternal Kubernetes API server URL.
.ServeURLstringExternal metalman HTTP URL.
.KubernetesVersionstringResolved Kubernetes version for the machine.
.ClusterDNSstringCluster DNS service IP.

Building images

Images are built, tagged, and pushed using standard container tooling:

docker build -t ghcr.io/azure/images/host-ubuntu2404:v1 .
docker push ghcr.io/azure/images/host-ubuntu2404:v1

See images/host-ubuntu2404/ for an example Containerfile.

metadata.yaml

dhcpBootImageName: shimx64.efi

The dhcpBootImageName field specifies the boot filename included in DHCP responses (option 67).


CRD relationships

Machine CRD relationships: Machine spec fields reference OCI Image, Secrets in unbounded-kube and kube-system namespaces, with bidirectional Machine-Node link via label

See Also

  • SSH Guide – SSH provisioning walkthrough using these CRDs.
  • PXE Guide – Bare-metal provisioning walkthrough using Machine and OCI netboot images.
  • Networking CRDs – Site, GatewayPool, and related CRDs from unbounded-net.
  • CLI Reference – The kubectl unbounded commands that create these resources.
  • Architecture – How these CRDs drive the provisioning pipelines.