Diskless Debian, network boot

References: http://blog.tremily.us/posts/Abax/nfs_root/

  • Install pxe and the tftp server:
sudo apt-get install syslinux tftpd-hpa isc-dhcp-server nfs-kernel-server unionfs-fuse
  • Configure the dhcp server. Edit file /etc/dhcp/dhcpd.conf and edit the following lines:
option domain-name "example.loc";
option domain-name-servers dns1ip, dns2ip;
  • And add the following lines …
subnet 192.168.2.0 netmask 255.255.255.0 {
 range 192.168.2.100 192.168.2.200;
 option routers 192.168.2.1;
 option broadcast-address 192.168.2.255;
 default-lease-time 600;
 max-lease-time 7200;
}

host diskless_client {
   hardware ethernet mac-address;
   fixed-address 192.168.2.10;
   filename "pxelinux.0";
   next-server 192.168.2.1;
   option subnet-mask 255.255.255.0;
   option broadcast-address 192.168.2.255;
   option routers 192.168.2.1;
}
  • Restart dhcp server:
sudo /etc/init.d/isc-dhcp-server restart
  • Configure the tftp files for network boot:
sudo cp /usr/lib/syslinux/pxelinux.0 /srv/tftp/
sudo mkdir pxelinux.cfg
cd /srv/tftp/pxelinux.cfg/

* Create and edit a file called diskless_client and put the following inside:
PROMPT 1
DEFAULT diskless_client
TIMEOUT 10
LABEL diskless_client
#skipping one of the dhcp steps: ip=<ip>:<server-ip>:<gateway-ip>:<netmask>::eth0:
# It is possible to use ip=:::arcoslab02:amy:eth6:dhcpi but it may be slow.
# Also, eth6 must be the card that receives DHCP answers, even when
# the trunking to the outside is not set up yet.
# It is not possible to put a name in nfsroot.

      kernel diskless_client/vmlinuz-3.2.0-3-amd64
      append boot=nfs root=/dev/nfs nfsroot=192.168.17.1:/ ip=dhcp initrd=diskless_client/initrd.img-3.2.0-3-amd64 rw rootdelay=10 vga=extended init=/etc/init.d/init_diskless_client --

#break=mount
  • Make a link to default
sudo ln -s diskless_client default
  • Copy the kernel and initrd images to the tftp directory:
sudo mkdir /srv/tftp/diskless_client/
sudo cp /boot/vmlinuz-3.2.0-3-amd64 /srv/tftp/diskless_client/
sudo cp /boot/initrd.img-3.2.0-3-amd64 /srv/tftp/diskless_client/
  • Create a directory and some files for the system files that will be different on the diskless_client computer. This will later be mounted on the diskless_client on top of the root filesystem using unionfs.
sudo mkdir /unionfsfstab
sudo mkdir -p /unionfs/common/etc
sudo mkdir -p /unionfs/common/var
sudo mkdir -p /unionfs/host
sudo mkdir -p /unionfs/hosts/diskless_client/etc/apache2/sites-enabled
sudo mkdir -p /unionfs/hosts/diskless_client/etc/dhcp/fstab
sudo mkdir -p /unionfs/hosts/diskless_client/etc/init.d/
sudo mkdir -p /unionfs/hosts/diskless_client/etc/network
sudo mkdir -p /unionfs/hosts/diskless_client/etc/rc2.d/
sudo mkdir -p /unionfs/hosts/diskless_client/etc/rc6.d/
sudo mkdir -p /unionfs/hosts/diskless_client/etc/rcS.d/
sudo mkdir -p /unionfs/hosts/diskless_client/var
sudo mkdir -p /unionfs/union/etc
sudo mkdir -p /unionfs/union/var
sudo touch /unionfs/common/etc/README
sudo touch /unionfs/common/var/README
sudo touch /unionfs/host/README
sudo touch /unionfs/hosts/diskless_client/etc/README
sudo touch /unionfs/union/etc/README
sudo touch /unionfs/union/var/README
sudo touch /unionfs/hosts/diskless_client/etc/apache2/sites-enabled/000-default
sudo touch /unionfs/hosts/diskless_client/etc/apache2/sites-enabled/default-ssl
sudo touch /unionfs/hosts/diskless_client/etc/apache2/sites-enabled/dokuwiki
sudo touch /unionfs/hosts/diskless_client/etc/apache2/sites-enabled/homes
sudo touch /unionfs/hosts/diskless_client/etc/exports
sudo touch /unionfs/hosts/diskless_client/etc/init.d/apache2
sudo touch /unionfs/hosts/diskless_client/etc/init.d/isc-dhcp-server
sudo touch /unionfs/hosts/diskless_client/etc/init.d/nfs-kernel-server
sudo touch /unionfs/hosts/diskless_client/etc/init.d/tftp-hpa
sudo touch /unionfs/hosts/diskless_client/etc/rc6.d/K03sendsigs
  • Also edit some of the following files with:

