Custom Images
Elemental Teal images can be customized in different ways. One option is to provide additional resources within the installation media so that during installation, or eventually at boot time, additional binaries such as drivers can be included.
Another option would be to remaster the Elemental Teal by simply using a docker build. Elemental Teal is a regular container image, so it is absolutely possible to create a new image using a Dockerfile based on Elemental Teal image.
Customize installation ISO and installation process
In order to adapt the installation ISO a simple approach is to append extra configuration files into the ISO root in the same way a registration yaml configuration file is added.
Additional configuration files
Elemental Teal installation can be customized in three different, non-exclusive ways. First, including some custom Elemental client configuration file, second, by including additional cloud-init files to execute at boot time, and finally, by including installation hooks.
Custom Elemental client configuration file
Elemental client install, upgrade and reset commands can be configured with a
custom configuration file.
In order to set a custom configuration file in the installation
media the MachineRegistration resource associated with this ISO should also include
the Elemental client configuration directory. For that purpose, the install field
supports the config-dir field. See MachineRegistration reference and the example
below:
apiVersion: elemental.cattle.io/v1beta1kind: MachineRegistrationmetadata: name: my-nodes namespace: fleet-defaultspec: ... config: ... elemental: ... install: ... config-dir: "/run/initramfs/live/elemental.conf.d"Elemental Teal live ISOs, when booted, have the ISO root mounted at /run/initramfs/live.
So in that case, the ISO will contain the custom Elemental client configuration file
as /elemental.conf.d/config.yaml.
Adding additional cloud-init files at boot
In order to include additional cloud-init files during the installation they need
to be added to the installation data into the MachineRegistration resource. More specific
the config-urls field is used for this exact purpose. See MachineRegistration reference page.
config-urls is a list of string literals where each item is an http url pointing to a
cloud-init file or a local path of a cloud init file. Note the local path is evaluated at the
time of execution by the installation media, hence the local path must exist within
the installation media, commonly an ISO image.
Since in Elemental Teal live systems the ISO root is mounted at /run/initramfs/live,
the local paths for config-url in MachineRegistrations are likely to point there.
See the example below:
apiVersion: elemental.cattle.io/v1beta1kind: MachineRegistrationmetadata: name: my-nodes namespace: fleet-defaultspec: ... config: ... elemental: ... install: ... config-urls: - "/run/initramfs/live/oem/10_install_extra_drivers.yaml"In that case the ISO root is expected to include the /oem/10_install_extra_drivers.yaml file.
Installation hooks
Elemental client install, upgrade and reset procedures include three different hooks:
before-install: executed after all partition mountpoints are set.after-install-chroot: executed after deploying the OS image and before unmounting the associated loop filesystem image. Runs chrooted to the OS image.after-install: executed before unmounting partitions but after all OS images are set and unmounted.
Hooks are provided as cloud-init stages. Equivalent hooks exist for reset and upgrade procedures.
Hooks are evaluated at install,reset and upgrade processes from /oem, /system/oem and /usr/local/cloud-config, however
additional paths can be provided with the cloud-init-paths flag in Elemental client configuration.
Adding extra driver binaries into the ISO example
This example is covering the case in which extra driver binaries are included into the ISO and during the installation they are installed over the OS image.
For that use case the following files are required:
- additional binaries to install (they could be in the form of RPMs)
- additional hooks file to copy binaries into the persistent storage and to install them
- additional Elemental client configuration file to point hooks file location
Lets create an overlay directory to include the overlay root-tree that needs to be
applied over the ISO root. In that case the overlay directory could contain:
overlay/ data/ extra_drivers/ some_driver.rpm hooks/ install_hooks.yaml elemental/ config.yamlThe Elemental client config file in overlay/elemental could be as:
cloud-init-paths: - "/run/initramfs/live/hooks"This is just to let Elemental client know where to find installation hooks.
Finally, the overlay/hooks/install_hooks.yaml could be as:
name: "Install extra drivers"stages: before-install: # Preload data to the persistent storage # During installation persistent partition is mounted at /run/cos/persistent - commands: - rsync -a /run/initramfs/live/data/ /run/cos/persistent after-install-chroot: # extra_drivers folder is at `/usr/local/extra_drivers` from the OS image chroot - commands: - rpm -iv /usr/local/extra_drivers/some_driver.rpmNote the installation hooks only cover installation procedures, for upgrades equivalent
before-upgrade and/or after-upgrade-chroot should be defined.
Repacking the ISO image with extra files
Assuming an overlay folder was created in the current directory containing all
additional files to be appended, the following xorriso command adds the extra files:
xorriso -indev elemental-teal.x86_64.iso -outdev elemental-teal.custom.x86_64.iso -map overlay / -boot_image any replayFor that a xorriso equal or higher than version 1.5 is required.
Remastering a custom docker image
Since Elemental Teal image is a Docker image it can also be used as a base image in a Dockerfile in order to create a new container image.
Imagine some additional package from an extra repository is required, the following example show case how this could be added:
# The version of Elemental to modifyFROM registry.opensuse.org/isv/rancher/elemental/teal52/15.3/rancher/elemental-node-image/5.2:VERSION# Custom commandsRUN rpm --import <repo-signing-key-url> && \ zypper addrepo --refresh <repo_url> extra_repo && \ zypper install -y <extra_package># IMPORTANT: /etc/os-release is used for versioning/upgrade. The# values here should reflect the tag of the image currently being builtARG IMAGE_REPO=norepoARG IMAGE_TAG=latestRUN echo "IMAGE_REPO=${IMAGE_REPO}" > /etc/os-release && \ echo "IMAGE_TAG=${IMAGE_TAG}" >> /etc/os-release && \ echo "IMAGE=${IMAGE_REPO}:${IMAGE_TAG}" >> /etc/os-releaseWhere VERSION is the base version we want to customize.
And then the following commands
docker build --build-arg IMAGE_REPO=myrepo/custom-build \ --build-arg IMAGE_TAG=v1.1.1 \ -t myrepo/custom-build:v1.1.1 .docker push myrepo/custom-build:v1.1.1The new customized OS is available as the Docker image myrepo/custom-build:v1.1.1 and it can
be run and verified using docker with
docker run -it myrepo/custom-build:v1.1.1 bash