Preface

Several weeks of testing Netboot for Raspberry Pi with /boot and root (/) on NFS went fine until I hit a problem with home-assistant due to container didn’t want to start at all with strange message failed to reserve container name is reserved for.

I knew that there is iSCSI feature on my Synology, but I never tried it before. So the time has come to try.

Plan was quite simple - partially to use what already was done with PXE and booting from TFTP, but now root (/) should be on iSCSI disks, not on NFS mount as before, /boot can be still left on NFS mount.

After reading several good articles (all of them are left at the end) I’ve understood that in addition to what was done initrd has to be recompiled with iscsi modules as by default they are not there so OS won’t start without it from iscsi disk.

Plan

So at the end I’ve got the following release plan:

  • Configure the DHCP service on your router (the same as Netboot for Raspberry Pi with /boot and root (/) on NFS)
  • Configure the NFS and TFTP services on your NAS (only /boot will be on NFS now)
  • Configure iSCSI and test it (on storage and RPi ends)
  • Recompile initrd with iscsi modules on RPi
  • Copy /boot to NFS and update boot configuration for iSCSI
  • Copy / to iSCSI disk

NFS/TFTP service

On NAS rpi-tftpboot folder should be created, /boot file systems for each RPi will be stored there.

NFS-service has to be active and RW-access should be provided for RPi-nodes to rpi-tftpboot folder.

TFTP-service has to be enabled either and rpi-tftpboot folder should be specified as TFTP root folder.

Configure iSCSI and test it

Storage

From storage side volumes (disks/LUNs) have to be created and mapped to targets (one target per each RPi server), I use 16GB volumes (one for each RPi) and simple CHAP authentication (not mutual). On examples below 192.168.8.99 is my Synology.

Server/RPi

From server side open-iscsi packet has to be installed and configured

apt-get install open-iscsi -y

In /etc/iscsi/iscsid.conf file the same authentication credentials should be specified RPi to be able to login to iSCSI server to see available LUN. Restart service after changing configuration.

# egrep -v "^#" /etc/iscsi/iscsid.conf | egrep "(node.session.auth)|node.startup"
node.startup = automatic
node.session.auth.authmethod = CHAP
node.session.auth.username = rpi1
node.session.auth.password = mysupersecurepassword

# systemctl restart iscsid.service

Now you can try to run discovery and see what is available on iscsi-server (storage)

iscsiadm -m discovery -t st -p 192.168.8.99
192.168.8.99:3260,1 iqn.2000-01.com.synology:storage.rpi1.ebab984136

Let’s try to login:

# iscsiadm   --mode node  --targetname "iqn.2000-01.com.synology:storage.rpi1.ebab984136" --portal 192.168.8.99 --login
Logging in to [iface: default, target: iqn.2000-01.com.synology:storage.rpi1.ebab984136, portal: 192.168.8.99,3260] (multiple)
Login to [iface: default, target: iqn.2000-01.com.synology:storage.rpi1.ebab984136, portal: 192.168.8.99,3260] successful.

Now we should be able to see new disk available (/dev/sda) like usual local drive:

# lsblk 
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda    8:0    0  16G  0 disk 

It can be formatted as ext4, just remember UUID of new created FS - it will be needed configuring boot later.

mkfs.ext4 /dev/sda
mkdir /mnt/iscsi
mount /dev/sda /mnt/iscsi
blkid /dev/sda
/dev/sda: UUID="de208c76-4d29-467f-b6c5-4d7c9f0e0827" TYPE="ext4"

Recompile initrd with iscsi modules on RPi

Pretty simple and fast procedure, just don’t forget to update system before to do that.

apt-get update && apt-get upgrade -y

touch /etc/iscsi/iscsi.initramfs
update-initramfs -v -k `uname -r` -c

ls -l /boot/initrd.img-5.10.17-v7l+
-rwxrwxrwx 1 1024 users 8792648 Jun 12 12:31 /boot/initrd.img-5.10.17-v7l+

Copy /boot to NFS and update boot configuration for iSCSI

