Cloud init based
Kairos supports the standard cloud-init syntax and its own extended syntax to allow to configure a system declaratively with a cloud-config centric approach.
If you are not familiar with the concepts of cloud-init, official cloud-init is a recommended read.
Configuration persistency
Kairos is an Immutable OS and the only configuration that is persistent across reboots is the cloud-init configuration. Multiple cloud-init files can be present in the system and Kairos will read them and process them in sequence (lexicographic order) allowing to extend the configuration with additional pieces also after deployment, or to manage logical configuration pieces separately.
In Kairos the /oem
directory keeps track of all the configuration of the system and stores the configuration files. Multiple files are allowed and they are all executed during the various system stages. /usr/local/cloud-config
can be optionally used as well to store cloud config files in the persistent partition instead. /system/oem
is instead reserved to default cloud-init files that are shipped by the base OS image.
By using the standard cloud-config syntax, a subset of the functionalities are available and the settings will be executed in the boot stage.
Configuration order
When an action is done (install, upgrade, reset) several default directories in the system are read to obtain the configuration and are merged together. The directories and the order in which they are read and merged, is as shown below, from first to last. Notice that any values found in different directories will override existing ones in previous directories.
- /run/initramfs/live (Only available on LiveCD/Netboot)
- /usr/local/cloud-config
- /etc/kairos
- /etc/elemental (deprecated)
- /oem
This means that you could ship an ISO with a bundled config (see Automated install or Auroraboot to see how) that adds a generic configuration that you want everywhere, and using userdata you can then overwrite the default config if needed per node/datacenter/deployment, as the useradata is read and stored into /oem
it will be read later in the process and overwrite whatever you shipped on the defaults bundled with the ISO.
In order to see the final config, you can run on a running system kairos-agent config
and that should show the final configuration after scanning all sources.
NOTE: Other than configuration (for installation/upgrade/reset/etc), in the cloud config files, you can also define “stages” to be run during boot. When the same stage is defined in more than one cloud config files, all definitions will be respected. In other words, stages won’t be overwritten.
Boot stages
During boot the stages are emitted in an event-based pattern until a system completes its boot process
The events can be used in the cloud-config extended syntax to hook into the various stages, which can allow to hook inside the different stages of a node lifecycle.
For instance, to execute something before reset is sufficient to add the following to the config file used to bootstrap a node:
name: "Run something before reset"
stages:
before-reset:
- name: "Setting"
commands:
- |
echo "Run a command before reset the node!"
Below there is a detailed list of the stages available that can be used in the cloud-init configuration files:
Stage | Description |
---|---|
rootfs | This is the earliest stage, running before switching root, just right after the root is mounted in /sysroot and before applying the immutable rootfs configuration. This stage is executed over initrd root, no chroot is applied. |
initramfs | This is still an early stage, running before switching root. Here you can apply radical changes to the booting setup of Elemental. Despite this is executed before switching root this execution runs chrooted into the target root after the immutable rootfs is set up and ready. |
boot | This stage is executed after initramfs has switched root, during the systemd bootup process. |
fs | This stage is executed when fs is mounted and is guaranteed to have access to the state and persistent partitions ( COS_STATE and COS_PERSISTENT respectively). |
network | This stage is executed when network is available |
reconcile | This stage is executed 5m after boot and periodically each 60m. |
kairos-install.pre | This stage is executed before installation of the OS starts |
kairos-uki-install.pre | This stage is executed before installation of the OS starts. Only run under Trusted Boot |
kairos-install.after | This stage is executed after installation of the OS ends |
kairos-uki-install.after | This stage is executed after installation of the OS ends. Only run under Trusted Boot |
kairos-uki-reset.pre | This stage is executed before reset. Only run under Trusted Boot |
kairos-uki-reset.after | This stage is executed after reset. Only run under Trusted Boot |
kairos-uki-upgrade.pre | This stage is executed before upgrade. Only run under Trusted Boot |
kairos-uki-upgrade.after | This stage is executed after upgrade. Only run under Trusted Boot |
before-install | This stage happens after partitioning but before the image OS is applied |
after-install-chroot | This stage happens after installing active and grub inside chroot1 |
after-install | This stage runs after active,passive and recovery images are installed and after disks have been encrypted |
before-reset | This stage happens after partitions have been formatted and mounted but before the image has been reset |
after-reset | This stage happens after partitions have been formatted and mounted and active and passive images reset |
after-reset-chroot | This stage happens after active has been reset but before passive has been touched inside chroot1 |
before-upgrade | This stage happens after mounting partitions with RW but before any image has been upgraded |
after-upgrade | This stage happens after upgrade has been done |
after-upgrade-chroot | This stage happens after the image has been upgraded inside chroot1 |
In case you’re using a standard image, with the Kairos provider, then these other stages are also available
Stage | Description |
---|---|
provider-kairos.bootstrap.before. | The provider fires this stage before starting to bootstrap K3S. |
provider-kairos.bootstrap.after. | The provider fires this stage after it finished bootstrapping K3S. |
System stages with after and before substages
The system run stages that are not part of an action (install,upgrade,reset) all have sub-stages so users can override or modify system behaviour.
This applies to rootfs
, initramfs
, boot
, fs
, reconcile
and network
stages. All of those stages will also run a suffixed after
and before
substage that users can hook into to change different setting before the main stage is run.
As those stages are run as part of the system os during different phases and some default configs are shipped with a Kairos system, we add those stages on the fly so they are easily overridable or reverted if one would not want something that ships with KAiros.
For example if we detect that we are running on a VM, we try to enable the helper services that VM vendors provide but that may conflict with a user approach of having no superfluous services running. As that config is shipped as part of the base image, its not easy to remove it unless you build a new artifact.
Instead we can revert that by having a config that disables it as soon as possible.
We know that the stage is run during boot
stage as shown in the config file so we could write the following config:
name: "Disable QEMU tools"
stages:
boot.after:
- name: "Disable QEMU"
if: |
grep -iE "qemu|kvm|Virtual Machine" /sys/class/dmi/id/product_name && \
( [ -e "/sbin/systemctl" ] || [ -e "/usr/bin/systemctl" ] || [ -e "/usr/sbin/systemctl" ] || [ -e "/usr/bin/systemctl" ] )
commands:
- systemctl stop qemu-guest-agent
Notice how we set the stage to be boot.after
. That will run immediately after the boot
stage has run, so we dont have to know where it will run and play with trying to disable it in the same stage and run into race problems, we cna just use that substage to make sure that our configs runs after the default system ones.
All the mentioned stages (rootfs
, initramfs
, boot
, fs
, reconcile
and network
) have STAGE.before
and STAGE.after
substages.
Stages during kairos-agent operations in detail
Modules
For each stage, a number of modules are available, that implement various useful functions. Read more about them in this page: Stage modules
Sentinels
When a Kairos boots it creates sentinel files in order to allow to execute cloud-init steps programmaticaly.
- /run/cos/recovery_mode is being created when booting from the recovery partition
- /run/cos/live_mode is created when booting from the LiveCD
To execute a block using the sentinel files you can specify: if: '[ -f "/run/cos/..." ]'
, for instance: