Ramroot is a lightweight solution for live-booting Ubuntu or Debian over HTTP, similar to how NFS roots are supported. It is implemented as a plugin to the standard Ubuntu initrd images.
Possible use cases include, but are not limited to:
- Rescue images
- Automated maintenance tasks (firmware upgrades, etc)
- Souped-up bootloader using kexec
The main advantage of using Ramroot over NFS-based live booting is that you don't need an NFS server. NFS can be tricky to make reliable at scale, but if scale is an issue you probably already have scalable infrastructure for serving HTTP.
Ramroot has the following dependencies:
- Ubuntu or Debian for creating the initrd and root image (a Docker image will do)
- pixz for compressing/uncompressing the image
To install Ramroot, simply copy the initramfs-tools
folder into
/etc/initramfs-tools
in an Ubuntu or Debian system. Whenever you install a
new kernel, Ramroot will be included in the initrd image. To regenerate the
initrd of an already installed kernel in order to include Ramroot, use
update-initramfs
.
The Ramroot image itself can be generated using whatever tools you prefer, as long as the output is an xzipped tarball of the root filesystem stored in a file ending with .tar.xz. We have included instructions on how to create both the kernel/initrd images and the ramroot filesystem using Docker.
When configuring your PXE boot, configure it as you normally would, except you skip creating the nfs share and replace
boot=casper netboot=nfs nfsroot=server:/path
with
boot=ramdisk ramroot=http://your.server/ramroot.tar.xz
in the kernel parameters.
We recommend using a PXE solution capable of transferring the kernel and initrd over HTTP, such as iPXE or lpxelinux. Using HTTP instead of TFTP for transferring the initrd is significantly faster.
You may also want to configure your PXE solution to provide the mac address of
the NIC you booted from in the BOOTIF
kernel parameter. This will allow
the gen_network_interfaces script
to configure the linux system to use the same NIC you booted from. This allows
networking to work smootly both during and after booting.
See Dockerfile.kernel-example for an example Dockerfile for generating an initrd image.
To generate the initrd and extract it from the docker image, you can use or adapt the following commands:
# Build the Docker image
docker build -f Dockerfile.kernel-example -t ramroot-kernel .
# Extract the kernel and initrd
docker run --rm -v $PWD:/host ramroot-kernel bash -c 'cp -v /boot/initrd.img-* /boot/vmlinuz-* /host'
You will now find a kernel image (vmlinuz-*
) and an initrd image
(initrd.img-*
) in the current working directory.
You can customize the Dockerfile if you need more included in your initrd.
To create a Ramroot image using Docker, simply create a docker image and convert it using docker-to-ramroot in the tools folder. See Dockerfile.ramroot-example for a bare-bones image based on the official ubuntu:16.04 image:
# Build the Docker image
docker build -f Dockerfile.ramroot-example -t ramroot .
# Convert the Docker image to a ramroot
tools/docker-to-ramroot ramroot ramroot.tar.xz
Notice how this image does not need to include the kernel and modules. This allows you to upgrade the ramroot and the kernel independently, and also makes the image smaller.
Ramroot supports the same hooks a standard Ubuntu initrd does. To run custom
scripts in the end of the initrd execution, add them to
/etc/initramfs-tools/scripts/ramdisk-bottom
. A few scripts for kernel and
network configuration are already provided.
Ramroot is released under the MIT licence.