Ubuntu PXE boot with NFS root
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. # BOOT=nfs
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 # MODULES=netboot
$ 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,
label linux kernel vmlinuz-3.13.0-43-generic append root=/dev/nfs initrd=initrd.img-3.13.0-43-generic nfsroot=184.108.40.206:/mnt/zfs-vol-1/mythroot ip=dhcp rw default linux
There's still a few things to tidy up.
/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
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
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
$ sudo apt-get install nfs-client $ sudo mount 220.127.116.11:/mnt/zfs-vol-1/mythroot /mnt
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.