/unionfs/hosts/diskless_client/etc/fstab

192.168.2.1:/root     /root    nfs     rw,nfsvers=3,hard,intr,bg,timeo=600,nolock,rsize=32768,wsize=32768,noatime      0       0
192.168.2.1:/home     /home    nfs     rw,nfsvers=3,hard,intr,bg,timeo=600,nolock,rsize=32768,wsize=32768,noatime      0       0
tmpfs                  /tmp     tmpfs   defaults        0       0
/unionfs/union/etc     /etc     none    ro,bind         0       0

/unionfs/hosts/diskless_client/etc/hostname

arcoslab02

/unionfs/hosts/diskless_client/etc/hosts

127.0.0.1 localhost
127.0.1.1 example2.com example2

/unionfs/hosts/diskless_client/etc/network/interfaces

auto lo 
iface lo inet loopback

/unionfs/hosts/diskless_client/etc/syslog.conf

#send everything to diskless_server
*.*;local4.!* /var/log/messages
*.*;local4.!* @diskless_server_ip
local4.*      /var/log/ipmi
  • Export root file system as read-only (to avoid damage by the other computer) and others as read-write using nfs:
#diskless_client
/    192.168.2.23(ro,insecure,async,no_subtree_check,no_root_squash,insecure_locks)
/root   192.168.2.23(rw,insecure,async,no_subtree_check,no_root_squash,insecure_locks)
/home   192.168.2.23(rw,insecure,async,no_subtree_check,no_root_squash,insecure_locks)
/unionfs        192.168.2.23(rw,insecure,async,no_subtree_check,no_root_squash,insecure_locks)
  • In the server computer create a file called /etc/init_diskless_client with :
#!/bin/sh -x
NFS_SERV="192.168.2.1"
NFS_OPT="-otcp,nfsvers=3,hard,intr,bg,timeo=600,nolock,rsize=32768,wsize=32768"

FUSE_OPT="-o default_permissions -o allow_other -o use_ino -o nonempty -o suid"
UNION_OPT="-o cow -o noinitgroups"

UPATH="/unionfs"
UBIN="/usr/bin/unionfs-fuse"

ulimit -n 16384

#This tmpfs is needed, because mount and others need a temporary place to write
#consider changing this to a permanent place over NFS?  Could fill RAM
mount -n -t tmpfs tmpfs /tmp

ifconfig lo 127.0.0.1

#specific directory
mount -n -t nfs $NFS_OPT ${NFS_SERV}:${UPATH}/hosts/diskless_client ${UPATH}/host

#function to combine a directory from the read-only root directory (/),
#with a specific unionfs for this host that is writable
unionmount()
{
      dir=$1
      mkdir -p ${UPATH}/host/$dir  #if not existant, create dir
      mount -n --bind /$dir $UPATH/common/$dir  #mount the original read-only dir to common
      host="${UPATH}/host/${dir}=RW"
      common="$UPATH/common/${dir}=RO"
      #combine the two directories into a unionfs
      $UBIN $FUSE_OPT $UNION_OPT ${host}:${common} $UPATH/union/$dir
      #replace the mount in /$dir with the newly created combination
      mount -n --bind $UPATH/union/$dir /$dir
}

#same as the previous function, just make the directory read-only at the end
unionmount_ro()
{
      dir=$1
      unionmount $dir
      mount -n -o remount,ro /$dir
}

#which directories will get the overlay of the unionfs:
unionmount etc
cat /proc/mounts > /etc/mtab
mount -n -o remount,ro $UPATH/union/etc
mount -n -o remount,ro /etc

#sleep 4                                                                        

unionmount var

mount -t nfs -a
#/etc/init.d/chrony start                                                       
/etc/init.d/ssh start

#exec /bin/bash                                                                 
exec /sbin/init
  • Change permissions of this file to executable:
sudo chmod +x /etc/init.d/diskless_client
Enter your comment. Wiki syntax is allowed:
If you can't read the letters on the image, download this .wav file to get them read to you.
 
  • tutorials/diskless_debian_network_boot.txt
  • Last modified: 2016/02/26 11:52
  • by amora