You are viewing the development docs which are in progress. For the latest stable documentation, click here.
Creating Custom Cloud Images
This guide provides a complete walkthrough for creating custom cloud images with Kairos. It covers the entire process from start to finish, using the latest tools like kairos-init
and AuroraBoot
.
Overview
Kairos provides several tools to create custom cloud images:
- kairos-init: A tool for creating base container images
- AuroraBoot: A tool for generating bootable images (ISOs, cloud images, etc.)
- Customization tools: Various methods to customize the images
Prerequisites
Before starting, ensure you have:
- Docker installed and running
- A Linux machine with KVM support (for testing)
- Basic understanding of container images and cloud configurations
Step 1: Creating a Base Image with kairos-init
The first step is to create a base container image using kairos-init
. This tool allows you to create a custom base image from popular distributions.
Here’s a basic example of creating a base image:
docker build -t my-custom-image - <<EOF
ARG BASE_IMAGE=ubuntu:24.04
FROM quay.io/kairos/kairos-init:v0.4.4 AS kairos-init
FROM ${BASE_IMAGE} AS base-kairos
ARG VARIANT=core
ARG MODEL=generic
ARG TRUSTED_BOOT=false
ARG KUBERNETES_DISTRO=k3s
ARG KUBERNETES_VERSION=latest
ARG FRAMEWORK_VERSION=v2.20.0
ARG VERSION
COPY --from=kairos-init /kairos-init /kairos-init
RUN /kairos-init -f "${FRAMEWORK_VERSION}" -l debug -s install -m "${MODEL}" -v "${VARIANT}" -t "${TRUSTED_BOOT}" -k "${KUBERNETES_DISTRO}" --k8sversion "${KUBERNETES_VERSION}" --version "${VERSION}"
RUN /kairos-init -f "${FRAMEWORK_VERSION}" -l debug -s init -m "${MODEL}" -v "${VARIANT}" -t "${TRUSTED_BOOT}" -k "${KUBERNETES_DISTRO}" --k8sversion "${KUBERNETES_VERSION}" --version "${VERSION}"
RUN /kairos-init -f "${FRAMEWORK_VERSION}" -l debug --validate -m "${MODEL}" -v "${VARIANT}" -t "${TRUSTED_BOOT}" -k "${KUBERNETES_DISTRO}" --k8sversion "${KUBERNETES_VERSION}" --version "${VERSION}"
RUN rm /kairos-init
EOF
Step 2: Customizing the Image
Once you have a base image, you can customize it by:
- Adding packages
- Modifying configurations
- Adding custom services
- Including additional files
See the Customizing Images guide for detailed instructions.
Step 3: Building Bootable Images with AuroraBoot
After creating and customizing your base image, you can use AuroraBoot to create bootable images:
docker run -v "$PWD"/build:/tmp/auroraboot \
-v /var/run/docker.sock:/var/run/docker.sock \
--rm -ti quay.io/kairos/auroraboot:v0.6.4 \
--set container_image=my-custom-image \
--set "disable_http_server=true" \
--set "disable_netboot=true" \
--cloud-config /path/to/cloud-config.yaml \
--set "state_dir=/tmp/auroraboot"
Note
For more details about AuroraBoot options and configurations, see the AuroraBoot documentation.State Partition Sizing
When creating cloud images, it’s important to consider the size of the state partition. The state partition is created at image build time and cannot be resized later. This partition needs to accommodate all images (passive, active, and transition image for upgrades) that might be used with the system.
By default, AuroraBoot sets the state partition size to 3 times the size of the current image plus some additional space for system files. This is usually sufficient for most use cases, but if you need to ensure the state partition can accommodate larger future images, you can override this with the disk.state_size
option:
docker run -v "$PWD"/build:/tmp/auroraboot \
-v /var/run/docker.sock:/var/run/docker.sock \
--rm -ti quay.io/kairos/auroraboot \
--set container_image=my-custom-image \
--set "disable_http_server=true" \
--set "disable_netboot=true" \
--set "disk.state_size=6000" \
--cloud-config /path/to/cloud-config.yaml \
--set "state_dir=/tmp/auroraboot"
The value is specified in megabytes (MB). When setting a custom size, make sure it’s at least 3 times the size of the largest image you plan to use, plus some additional space for system files. This ensures there’s enough space for the passive, active, and transition images, plus some overhead for future updates.
Step 4: Cloud Configuration
Your cloud configuration file (cloud-config.yaml
) is crucial for defining how your image will behave. Here’s a basic example:
#cloud-config
hostname: kairos-{{ trunc 4 .MachineID }}
users:
- name: "kairos"
passwd: kairos
groups:
- admin
reset:
system:
uri: "quay.io/kairos/opensuse:leap-15.6-standard-amd64-generic-master-k3sv1.32.1-rc2-k3s1"
In the example above, we are specifying a custom image that will be used during the first boot to reset the system. When you launch an instance, Kairos will boot into “auto-reset mode” by default. This means that Kairos will “install” itself on the first boot and then reboot. The reset.system.uri
field in the cloud-config specifies which image will be installed during this process.
As explained in the section above, sizing the state partition properly is important when using this option.
Step 5: Building for Specific Platforms
AWS
To install on AWS, follow the AWS Guide.
Google Cloud
To install on Google Cloud, follow the Google Cloud Installation Guide.
Microsoft Azure
For Azure deployments, see the Azure Installation Guide.
Troubleshooting
Common issues and solutions:
- Disk Size: Ensure your VM disk is large enough for all partitions. If there isn’t enough space, the auro-reset will fail and the VM will never boot into
active_boot
mode. - State Partition Size: If you encounter issues when resetting to a new image, it might be because the state partition is too small. Use the
disk.state_size
option when creating the image to set an appropriate size.