In this tutorial, I will guide you through the process of creating a PXE server on an Ubuntu Host. This guide also includes complete setup instructions for the PXE client and DHCP server. I will also guide you through an effective storage/deployment method so that you may quickly deploy identical PXE images.



Install Server Dependencies

  1. Update & clean current packages, then install the packages that are required for this tutorial.
    sudo apt-get update -y && sudo apt-get dist-upgrade -y &&
    sudo apt-get install -y isc-dhcp-server tftpd-hpa syslinux         \
                            syslinux nfs-kernel-server initramfs-tools \
                            debootstrap syslinux

Setup NFS root

  1. Create desired directory structure. In my configuration, the pxe directory is in the root and I store all of my pxe images in pxe-boot/images/*.

    sudo mkdir -p /pxe-boot/{pxelinux.cfg,images/{base-cluster-image}}

  2. Copy the PXE boot file to the PXE root.

    sudo cp /usr/lib/syslinux/pxelinux.0 /pxe-boot

  3. Share new directory via NFS

    sudo nano /etc/exports
    /pxe-boot             192.168.69.100(rw,no_root_squash,async,insecure)  #< You will want to modify the IP

  4. Sync exports

    sudo exportfs -rv

  5. Download base system via debootstrap to pxe-boot/images/base-cluster-image. Add desired packages to the include parameter. This will take a while..you can continue with the other sections in another screen session if you want to save time. You can also change the arch or distribution (quantal) to fit your desired setup.

    sudo debootstrap --variant=minbase --include=procps,screen,passwd,less,nano,bash,nfs-common \
      --arch amd64 quantal /pxe-boot/images/base-cluster-image http://archive.ubuntu.com/ubuntu

  6. Chroot to the image directory.

    sudo chroot /pxe-boot/images/base-cluster-image/

  7. Setup the hostname (replace base-cluster-image with your desired hostname)

    echo base-cluster-image > /etc/hostname

  8. Setup the hosts file.

    nano /etc/hosts
    127.0.0.1       localhost
    127.0.1.1       base-cluster-image  #< (replace `base-cluster-image` with your desired hostname)
    # The following lines are desirable for IPv6 capable hosts
    ::1     ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters

  9. Setup the fstab. It should look similar to the below (adding other mounts if necessary)

    nano /etc/fstab
    /proc    /proc    proc    defaults   0 0
    /sys     /sys     sysfs   defaults   0 0
    /dev/nfs /        nfs     defaults   1 1

  10. Setup interfaces (client already discovered DHCP during boot process, so the interface needs to be set to manual).

    nano /etc/network/interfaces`
    # Loopback
    auto lo
    iface lo inet loopback
    
    # Don't discover DHCP
    iface eth0 inet manual

  11. Add network adapter names to /etc/initramfs-tools/modules (such as ar8121, r8169, etc. – one per line)

  12. Mount /proc.

    mount /proc

  13. Set the root password.

    passwd
    Enter new UNIX password:
    Retype new UNIX password:

  14. Generate/update locale settings.

    locale-gen en_US.UTF-8
    dpkg-reconfigure locales

  15. Edit sources nano /etc/apt/sources.list and add:

    deb http://archive.ubuntu.com/ubuntu quantal main restricted universe multiverse
    deb http://archive.ubuntu.com/ubuntu quantal-updates main restricted universe multiverse
    deb http://archive.ubuntu.com/ubuntu quantal-security main restricted universe multiverse

  16. Update app cache
    apt-get update
  17. Install system kernel

    apt-get install -y linux-headers-generic 
    apt-get install -y linux-image-generic

  18. Link kernel to a better spot and set permissions. This will allow you to upgrade kernels without changing configuration files.

    ln -s /boot/vmlinuz-3.5.0-21-generic /vmlinuz         #< Substitute for your kernel version
    ln -s /boot/initrd.img-3.5.0-21-generic /initrd.img  #< Substitute for your kernel version
    chmod 777 -R  /vmlinuz /initrd.img /boot/          #< /boot could probably be left out of this..

  19. Edit initramfs.conf nano /etc/initramfs-tools/initramfs.conf and make the following options match

    MODULES = netboot 
    BOOT    = nfs

  20. Update initramfs with new params update-initramfs -u

  21. Install any source packages your image needs (or any you did not have in the debootstrap –include)

  22. Exit chroot
    umount /proc
    exit

TFTP

  1. Open the config file.
    sudo nano /etc/default/tftpd-hpa
  2. Make it look like the below (replace TFTP_DIRECTORY with PXE root)

    # /etc/default/tftpd-hpa
    
    RUN_DAEMON="yes"
    OPTIONS="--secure"
    TFTP_ADDRESS="0.0.0.0:69"
    TFTP_USERNAME="tftp"
    TFTP_DIRECTORY="/pxe-boot/"

  3. Create default boot config

    DEFAULT images/base-cluster-image/vmlinuz
    APPEND boot=nfs root=/dev/nfs initrd=images/base-cluster-image/initrd.img nfsroot=192.168.69.100:/pxe-boot/images/base-cluster-image,rw ip=dhcp rw

    1. Follow this for pxe menu setups
    2. Or, you can serve a different pxe config file per system

  4. Permissions sudo chmod 777 /pxe-boot

  5. Start tftp server sudo /etc/init.d/tftpd-hpa start

  6. Verify server is listening
    dlasley@server:/$ ss -apu | grep tftp
    UNCONN  0  0  *:tftp  *:*

DHCPD

Note that the below configurations are redundant, and should be chosen depending on your environment. Windows users would use the GUI.

Linux

  1. Edit config sudo nano /etc/default/isc-dhcp-server to listen on specific interfaces (space separate). Configure everything else to your liking

    INTERFACES="bond0"

  2. Edit dhcpd.conf sudo nano /etc/dhcp/dhcpd.conf. Mine is below (minus unrelated static clients), edit for your config (IPs, hostnames, MACs, etc.)

    ddns-update-style none;
    option subnet-mask 255.255.255.0;
    option broadcast-address 192.168.69.255;
    option routers 192.168.69.254;
    option domain-name-servers 192.168.69.110, 192.168.69.100, 192.168.69.254;
    option domain-name "dlasley.net";
    
    default-lease-time 86400;
    max-lease-time 604800;
    #option time-offset -18000;
    authoritative;
    log-facility local7;
    
    allow booting;
    allow bootp;
    
    #       Reserve >100 for static
    subnet 192.168.69.0 netmask 255.255.255.0 {
     range 192.168.69.1 192.168.69.99;
    
     get-lease-hostnames on;
     use-host-decl-names on;
    
     next-server 192.168.69.100;
     filename "/pxe-boot/pxelinux.0";
    }
    
    host cluster_1 {
     hardware ethernet      00:21:97:32:D6:B5;
     fixed-address          192.168.69.103;
     #filename               "/pxe-boot/pxelinux.0";  #< Can also define on a 
     #next-server            192.168.69.104;          #  client-by-client basis
    }

  3. Restart DHCP server sudo service isc-dhcp-server restart

Ubiquiti EdgeRouter Lite

  1. Login to router via ssh, enter configure more
    configure
  2. Add bootfile-server to DHCP config
    edit service dhcp-server shared-network-name dlasley.net subnet 192.168.69.0/24
    set bootfile-server 192.168.69.100
  3. Add filename options to DHCP config. Make sure to encapsulate the file path in &quot;
    set subnet-parameters "filename &quot;/pxe-boot/pxelinux.0&quot;;"
  4. Commit and save
    commit
    save

Storing/Deploying Images (Optional)

  1. Compress base image for storage

    tar cvpjf base-cluster-image.tar.bz2 ./base-cluster-image
    rm -Rf ./base-cluster-image

  2. Extract base image

    tar xvpfj ./base-cluster-image.tar.bz2 -C ./

  3. Rename folder

    mv ./base-cluster-image ./cluster-0

  4. Setup the hostname (replace base-cluster-image with your hostname)

    echo cluster-0 > ./cluster-0/etc/hostname

  5. Setup hosts file nano /etc/hosts (note 127.0.1.1 is now cluster-0 instead of base-cluster-image)
    127.0.0.1       localhost
    127.0.1.1       cluster-0
    # The following lines are desirable for IPv6 capable hosts
    ::1     ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters

Booting (On The Client)

  1. Setup BIOS to boot from NIC

  2. Client should get net config from DHCP server, download pxe file from TFTP server, then begin booting

    1. If permissions issues arise, it may be acls. Try:

      sudo setfacl -bR /pxe-boot/


Add Swap Space (Optional)

You can add swap space using either a network share, or an external device (flash drive)

Network Share

This will create swap space on the network share

  1. On the booted client
    sudo apt-get install dphys-swapfile  #< Install, sets up swap at `/var/swap` that is 2x current RAM (or 2048MB per default config)
    sudo losetup /dev/loop0 /var/swap    #< Set up and control loop devices (swap)
    sudo swapon /dev/loop0               #< Enable for paging and swapping
  2. Run top to verify that you have swap space.
    KiB Swap:  2097148 total,        0 used,  2097148 free,  1462084 cached
  3. Make the change permanent.

    sudo nano /etc/fstab
    /dev/loop0  none  swap  sw  0 0  #< Add this

External Device

This will create swap space on an external device

  1. Umount the drive
    sudo umount /media/mounted_swap
  2. Find the device with fdisk. For the purposes of this article, I will be using /dev/sdc1
    sudo fdisk -l
  3. Write the swap file to the device
    sudo mkswap /dev/sdc1
  4. Activate the swap device.
    sudo swapon –p 32767 /dev/sdc1
  5. Run top to verify that you have swap space.
    KiB Swap:  2097148 total,        0 used,  2097148 free,  1462084 cached
  6. Make the change permanent.
    sudo nano /etc/fstab
    /dev/sdc1  none  swap  sw  0 0  #< Add this

Credits

0