You are viewing the development docs which are in progress. For the latest stable documentation, click here.

Bundles

Bundles are a powerful feature of Kairos that let you customize and configure your operating system. This section explains how to use and build custom bundles.

Whether you need to add custom logic, install extra packages, or make other modifications to your system, bundles simplify the process. They can be applied after installation or before bootstrapping a node.

Bundles are container images containing only files (and not full OS) that can be used to install new software or extend the cloud-init syntax. You can find community-supported bundles in the community-bundles repository.

Consuming Bundles

To use a bundle in your Kairos configuration, you will need to specify the type of bundle and the target image in your cloud-config file.

There are two points in time when the bundles may be installed:

  • Right after installation, before booting to the installed system.
  • On first boot, after booting to the installed system. If you are booting a “standard” image (the one with Kubernetes), the bundle is installed before Kubernetes starts.

The first type of installation can be used to create systemd-sysext extensions. You can read more here.

The second type of installation can be used to make changes to the installed system. E.g. create kubernetes resource files in /var/lib/rancher/k3s/server/manifests/ like longhorn community bundle does.

To apply a bundle on the first boot (and before Kubernetes starts), you can include it in your config like this:

#cloud-config bundles: - targets: - run://<image>

Replace <image> with the URL or path to the bundle image. The prefix (e.g. run://) indicates the type of bundle being used.

To install a bundle after installation instead (for bundles that are created to be used like that), use the following:

#cloud-config install: bundles: - targets: - run://<image>

Bundles have access to the Kairos cloud-config during their installation. This allows the user to add new blocks of configuration to configure the bundles.

For example, this is how metalLB community bundle can be configured:

#cloud-config hostname: kairoslab-{{ trunc 4 .MachineID }} users: - name: kairos ssh_authorized_keys: # Add your github user here! - github:mudler k3s: enable: true args: - --disable=servicelb # Specify the bundle to use bundles: - targets: - run://kairos.docker.scarf.sh/community-bundles:metallb_latest # Specify metallb settings metallb: version: 0.13.7 address_pool: 192.168.1.10-192.168.1.20

If you want the installation to stop if a bundle installation fails, you can add set the following option to true in your Kairos config:

fail_on_bundles_errors: true

If you want to install a bundle after installation has finished, you can use the kairos-agent to perform a manual installation. E.g.:

kairos-agent install-bundle run://quay.io/kairos/community-bundles:cert-manager_latest

Bundle types

Bundles can carry also binaries that can be overlayed in the rootfs, either while building images or with Live layering.

Kairos supports three types of bundles:

  • Container: This type is a bare container that simply contains files that need to be copied to the system. It is useful for copying over configuration files, scripts, or any other static content that you want to include on your system (prefixed with container: or docker:).

  • Run: This type is also a bare container, but it comes with a script that can be run during the installation phase to add custom logic. This is useful for performing any necessary setup or configuration tasks that need to be done before the cluster is fully deployed (prefixed with run:).

  • Package: This type is a luet package that will be installed in the system. It requires you to specify a luet repository in order to work. Luet packages are a powerful way to manage dependencies and install software on your system (prefixed with luet:).

You can also specify local_file: true in the bundles configuration. In that case the bundle’s URL is translated as an absolute path to an image tarball on the filesystem. This feature can be used in airgap situations, where you can pre-add bundles to the image before deployment.

For example:

install: bundles: - targets: - container:///home/kairos/mybundle.tar local_file: true

The format of the bundle tarball is the one you get when you docker save myorg/myimage or skopeo copy docker-daemon:myorg/myimage docker-archive:myimage.tar

It’s important to note that bundles do not have any special meaning in terms of immutability. They install files over paths that are mutable in the system, as they are simply overlaid during the boot process. This means that you can use bundles to make changes to your system at any time, even after it has been deployed.

Create bundles

To build your own bundle, start by creating a Dockerfile along with any required files and scripts. A bundle is essentially a container image that packages all the assets needed for a specific task.

When defining your bundle, choose a base image and copy the relevant files and scripts into it. For example, the following Dockerfile creates a bundle that deploys everything inside assets to a Kubernetes cluster:

FROM alpine COPY ./run.sh / COPY ./assets /assets

And the associated run.sh that installs the assets depending on a cloud-config keyword can be:

#!/bin/bash K3S_MANIFEST_DIR="/var/lib/rancher/k3s/server/manifests/" mkdir -p $K3S_MANIFEST_DIR # IF the user sets `example.enable` in the input cloud config, we install our assets if [ "$(kairos-agent config get example.enable | tr -d '\n')" == "true" ]; then cp -rf assets/* $K3S_MANIFEST_DIR fi

This Dockerfile creates an image based on the Alpine base image, and copies over a script file and some assets to the image. You can then add any additional instructions to the Dockerfile to install necessary packages, set environment variables, or perform any other tasks required by your bundle.

Once you have created your Dockerfile and any necessary script files, you can build your bundle image by running docker build and specifying the path to your Dockerfile.

For example:

docker build -t <image> .

This command will build an image with the name you specify ( replace <image> accordingly ) based on the instructions in your Dockerfile.

After building your bundle image, you will need to push it to a registry so that it can be accessed by Kairos. You can use a public registry like Docker Hub. To push your image to a registry, use the docker push command. For example:

docker push <image>

This will push the <image> to your specified registry.

And use it with Kairos:

#cloud-config bundles: - targets: # e.g. run://quay.io/...:tag - run://<image> example: enable: true

See the community-bundles repository for further examples.