Ubuntu PXE boot with NFS root

From Wiki
Jump to: navigation, search

How did I end up in this ridiculous situation? I have an old Dell desktop which serves as my MythTV backend. The hard disk failed and I wanted to get it going again without going to the shops because they are full of the great unwashed due to Christmas shopping. So, at my disposal, I have:

  • A Dell desktop with no disks and no optical drive
  • A FreeNAS server offering NFS
  • A TFTP server running Debian Linux
  • A pfSense firewall
  • A MacBook Air
  • An 8GB USB flash drive

Unfortunately it does not seem to be possible to jump straight to the eventual solution, mainly because the Ubuntu installer does not cater for those of us who wish to use NFS for the root filesystem. So it's necessary to start with an intermediate step of having a running Ubuntu system and converting that to a diskless system.

Ubuntu installed on USB

The first step is to get the net installer for Ubuntu and make it available on your TFTP server. This can be accomplished by doing

$ wget -r --no-parent http://archive.ubuntu.com/ubuntu/dists/trusty/main/installer-i386/current/images/netboot/

...or the appropriate URL for your architecture

Then, configure the DHCP server to point to the TFTP server and specify pxelinux.0 as the file to boot from.

It should now be possible to PXE boot your diskless system and install Ubuntu to the USB drive in the usual way. Once you've got a basic install of Ubuntu it's time to convert it to a diskless system.


Add an NFS share with all users mapped to user 'root' and group 'wheel'. That's really it. Any NFS server ought to do, it doesn't have to be FreeNAS obviously.

Convert from local disk to NFS

It's necessary to rebuild the kernel with the correct modules needed for an NFS boot:

Change the BOOT flag to nfs in /etc/initramfs-tools/initramfs.conf

# BOOT: [ local | nfs ]
# local - Boot off of local media (harddrive, USB stick).
# nfs - Boot using an NFS drive as the root of the drive.


Change the MODULES flag to netboot in /etc/initramfs-tools/initramfs.conf

# MODULES: [ most | netboot | dep | list ]
# most - Add all framebuffer, acpi, filesystem, and harddrive drivers.
# dep - Try and guess which modules to load.
# netboot - Add the base modules, network modules, but skip block devices.
# list - Only include modules from the 'additional modules' list


Run mkinitramfs

$ mkinitramfs -o ~/initrd.img-`uname -r`

Copy your kernel from /boot/vmlinuz-`uname -r` and doctored initrd from ~/initrd.img-`uname -r` to your TFTP server, wherever that may be. Install syslinux

$ sudo apt-get install syslinux

In order to boot the normal kernel rather than the installer kernel, it's necessary to replace pxelinux.0. To do this, copy /usr/lib/syslinux/pxelinux.0 over to your TFTP server overwriting the old one.

You must also replace the configuration for PXE, pxelinux.cfg/default

label linux
kernel vmlinuz-3.13.0-43-generic
append root=/dev/nfs initrd=initrd.img-3.13.0-43-generic nfsroot= ip=dhcp rw
default linux

...or similar.

There's still a few things to tidy up.

Edit /etc/network/interfaces, we have already obtained a DHCP lease when we booted, so there is no need to do it again:

iface eth0 inet manual

In fstab, disable swap and move the root filesystem to NFS:

proc            /proc           proc    defaults        0       0
/dev/nfs        /               nfs     defaults        1       1
none            /tmp            tmpfs   defaults        0       0
none            /var/run        tmpfs   defaults        0       0
none            /var/lock       tmpfs   defaults        0       0
none            /var/tmp        tmpfs   defaults        0       0

Comment out exec update-grub in /etc/kernel/postinst.d/zz-update-grub – we will not be using GRUB anymore because we have no disks!

At long last, install nfs-client and mount the NFS share on /mnt

$ sudo apt-get install nfs-client
$ sudo mount /mnt

Use rsync to duplicate the root filesystem

$ sudo apt-get install rsync
$ sudo rsync -av --exclude=/dev --exclude=/sys --exclude=/proc --exclude=/mnt /* /mnt/ ; mkdir /mnt/dev ; mkdir /mnt/proc ; mkdir /mnt/sys

That should be it. Reboot, pull out the USB flash drive, and it should PXE boot the new kernel.