Network booting
Most modern hardware supports booting an operating system from the network. The technology behind this is called Preboot Execution Environment. PXE booting Kairos needs three files: a kernel, an initrd and a squashfs rootfs. These are not shipped as standalone release assets — you obtain them from a Kairos OCI image or ISO.
The recommended way to do this is with AuroraBoot, which pulls a Kairos OCI image, extracts the netboot artifacts and serves them over HTTP, with built-in ProxyDHCP so a target machine on the same network can boot directly. If you'd rather plug Kairos into an existing PXE/TFTP setup, AuroraBoot can also extract the same artifacts ahead of time from a Kairos ISO so you can serve them yourself.
Generic hardware-based netboot setup (PXE BIOS configuration, DHCP, etc.) is out of scope for this document.
Run Kairos from RAM with local persistent data​
The in-RAM workflow is useful for machines that load the Kairos root filesystem
into memory from live media or PXE, but still need machine-specific
configuration and persistent data on a local disk. The machine does not need
COS_STATE or COS_ACTIVE partitions. It mounts:
COS_OEMat/oemfor cloud config and user dataCOS_PERSISTENTat/usr/localfor persistent state
Add a kairos.ram.* option to the kernel command line to select this workflow.
Use the bare kairos.ram option if you do not need any of the partition
options:
kairos.ram
For first boot on an empty disk, let Kairos create the local partitions:
kairos.ram.create_partitions
Kairos selects the largest eligible empty disk. Removable media, CD-ROMs, and virtual block devices such as loop and device-mapper devices are excluded. To select a disk yourself, pass its path:
kairos.ram.create_partitions=/dev/vda
The default COS_OEM size is 64 MiB. COS_PERSISTENT uses the rest of the
disk. Override either size with a plain integer in MiB:
kairos.ram.create_partitions=/dev/vda kairos.ram.oem=128 kairos.ram.persistent=10240
If one of the partitions already exists, Kairos keeps it and creates only the
missing partition. Kairos refuses to repartition a disk that contains unrelated
partitions unless you add kairos.ram.wipe.
kairos.ram.wipe allows Kairos to replace an existing partition table and
destroys all data on the selected disk.
With AuroraBoot, put the same options in netboot.cmdline. With another PXE
server, add them to the kernel command line in its boot entry.
Because in-RAM mode does not run an installation, nothing seeds the machine
configuration for you: provide cloud
config yourself. This is especially
important on the first boot, when the machine needs user data such as login
credentials. Bundle the config with the boot artifacts, use a supported metadata
source, or add kairos.config_url=<URL> to the kernel command line to fetch it
from a central server. kairos.config_url is particularly useful with PXE
because the server can keep both the boot configuration and machine
configuration centralized.
User data pulled from a metadata source (NoCloud/cidata, cloud provider
metadata, …) is written to /oem/95_userdata on the local COS_OEM
partition, so it survives reboots and is not fetched again on later boots.
Config fetched through kairos.config_url is read on every boot instead.
An in-RAM boot is reported as active_boot, so both of these sentinel files
exist after immucore finishes:
/run/cos/active_mode
/run/cos/in_ram_mode
Use /run/cos/in_ram_mode when a script must distinguish an in-RAM root
filesystem from a regular active boot:
if [ -e /run/cos/in_ram_mode ]; then
echo "Kairos is running from RAM"
fi
In-RAM boot with Trusted Boot (UKI)​
The same kairos.ram.* options work under Trusted
Boot. A UKI already runs entirely from RAM, so
the regular UKI boot flow applies, with a few differences:
- The kernel command line is part of the signed UKI (or a signed addon), so the
kairos.ram.*options must be baked in when the image is built and signed — they cannot be added or edited interactively at boot time. kairos.ram.create_partitionsencrypts the partitions it creates with the TPM PCR policy — the samesystemd-cryptenrollenrollment kairos-agent performs during a trusted-boot installation — so every later boot unlocks them through the TPM. There is no plaintext fallback: if encryption fails, the boot halts with a full-screen error. Remote key management (kcrypt-challenger) is not supported in this flow, because the UKI initramfs has no network yet when the partitions are created and unlocked.- The boot is marked with the
/run/cos/uki_boot_modesentinel (notuki_install_mode), so the installer cloud-init stages do not run.
The stock datasource configuration skips pulling providers (NoCloud/cidata,
cloud provider metadata services, …) when /run/cos/uki_boot_mode is present:
on an installed trusted-boot system the configuration was baked into the OEM
partition at install time, so there is nothing to pull. An in-RAM boot never
runs an installation, though — without further action the machine comes up
with no per-machine configuration at all.
The recommended approach is to bundle the configuration into the image at build time: it becomes part of the signed, measured artifact and the machine never needs to reach out to a datasource at boot.
When the configuration must be per-machine and cannot be bundled, bake
kairos.pull_datasources into the signed kernel command line to pull it from
a datasource instead. The pulled user data is stored at /oem/95_userdata on
the (TPM-encrypted) COS_OEM partition, so it persists across reboots and
later boots skip the pull.
Use AuroraBoot​
docker run --rm -ti --net host quay.io/kairos/auroraboot \
--set "container_image=quay.io/kairos/hadron:v0.4.0-standard-amd64-generic-v4.1.2-k3s-v1.36.1-k3s1"
# Optionally:
# --cloud-config ....
This will netboot the quay.io/kairos/hadron:v0.4.0-standard-amd64-generic-v4.1.2-k3s-v1.36.1-k3s1 image. AuroraBoot listens for PXE requests on the host network and serves the boot artifacts to any machine on that network configured to boot from the network. See the AuroraBoot documentation for more options (cloud-config, custom command line, disabling DHCP if you already have one, etc.).
If your hardware doesn't support PXE booting from firmware, you can use our generic iPXE ISO to bootstrap iPXE, which will then look for AuroraBoot (or any other ProxyDHCP server) on the network.
Use your own netboot server​
If you'd rather plug Kairos into an existing netboot setup (pixiecore, dnsmasq, a PXE/TFTP server you already run), AuroraBoot exposes two subcommands to support that workflow.
First, extract the kernel, initrd and squashfs from a Kairos ISO:
docker run --rm -v $PWD:/work quay.io/kairos/auroraboot \
netboot /work/kairos.iso /work/out kairos
This writes kairos-kernel, kairos-initrd and kairos.squashfs into ./out. Feed those files into your existing server.
If you don't have a netboot server yet, AuroraBoot can be one. The start-pixie subcommand runs Pixiecore directly against the artifacts above:
docker run --rm --net host -v $PWD:/work quay.io/kairos/auroraboot \
start-pixie /work/cloud-config.yaml /work/out/kairos.squashfs 0.0.0.0 8090 \
/work/out/kairos-initrd /work/out/kairos-kernel
Pixiecore acts as a ProxyDHCP server, so it integrates with whatever DHCP server is already on the network — target machines configured to PXE-boot will pick up the kernel and initrd served on the address and port you passed.