This is the result of a project to PXE-boot a diskless desktop backed by a Ceph cluster.
Initially, the plan was to use CephFS for both /
(root) and /boot
, with /boot
accessible by the PXE server to be able to streamline updates to the initrd and kernel
from the OS. While /boot
is still on CephFS, /
was moved to an RBD image, using
namespaces for permissions.
- Setting up Ceph (CephFS, RBD, permissions/auth, etc), outside of where it directly interacts with the initrd process.
- Setting up or configuring PXE
- LUKS encryption
- Ubuntu (both as build system and desktop image) - will probably work with other Debian
- CephFS and Ceph RBD image are setup, configured, and mounted on a system to be used for building
- PXE is setup (or will be setup separately)
- iPXE firmware (lots of chainloading here)
While not explicitly covered, a brief explaination of the iPXE environment I use:
- iPXE firmware (either on the NIC itself, or on a USB/SSD on the host)
- Default
boot.iPXE
(via TFTP server provided by DHCP server) that chainloads to an HTTP server using $uuid and $mac parameters - Webserver (Nginx, etc) that uses UUID and MAC parameters to server the proper iPXE boot script
- boot script loads kernel and initrd from Webserver using UUID and MAC again, and provides kernel parameters
- Webserver serves correct kernel and initrd based on UUID and MAC
- Use RBD for
/
(and one image per host) - Use CephFS for
/boot
, use the same CephFS for all hosts, so have separate directories for each host - Put the iPXE scripts on the CephFS. Don't have to be in the host directories (but could be!)
- Use namespaces to control access to the RBDs, and use fine-grained permissions
- Use permissions on the CephFS so hosts (and the PXE server) can only access their own directory
These can be anywhere, so set these variables to the actual paths to the mounted drives/partitions.
root="/mnt/root"
boot="/mnt/boot"
Example mounts:
sudo mkdir -p "${root}" "${boot}"
sudo rbd device map POOL/NAMESPACE/IMAGE --name=client.CLIENT_NAME
sudo mount /dev/rbd0 "${root}"
sudo mount -t ceph [email protected]_NAME=/ "${boot}" -o exec
(note: replace the ALL_CAPS values as needed, and make sure /etc/ceph/ceph.conf
and /etc/ceph/keyring
are setup)
sudo debootstrap --arch amd64 noble "${root}" http://archive.ubuntu.com/ubuntu
sudo mount -t proc proc "${root}/proc"
sudo mount -t sysfs sysfs "${root}/sys"
sudo mount --bind /dev "${root}/dev"
sudo mount -t devpts pts "${root}/dev/pts"
sudo mount --bind "${boot}" "${root}/boot"
sudo chroot "${root}"
Install dependencies:
apt install --no-install-recommends initramfs-tools linux-image-generic ceph-common systemd-sysv grub-pc-bin zstd vim acl cryptsetup-initramfs
(note: cryptsetup-initramfs
only needed if using LUKS)
Add the files below to their proper places (filename is unimportant):
/etc/initramfs-tools/hooks/ceph
/etc/initramfs-tools/scripts/local-top/cephboot
- Make sure to update MACs and
{{RBD_IMAGE}}
and{{CLIENT_NAME}}
at the end
- Make sure to update MACs and
Install/configure Ceph:
/etc/ceph/ceph.conf
[global]
sectionmon_host
(can't usemon_dns_srv_name
as DNS doesn't really work
/etc/ceph/ceph.conf
[client.{{ CLIENT_NAME }}]
- make sure this matches your client name!key = {{KEY}}
- this is the key for the user for Ceph
Setup /etc/fstab
. Make sure to include root and boot:
/dev/rbd0 / ext4 defaults 0 1
[email protected]_NAME=/PATH /boot ceph defaults 0 0
(note: change the /
device if using cryptsetup, and make sure the CephFS values (the ALL_CAPS
) for /boot
are correct)
(Re-)Build the initrd:
update-initramfs -v -c -k "$(ls -t /boot/vmlinuz-* | head -n 1 | sed -r 's|/boot/vmlinuz-||')"
(note: this should (re-)build the initrd for the most recently installed kernel, specify the version explicitly if needed)
Add any users or update/create passwords for users (or root, etc), install anything useful (like ssh
, ubuntu-desktop
, etc) you'll want in the booted system. Also a good time to update NetPlan config as well, though can probably be done after first boot, too (but may cause some "fun" delays in the boot process without it, but shouldn't prevent boot)
Exit the chroot (^d
or exit
)
sudo umount "${root}/proc"
sudo umount "${root}/sys"
sudo umount "${root}/dev/pts"
sudo umount "${root}/dev"
sudo umount "${root}/boot"
sudo umount "${root}"
Watch for any errors, and use -l
if needed.
Also unmap the RBD device (if you are, in fact, using that here):
sudo rbd device unmap /dev/rbd0
You don't need to unmount CephFS, though, it's okay with concurrent access (RBD WILL have issues if it is mounted in more than one system)
Update (or create!) the iPXE script for the host and double check the root=
param matches either /dev/rbd0
or the mapped cryptsetup device /dev/mapper/NAME
.