The same way as it was mentioned in Netboot for Raspberry Pi with /boot and root (/) on NFS post /boot should be copied to NFS rpi-tftpboot folder, each RPi should have their own boot sub-folder there (based on RPi s/n).

vcgencmd otp_dump | grep 28: | sed s/.*://g
47102626

mkdir /mnt/boot
sudo mount 192.168.8.99:/volume1/rpi-tftpboot /mnt/boot
sudo cp -r /boot/* /mnt/boot/47102626

Add to config.txt details about what initrd should be used

cat >> /mnt/boot/47102626/config.txt
initramfs initrd.img-5.10.17-v7l+ followkernel
[Ctrl+D]

To update cmdline.txt the following details need to know, all of them should be specified instead of current details about root device:

  • root=UUID=de208c76-4d29-467f-b6c5-4d7c9f0e0827
  • ISCSI_USERNAME=rpi1
  • ISCSI_PASSWORD=mysupersecurepassword
  • ISCSI_INITIATOR=iqn.1993-08.org.debian:01:3f3ea6e86ba8 (can be taken from /etc/iscsi/initiatorname.iscsi)
  • ISCSI_TARGET_NAME=iqn.2000-01.com.synology:storage.rpi1.ebab984136
  • ISCSI_TARGET_IP=192.168.8.99
  • ISCSI_TARGET_PORT=3260
  • rootfstype=ext4

So cmdline.txt should look like that:

cat /mnt/boot/47102626/cmdline.txt
console=serial0,115200 console=tty1 ip=dhcp root=UUID=de208c76-4d29-467f-b6c5-4d7c9f0e0827 ISCSI_USERNAME=rpi1 ISCSI_PASSWORD=mysupersecurepassword ISCSI_INITIATOR=iqn.1993-08.org.debian:01:d52b48145cc ISCSI_TARGET_NAME=iqn.2000-01.com.synology:storage.rpi1.ebab984136 ISCSI_TARGET_IP=192.168.8.99 ISCSI_TARGET_PORT=3260 rw rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory

RPi 5

On RPi 5 (Raspbian OS 12 bookworm) cmdline.txt and config.txt are in /boot/firmware. Generated initrd-file has to be copied to /boot/firmware either.

If during generating of initrd the following error is returned it can be solved by editing /etc/initramfs-tools/initramfs.conf file by changing MODULES oarameter from dep to most:

mkinitramfs: failed to determine device for /
mkinitramfs: workaround is MODULES=most

grep -r MODULES /etc/initramfs-tools
/etc/initramfs-tools/initramfs.conf:# MODULES: [ most | netboot | dep | list ]
/etc/initramfs-tools/initramfs.conf:MODULES=most
/etc/initramfs-tools/initramfs.conf:#MODULES=dep

Copy / to iSCSI disk

Last step is to copy all data from current / to iscsi disk which is still mounted as /mnt/iscsi

rsync -xa --progress --exclude /mnt / /mnt/iscsi

And edit copied /etc/fstab to mount /boot from NFS and specify new /

cat > /mnt/iscsi/etc/fstab
proc            /proc           proc    defaults          0       0
192.168.8.99:/volume1/rpi-tftpboot/47102626 /boot nfs defaults,vers=3,proto=tcp 0 0
UUID=de208c76-4d29-467f-b6c5-4d7c9f0e0827	/               ext4    defaults  1       1

Reboot

After all these steps run reboot and check how it goes. System should boot via PXE, login to iSCSI server, get root disk visible and start from it as usually. After reboot you’ll see something like:

# df -h
Filesystem                                 	Size  Used Avail Use% Mounted on
udev                                       	1.8G     0  1.8G   0% /dev
tmpfs                                      	383M   17M  367M   5% /run
/dev/sda                                   	16G  5.0G  9.9G  34% /
tmpfs                                    	1.9G     0  1.9G   0% /dev/shm
tmpfs                                      	5.0M  4.0K  5.0M   1% /run/lock
tmpfs                                      	1.9G     0  1.9G   0% /sys/fs/cgroup
192.168.8.99:/volume1/rpi-tftpboot/47102626	5.5T  4.2T  1.3T  77% /boot

And now home-assistant container works as expected in K3s.