Creating bootable images
cOS
deploymentsA derivative is a simple container image which can be processed by the cOS toolkit in order to be bootable and installable. This section describes the requirements to create a container image that can be run by cOS
.
Requirements
Bootable images are standard container images, that means the usual build
and push
workflow applies, and building images is also a way to persist oem customizations.
The base image can be any Linux distribution that is compatible with our flavors.
The image needs to ship:
- parts of the cos-toolkit (required, see below)
- kernel (required)
- initrd (required)
- grub (required)
- dracut (optional, kernel and initrd can be consumed from the cOS repositories)
- microcode (optional, not required in order to boot, but recomended)
- cosign and luet-cosign packages (optional, required if you want to verify the images installed by luet)
Example
An illustrative example can be:
ARG LUET_VERSION=0.20.6
FROM quay.io/luet/base:$LUET_VERSION AS luet
FROM opensuse/leap:15.3
ENV COSIGN_EXPERIMENTAL=1
ENV COSIGN_REPOSITORY=raccos/releases-green
ARG ARCH=amd64
ENV ARCH=${ARCH}
RUN zypper in -y \
bash-completion \
conntrack-tools \
coreutils \
curl \
device-mapper \
dosfstools \
dracut \
e2fsprogs \
findutils \
gawk \
gptfdisk \
grub2-i386-pc \
grub2-x86_64-efi \
haveged \
iproute2 \
iptables \
iputils \
issue-generator \
jq \
kernel-default \
kernel-firmware-bnx2 \
kernel-firmware-i915 \
kernel-firmware-intel \
kernel-firmware-iwlwifi \
kernel-firmware-mellanox \
kernel-firmware-network \
kernel-firmware-platform \
kernel-firmware-realtek \
less \
lsscsi \
lvm2 \
mdadm \
multipath-tools \
nano \
NetworkManager\
nfs-utils \
open-iscsi \
open-vm-tools \
parted \
pigz \
policycoreutils \
procps \
python-azure-agent \
qemu-guest-agent \
rng-tools \
rsync \
squashfs \
strace \
systemd \
systemd-sysvinit \
tar \
timezone \
vim \
which
RUN zypper cc
# Configure NetworkManager as default network management service
RUN zypper remove -y wicked
RUN systemctl disable wicked \
&& systemctl enable NetworkManager
# Copy the luet config file pointing to the upgrade repository
COPY conf/luet.yaml /etc/luet/luet.yaml
# Copy luet from the official images
COPY --from=luet /usr/bin/luet /usr/bin/luet
RUN luet install -y meta/cos-verify
RUN luet install --plugin luet-cosign -y meta/cos-minimal \
utils/k9s \
utils/nerdctl
COPY files/ /
RUN mkinitrd
With the config file:
logging:
color: false
enable_emoji: false
general:
debug: false
spinner_charset: 9
repositories:
- name: "cos"
description: "cOS official"
type: "docker"
enable: true
cached: true
priority: 1
verify: false
urls:
- "quay.io/costoolkit/releases-green"
In the example above, the cos-toolkit parts that are required are pulled in by RUN luet install -y meta/cos-minimal
.
Afterwards we install k9s and nerdctl packages to create our derivative with those packages on it.
meta/cos-minimal is a meta-package that will pull toolchain/luet , toolchain/yip , utils/installer , system/cos-setup , system/immutable-rootfs , system/base-dracut-modules , system/grub2-config , system/cloud-config .
Note
system/cloud-config is optional, but providescOS
defaults setting, like default user/password and so on. If you are not installing it directly, an equivalent cloud-config has to be provided in order to properly boot and run a system, see oem configuration.Using cosign in your derivative
The meta/cos-verify is a meta package that will pull toolchain/cosign and toolchain/luet-cosign .
toolchain/cosign and toolchain/luet-cosign are optional packages that would install cosign and luet-cosign in order to verify the packages installed by luet.
You can use cosign to both verify that packages coming from cos-toolkit are verified and sign your own derivative artifacts
Note
If you want to manually verify cosign and luet-cosign packages before installing them with luet, you can do so by:
- Install Cosign
- Export the proper vars
export COSIGN_EXPERIMENTAL=1
for keyless verifyexport COSIGN_REPOSITORY=raccos/releases-green
to point cosign to the repo the signatures are stored on
- Manually verify the signatures on both packages
- Check the latest $VERSION for both packages at the repo (i.e.
https://quay.io/repository/costoolkit/releases-green?tab=tags
) cosign verify quay.io/costoolkit/releases-green:luet-cosign-toolchain-$VERSION
cosign verify quay.io/costoolkit/releases-green:cosign-toolchain-$VERSION
- Check the latest $VERSION for both packages at the repo (i.e.
For more info, check the cosign page.
Initrd
The image should provide at least grub
, systemd
, dracut
, a kernel and an initrd. Those are the common set of packages between derivatives. See also package stack.
By default the initrd is expected to be symlinked to /boot/initrd
and the kernel to /boot/vmlinuz
, otherwise you can specify a custom path while building an iso and by customizing grub.
system/base-dracut-modules
is required to be installed with luet
in case you are building manually the initrd from the Dockerfile and also to run dracut
to build the initrd, the command might vary depending on the base distro which was chosen.
system/kernel
and
system/dracut-initrd
can also be installed if you plan to use kernels and initrd from the cOS
repositories and don’t build them / or install them from the official distro repositories (e.g. with zypper
, or dnf
or either apt-get
…). In this case you don’t need to generate initrd on your own, neither install the kernel coming from the base image.
Building
The workflow would be then:
docker build
the imagedocker push
the image to some registryelemental upgrade --no-verify --docker-image $IMAGE
from a cOS machine or (elemental reset
if bootstrapping a cloud image)
The following can be incorporated in any standard gitops workflow.
You can explore more examples in the example section on how to create bootable images.
What’s next?
Now that we have created our derivative container, we can either:
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.