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.
——-
[[[TOC]]]
——-
= Install Server Dependencies =
# 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 =
# 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}}
}}}
# Copy the PXE boot file to the PXE root.
{{{
sudo cp /usr/lib/syslinux/pxelinux.0 /pxe-boot
}}}
# 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
}}}
# Sync exports
{{{
sudo exportfs -rv
}}}
# 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
}}}
# Chroot to the image directory.
{{{
sudo chroot /pxe-boot/images/base-cluster-image/
}}}
# Setup the hostname (replace `base-cluster-image` with your desired hostname)
{{{
echo base-cluster-image > /etc/hostname
}}}
# 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
}}}
# 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
}}}
# 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
}}}
# Add network adapter names to `/etc/initramfs-tools/modules` (such as ar8121, r8169, etc. - one per line)
# Mount `/proc`.
{{{
mount /proc
}}}
# Set the root password.
{{{
passwd
Enter new UNIX password:
Retype new UNIX password:
}}}
# Generate/update locale settings.
{{{
locale-gen en_US.UTF-8
dpkg-reconfigure locales
}}}
# 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
}}}
# Update app cache
{{{
apt-get update
}}}
# Install system kernel
{{{
apt-get install -y linux-headers-generic
apt-get install -y linux-image-generic
}}}
# 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..
}}}
# Edit initramfs.conf `nano /etc/initramfs-tools/initramfs.conf` and make the following options match
{{{
MODULES = netboot
BOOT = nfs
}}}
# Update initramfs with new params `update-initramfs -u`
# Install any source packages your image needs (or any you did not have in the debootstrap --include)
# Exit chroot
{{{
umount /proc
exit
}}}
-------
=TFTP=
# Open the config file.
{{{
sudo nano /etc/default/tftpd-hpa
}}}
# 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/"
}}}
# 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
}}}
## [[https://help.ubuntu.com/community/PXEInstallMultiDistro#Putting_it_All_Together|Follow this for pxe menu setups]]
## [[http://www.syslinux.org/wiki/index.php/PXELINUX#How_do_I_Configure_PXELINUX.3F|Or, you can serve a different pxe config file per system]]
# Permissions `sudo chmod 777 /pxe-boot`
# Start tftp server `sudo /etc/init.d/tftpd-hpa start`
# 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==
# Edit config `sudo nano /etc/default/isc-dhcp-server` to listen on specific interfaces (space separate). Configure everything else to your liking
{{{
INTERFACES="bond0"
}}}
# 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
}
}}}
# Restart DHCP server `sudo service isc-dhcp-server restart`
==Ubiquiti EdgeRouter Lite==
# Login to router via ssh, enter configure more
{{{ lang=bash
configure
}}}
# Add `bootfile-server` to DHCP config
{{{ lang=bash
edit service dhcp-server shared-network-name dlasley.net subnet 192.168.69.0/24
set bootfile-server 192.168.69.100
}}}
# Add `filename` options to DHCP config. **Make sure to encapsulate the file path in `"`**
{{{ lang=bash
set subnet-parameters "filename "/pxe-boot/pxelinux.0";"
}}}
# Commit and save
{{{ lang=bash
commit
save
}}}
-------
= Storing/Deploying Images (Optional)=
# Compress base image for storage
{{{
tar cvpjf base-cluster-image.tar.bz2 ./base-cluster-image
rm -Rf ./base-cluster-image
}}}
# Extract base image
{{{
tar xvpfj ./base-cluster-image.tar.bz2 -C ./
}}}
# Rename folder
{{{
mv ./base-cluster-image ./cluster-0
}}}
# Setup the hostname (replace `base-cluster-image` with your hostname)
{{{
echo cluster-0 > ./cluster-0/etc/hostname
}}}
# 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) =
# Setup BIOS to boot from NIC
# Client should get net config from DHCP server, download pxe file from TFTP server, then begin booting
## 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
# 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
}}}
# Run top to verify that you have swap space.
{{{
KiB Swap: 2097148 total, 0 used, 2097148 free, 1462084 cached
}}}
# 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
# Umount the drive
{{{
sudo umount /media/mounted_swap
}}}
# Find the device with fdisk. For the purposes of this article, I will be using /dev/sdc1
{{{
sudo fdisk -l
}}}
# Write the swap file to the device
{{{
sudo mkswap /dev/sdc1
}}}
# Activate the swap device.
{{{
sudo swapon –p 32767 /dev/sdc1
}}}
# Run top to verify that you have swap space.
{{{
KiB Swap: 2097148 total, 0 used, 2097148 free, 1462084 cached
}}}
# Make the change permanent.
{{{
sudo nano /etc/fstab
}}}
{{{
/dev/sdc1 none swap sw 0 0 #< Add this
}}}
-------
= Credits =
* [[https://help.ubuntu.com/community/PXEInstallMultiDistro|PXEInstallMultiDistro]]
* [[https://help.ubuntu.com/community/DisklessUbuntuHowto|DisklessUbuntuHowTo]]
* [[https://help.ubuntu.com/community/PXEInstallServer|PXEInstallServer]]
* [[https://help.ubuntu.com/community/Installation/OnNFSDrive|OnNFSDrive]]
* [[http://www.syslinux.org/wiki/index.php/PXELINUX|PXE Linux]]
* Various manpages ;)
Leave a Reply to John Cancel reply