HOWTO: Netboot a Raspberry Pi

Several of our projects (£B Till Display, Watershed Signage) use a Raspberry Pi at their heart with multiple units that are nearly identical.  In order to roll-out changes to all of them at the same time, we net-boot them – essentially the entire root-filesystem resides on another server that the Pi can access via NFS.

Step 1: The NFS-server

This is the most involved part and varies a little per operating system. There are plenty of guides on setting up an NFS-server, suffice to say that I’ll assume you have /exports/pi-root exported, read-only to the IP-address or subnet that your Pi will be on — also note that you should use no_root_squash or -maproot=root:wheel as appropriate.

The first thing to do is get a root filesystem. The easiest way to do this is to use the one on the Raspbian distribution’s “Raw Images”. Under Ubuntu, I just extracted it, worked out the partition start-point, mounted it via loopback and copied it verbatim:

unzip 2013-07-26-wheezy-raspbian.zip
fdisk -lu 2013-07-26-wheezy-raspbian.img
# Start is 122880, so offset is 122880 * 512 = 62914560
losetup -o 62914560 /dev/loop0 2013-07-26-wheezy-raspbian.img
mount /dev/loop0 /mnt
cp -rp /mnt/ /exports/pi-root/
umount /mnt
losetup -d /dev/loop0

Next we need to stop the OS from obtaining a new DHCP lease. Fortunately, this is quite easy, simply edit /etc/network/interfaces and make eth0 static:

iface eth0 inet static

You’ll also want to remove/comment-out the existing entry in /etc/fstab for mounting /dev/mmcblk0p2 on /, since netbooting has provided it with a root filesystem. It’s often also a Good IdeaTM to mount /boot read-only to avoid SD-card corruption on quick, unclean reboots or power-cycling:

#/dev/mmcblk0p1		/boot		vfat	defaults						0	2
/dev/mmcblk0p1		/boot		vfat	defaults,ro						0	2
#/dev/mmcblk0p2		/		ext4	defaults,noatime					0	1
/dev/nfs		/		rootfs	defaults,ro						0	0

If you’re going to have several instances of Pis netbooting off the same image, you will want to make the NFS-export read-only. Unfortunately, many services will want to write things all over the disk — sometimes you will want to too. Fortunately, tmpfs comes to the rescue here. For example, to create /tmp using 10% of the available RAM and /var/log using 20%, add this to /etc/fstab.

tmpfs  /tmp     tmpfs  nodev,nosuid,size=10%,mode=1777  0  0
tmpfs  /var/log tmpfs  nodev,nosuid,size=20%,mode=1755  0  0

Stop the boot-sequence whinging about /tmp being read-only before /tmp is mounted:

touch /tmp/.tmpfs

Step 2: DHCP

We’re using ISC-DHCPd, so we already have an IP-pool setup. All we do here is point the specific Raspberry Pi (identified by MAC-address) at the place on NFS server that it needs to use by adding this to our server’s dhcp.conf and restarting it:

host net-booting-raspberry-pi {
	hardware ethernet b8:27:eb:XX:XX:XX;	# Change to match your Pi's MAC-address
	fixed-address A.B.C.D;			# Optionally associate a specific IP-address with the Pi
	default-lease-time 115200;		# Keep the lease around for a long while (32-hours)
 	# The magic that sets what the Pi uses as its root filesystem
	option root-path "server:/exports/pi-root,tcp,vers=3";
}

Step 3: The Raspberry Pi

This is the easiest part.  Simply add this to /boot/cmdline.txt:

ip=dhcp root=/dev/nfs nfs-options=hard,intr,ro

With all that done, any changes to the root file-system on the NFS-server are instantly propagated to all the client Pis; however, just to keep everything happy, we tend to reboot them nightly by adding a crontab entry:

30 5 * * * root /usr/sbin/reboot -dfn

Extras

Whilst developing the environment, I found it quite useful to NFS-export a duplicate of the /exports/pi-root (e.g. as /exports/pi-root-dev) to one specific Pi (via a tweaked DHCP entry) with read/write permissions; make changes like apt-get update dist-upgrade; and then copy the files back to /exports/pi-root for all the others to grab.

We’ve found that you can get a little more performance out of some setups by specifying the read- and write-sizes. We’ve added rsize=32768,wsize=32768 to the Pi’s DHCP root-path entry and tweaked the NFS-server and networking stack similarly. Again, these changes may/not help you and are operating system specific, so left as an exercise for the reader.

Update: if you want the kernel on a network too…

@barnoid writes to mention that U-Boot allows you to netboot the entire OS (although because of the Pi’s limitations, you still have to load the U-Boot code from an SD card). We haven’t played with this yet, though.

2 thoughts on “HOWTO: Netboot a Raspberry Pi

  1. Great work.

    NFS share must be similar to “/mnt/rootfs *(rw,no_root_squash)” in /etc/exports to prevent bad perms (and many services crash).
    And we can add “/dev/nfs / rootfs defaults 0 0” to /etc/fstab (a little bit cleaner)

    • Hi alexalouit,

      You’re quite right on both counts and I’ve updated the post to reflect that.

      Thanks!
      Stewart.

Comments are closed.