how-to

Debian Stretch diskless machine via PXE boot

Inspired by this article. Sometimes I use barebone machines to test or run something, and I already have a server machine, so it’s better to use diskless PXE boot. Enjoy!

Prerequisites

To run PXE we need:

– DHCP server to serve PXE boot record

– TFTP server with PXE boot kernel

– NFS server as shared file storage for client

You can have other storage options too.

I used router with dnsmasq and client with realtek ethernet adapter.

Configure server

apt-get install tftpd-hpa syslinux pxelinux nfs-kernel-server

mkdir -p /srv/tftp /srv/nfs1
###cp -vax /srv/nfs1/boot/*.pxe /srv/tftp/ WE WILL DO THIS LATER
cp -vax /usr/lib/PXELINUX/pxelinux.o /srv/tftp/
cp -vax /usr/lib/syslinux/modules/bios/ldlinux.c32 /srv/tftp/
mkdir /srv/tftp/pxelinux.cfg

Create /srv/tftp/pxelinux.cfg/default file (if you have more than one diskless node – you may want to set different pxelinux.cfg configs instead of default one):

default Debian
prompt 1
timeout 3
label Debian
kernel vmlinuz.pxe
append rw initrd=initrd.pxe root=/dev/nfs ip=dhcp nfsroot=192.168.111.1:/srv/nfs1

Edit /etc/exports :

/srv/nfs1 192.168.111.0/24(rw,async,no_subtree_check,no_root_squash)

Reload services

systemctl restart tftpd-hpa
systemctl restart nfs-kernel-server

Create system on NFS share

Here we can install fresh system, or copy already working one.

See this article to copy system.

To install fresh one – you can use debootstrap.

Configure client to boot from NFS server

On server, edit /srv/nfs1/etc/fstab :

#192.168.111.1:/srv/nfs1 / nfs rw,noatime,nolock 1 1
/dev/nfs                 / nfs tcp,nolock 0 0
proc /proc    proc  defaults 0 0
none /tmp     tmpfs defaults 0 0
none /var/tmp tmpfs defaults 0 0
none /media   tmpfs defaults 0 0
none /var/log tmpfs defaults 0 0

Configure network, for example – edit /srv/nfs1/etc/network/interfaces :

iface eth0 inet dhcp

Add line to /srv/nfs1/etc/initramfs-tools/initramfs.conf :

BOOT=nfs

Start chroot:

mount --rbind /dev  /srv/nfs1/dev
mount --rbind /proc /srv/nfs1/proc/
mount --rbind /sys /srv/nfs1/sys/
chroot /srv/nfs1/  /bin/bash --login

Inside chroot:

If your client ethernet adapter needs kernel module to work – add it to /etc/initramfs-tools/modules , example for realtek r8169:

echo "r8169" >> /etc/initramfs-tools/modules

Generate initramfs:

mkinitramfs -d /etc/initramfs-tools -o /boot/initrd.pxe
update-initramfs -u
cp -vax /boot/initrd.img[TAB] /boot/initrd.pxe
cp -vax boot/vmlinuz[TAB] boot/vmlinuz.pxe

On server:

Copy INITRD.IMG and VMLINUZ to tftp:

cp -vax /srv/nfs1/boot/*.pxe /srv/tftp/

Congratulations, you can boot diskless machine!

There is one sidenote – you have to manually update boot kernel via

# 1) (on client) update client via it's package manager and get new kernel version
# 2) (on server) prepare and copy it into PXE boot dir 
cp -vax /srv/nfs1/boot/initrd.img[TAB] /boot/initrd.pxe
cp -vax /srv/nfs1/boot/vmlinuz[TAB] /srv/nfs1/boot/vmlinuz.pxe
cp -vax /srv/nfs1/boot/*.pxe /srv/tftp/

4 thoughts on “Debian Stretch diskless machine via PXE boot”

  1. Hello!
    Thanks for sharing this guide.

    I’m planning to setup a diskless Debian client and have some question regardin life cycle management:
    How do I upgrade the linux kernel or install new packages?
    Can I do this directly on the client and this will be stored in NFS root?
    Or must I create all these files on the server?

    THX

    1. You should do everything on client (or `chroot`ed in it’s FS while it’s offline), but to boot from freshly installed kernel you need to copy it into PXE boot dir, commands will be similar to:

      # 1) (on client) update client via it's package manager and get new kernel version
      # 2) (on server) prepare and copy it into PXE boot dir
      cp -vax /srv/nfs1/boot/initrd.img[TAB] /boot/initrd.pxe
      cp -vax /srv/nfs1/boot/vmlinuz[TAB] /srv/nfs1/boot/vmlinuz.pxe
      cp -vax /srv/nfs1/boot/*.pxe /srv/tftp/

  2. Hi, wonderful tutorial! Nevertheless, i have a question. If i have several diskless node, each one have a different hostname and several configuration detail so i need each of them to have a separate /etc. How can I do it?

    Best

    1. Glad to help!

      If you want more than one node, you should set it via additional /srv/tftp/pxelinux.cfg/ configs, for one node I just used default config. You can find an example of per-ip config here.

      So, you may set different NFS path for each node.

Leave a Reply

Your email address will not be published. Required fields are marked *