PXE Boot with Kickstart Install

From Wikidocs

Table of contents

PXE Boot Overview


WARNING! Don't place any Kickstart, PXE, or any other configuration files in the actual OS install trees. If you do, the rsync job used to keep the yum repositories up-to-date will delete them! Not that I found this out the hard way or anything. You have been warned! :)


PXE in conjunction with TFTP and DHCP provides a mechanism for bootstraping systems remotely over the network then either running in a diskless state over NFS or, more relevantly to our requirements, initialising an automated Kickstart install of linux.

When a system with a PXE enabled network card boots, assuming it's the first device in the boot sequence or that no other bootable media (floppy, cdrom, disk etc.) has been found, the device will send out a DHCP broadcast. If a correctly configured DHCP server responds with an IP address and a "next-server" instruction with a bootstrap "filename" then the client will contact that next server for that bootstrap file via TFTP.

At this stage we can utilise PXELINUX's configuration options to do a number of things.

  • For hosts which aren't specifically setup based on their IP or MAC addresses, we can present a menu allowing us to either...
    • Carry out an unattended Kickstart OS install using an install tree available via NFS, HTTP or FTP
    • Carry out an interactive, attended OS install as above
    • Boot into Rescue mode using a remotely available OS tree as above
    • Boot from an existing, bootable disk. (This is the most sensible default.)
  • If we explicitly define an entry for a host based on its IP or MAC address then we can skip the menu stage and choose one of the options listed above.

DHCP/TFTP/Kickstart Implementation

"$filestore" was our most likely candidate to be configured as the DHCP/TFTP/Kickstart server as it already has the Yum repositories (i.e. install trees) for all the distributions we currently run. DHCP, TFTP and Kickstart don't necessarily all have to run from the same central machine but it simplified implementation.


DHCP

If not already installed, install the ISC DHCP daemon package, copy the default configuration into /etc and edit to reflect current network setup.

[root@$filestore root]# yum install dhcp
[root@$filestore root]# cd /usr/share/doc/dhcp-*
[root@$filestore dhcp-3.0pl2]# cp dhcpd.conf.sample /etc/dhcpd.conf

Currently, the test config looks as follows...

# See /usr/share/doc/dhcp-$VER/dhcpd.conf &
# https://www.redhat.com/docs/manuals/enterprise/RHEL-3-Manual/sysadmin-guide/ch-dhcp.html
# for more info.

ddns-update-style interim;
ignore client-updates;
allow bootp;
allow booting;

subnet $subnetip netmask $netmask {

        option routers                  $routerip;
        option subnet-mask              $netmask;

	option domain-name-servers      $nameserverip;

        default-lease-time 21600;
        max-lease-time 43200;

       # This section is for the test host for PXE & DHCP netbooting and Kickstart installs
       # See  https://www.redhat.com/docs/manuals/enterprise/RHEL-3-Manual/sysadmin-guide/ch-pxe.html
       # for more info

        host pxetest {
                # This should match any PXE enabled client but we'll leave it off to allow
                # us more control
                # match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
                next-server $nfsserverip;
                filename "linux-install/pxelinux.0";
                hardware ethernet $macofinstallclient;
                fixed-address $iptoassigninstallclient;
        }
}

At the moment we're only dishing out DHCP assigned IP addresses to one individual host with the MAC $macofinstallclient that we're using as a test machine.


TFTP

Install the tftp-server and redhat-config-netboot packages if not already installed. Once this is done you need to copy /usr/lib/syslinux/pxelinux.0 into /tftpboot.

[root@$filestore root]# yum install tftp-server redhat-config-netboot 
[root@$filestore root]# cd /tftpboot/
[root@$filestore tftpboot]# cp /usr/lib/syslinux/pxelinux.0 /tftpboot/

Ensure your install tree is available via the method you intend to use (check /etc/exports for NFS, /etc/httpd/conf/httpd.conf if using HTTP, /etc/vsftpd/vsftpd.conf for FTP). The next step is to configure an install tree using redhat-config-netboot. redhat-config-netboot is a GUI tool that sets up the subdirectories and required files under /tftpboot to reflect your installation trees. For more info see Red Hat Enterprise Linux 4: System Administration Guide - Chapter 3. PXE Network Installations (https://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/sysadmin-guide/s1-netboot-pxe-config.html)

Once the install tree's configured (we use NFS) you can tailor the PXE boot screen and options to reflect what you want available. To customise the initial boot screen options edit /tftpboot/linux-install/pxelinux.cfg/default

default local
timeout 0
prompt 1
display msgs/custom.msg
F1 msgs/boot.msg
F2 msgs/general.msg
F3 msgs/expert.msg
F4 msgs/param.msg
F5 msgs/rescue.msg
F7 msgs/snake.msg

label local
  localboot 1

label 0
  localboot 1

label 1
  kernel wbel4/vmlinuz
  append initrd=wbel4/initrd.img ramdisk_size=10000

label 2
  kernel wbel4/vmlinuz
  append initrd=wbel4/initrd.img ramdisk_size=10000 ks=nfs:$nfsserverip:/opt/whitebox/4/en/os/i386/ks/ibmks.cfg

label 3
  kernel wbel4/vmlinuz
  append initrd=wbel4/initrd.img ramdisk_size=10000 text rescue ks=nfs:$nfsserverip:/opt/whitebox/4/en/os/i386/ks/rescueks.cfg

This config gives us the option to boot off a local disk (default behaviour), an interactive install of Whitebox EL 4, a Kickstart install of Whitebox EL4 or a Whitebox EL 4 Rescue environment.

Kickstart

WARNING! Don't place any kickstart or any other configuration files in the actual OS install trees. If you do the rsync job used to keep the yum repositories up-to-date will delete them.

There are currently two Kickstart configurations setup on $filestore.

The first, /opt/kickstart/wbel-install-ks.cfg, will install a minimal Whitebox EL 4 setup on the first SCSI disk of a system, configure Yum to correctly use the repository on $filestore, add the $username user with appropriate SSH keys, Future post-install modifications should include (snip other things...)

# Kickstart file automatically generated by anaconda.
# Modified by WMCD...
#
install
nfs --server=$nfsserverip --dir=/opt/whitebox/4/en/os/i386
lang en_US.UTF-8
langsupport --default=en_GB.UTF-8 en_GB.UTF-8
keyboard uk
#
reboot
#
# Don't need X, this is a minimal, unattended install...
# xconfig --card "VESA driver (generic)" --videoram 4096 --hsync 30-70 --vsync 50-160 --resolution 800x600 --depth 16
text
#
network --device eth0 --bootproto dhcp
# network --device eth1 --bootproto dhcp
rootpw --iscrypted $cryptedpass
firewall --disabled
selinux --disabled
authconfig --enableshadow --enablemd5
timezone --utc Europe/London
bootloader --location=mbr
# The following is the partition information you requested
# Note that any partitions you deleted are not expressed
# here so unless you clear all partitions first, this is
# not guaranteed to work
#
clearpart --all --initlabel --drives=sda
part /boot --fstype "ext3" --size=100 --ondisk=sda
part pv.0 --size=0 --grow --ondisk=sda
volgroup vg00 --pesize=32768 pv.0
logvol / --fstype ext3 --name=lv00 --vgname=vg00 --size=1024 --grow
logvol swap --fstype swap --name=lv01 --vgname=vg00 --size=256 --grow --maxsize=512
#
# clearpart --all --drives=sda
# part /boot --fstype "ext3" --size=100 --ondisk=sda
# part pv.5 --size=0 --grow --ondisk=sda
# volgroup VolGroup00 --pesize=32768 pv.5
# logvol / --fstype ext3 --name=LogVol00 --vgname=VolGroup00 --size=1024 --grow
# logvol swap --fstype swap --name=LogVol01 --vgname=VolGroup00 --size=256 --grow --maxsize=512
#
%packages
@ british-support
kernel
lvm2
grub
e2fsprogs
mc
vim-enhanced
yum
php
#
%post
#
# Add $filestore to /etc/hosts
echo "$ipaddress           $filestore" >> /etc/hosts
#
# Setup yum - we're cat-ing the whole config file because distroverpkg
# is wrong after the base install and there's no easy way to change it
# "in-place" unless mysql's installed then replace(1) would do
#
cat <<EOF > /etc/yum.conf
[main]
cachedir=/var/cache/yum
debuglevel=2
logfile=/var/log/yum.log
pkgpolicy=newest
distroverpkg=whitebox-release
tolerant=1
exactarch=1
retries=20
obsoletes=1
gpgcheck=1
#
# PUT YOUR REPOS HERE OR IN separate files named file.repo
# in /etc/yum.repos.d
[$filestore-whitebox-base]
name=Whitebox Linux \$releasever - \$basearch - Base
baseurl=ftp://$filestore/whitebox/\$releasever/en/os/\$basearch
#
[$filestore-whitebox-updates]
name=Whitebox Linux \$releasever - \$basearch - Updates
baseurl=ftp://$filestore/whitebox/\$releasever/en/updates/
#
[$filestore-whitebox-dag]
name=Whitebox Linux \$releasever - \$basearch - DAG
baseurl=ftp://$filestore/whitebox/\$releasever/en/dag/
#
EOF
#
# Add non-root user and appropriate keys (snipped out)
#

#
# Secure SSHD
#
# Setup Sudo
#
# Install GPG keys for RPMs from our locally mirrored DAG repository
#
cat <<EOF > /tmp/RPM-GPG-KEY.dag.txt
The following public key can be used to verify RPM packages
downloaded from  http://dag.wieers.com/apt/  using 'rpm -K'
if you have the GNU GPG package.
Questions about this key should be sent to:
Dag Wieers <dag@wieers.com>

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.2.1 (GNU/Linux)

mQGiBD9JMT0RBAC9Q2B0AloUMTxaK73sD0cOu1MMdD8yuDagbMlDtUYA1aGeJVO6
TV02JLGr67OBY+UkYuC1c3PUwmb3+jakZd5bW1L8E2L705wS0129xQOZPz6J+alF
5rTzVkiefg8ch1yEcMayK20NdyOmhDGXQXNQS8OJFLTIC6bJs+7MZL83/wCg3cG3
3q7MWHm3IpJb+6QKpB9YH58D/2WjPDK+7YIky/JbFBT4JPgTSBy611+bLqHA6PXq
39tzY6un8KDznAMNtm+NAsr6FEG8PHe406+tbgd7tBkecz3HPX8nR5v0JtDT+gzN
8fM3kAiAzjCHUAFWVAMAZLr5TXuoq4lGTTxvZbwTjZfyjCm7gIieCu8+qnPWh6hm
30NgA/0ZyEHG6I4rOWqPks4vZuD+wlp5XL8moBXEKfEVOMh2MCNDRGnvVHu1P3eD
oHOooVMt9sWrGcgxpYuupPNL4Uf6B6smiLlH6D4tEg+qCxC17zABI5572XJTJ170
JklZJrPGtnkPrrKMamnN9MU4RjGmjh9JZPa7rKjZHyWP/z/CBrQ1RGFnIFdpZWVy
cyAoRGFnIEFwdCBSZXBvc2l0b3J5IHYxLjApIDxkYWdAd2llZXJzLmNvbT6IWQQT
EQIAGQUCP0kxPQQLBwMCAxUCAwMWAgECHgECF4AACgkQog5SFGuNeeYvDQCeKHST
hIq/WzFBXtJOnQkJGSqAoHoAnRtsJVWYmzYKHqzkRx1qAzL18Sd0iEYEEBECAAYF
Aj9JMWAACgkQoj2iXPqnmevnOACfRQaageMcESHVE1+RSuP3txPUvoEAoJAtOHon
g+3SzVNSZLn/g7/Ljfw+uQENBD9JMT8QBACj1QzRptL6hbpWl5DdQ2T+3ekEjJGt
llCwt4Mwt/yOHDhzLe8SzUNyYxTXUL4TPfFvVW9/j8WOkNGvffbs7g84k7a5h/+l
IJTTlP9V9NruDt1dlrBe+mWF6eCY55OFHjb6nOIkcJwKxRd3nGlWnLsz0ce9Hjrg
6lMrn0lPsMV6swADBQP9H42sss6mlqnJEFA97Fl3V9s+7UVJoAIA5uSVXxEOwVoh
Vq7uECQRvWzif6tzOY+vHkUxOBRvD6oIU6tlmuG3WByKyA1d0MTqMr3eWieSYf/L
n5VA9NuD7NwjFA1kLkoDwfSbsF51LppTMkUggzwgvwE46MB6yyuqAVI1kReAWw+I
RgQYEQIABgUCP0kxPwAKCRCiDlIUa4155oktAKDAzm9QYbDpk6SrQhkSFy016BjE
BACeJU1hpElFnUZCL4yKj4EuLnlo8kc=
=mqUt
-----END PGP PUBLIC KEY BLOCK-----
EOF
#
rpm --import /tmp/RPM-GPG-KEY.dag.txt
#
# Install bash-complete, multitail, dconf, ganglia, nagios, webmin &
# keychain from DAG repo mirror. Install tripwire from somewhere too
yum -y install keychain webmin bash-completion multitail
#


The second kickstart config, /opt/whitebox/wbel4-rescue-ks.cfg, is just a very minimal file for booting into Rescue mode providing basic mouse, keyboard, language and NFS install tree location information (though no actual install takes place, it's needed for the rescue image).

# Kickstart configuration file RHEL 3 EL U4 Rescue Mode
#
#System  language
#
lang en_US.UTF-8
#
#Language modules to install
#
langsupport --default=en_GB.UTF-8 en_GB.UTF-8
#
#System keyboard
#
keyboard uk
#
#System mouse
#
mouse none
#
#Retrieve rescue system from NFS
#
nfs --server=$nfsserverip  --dir=/opt/whitebox/4/en/os/i386
#
#Network information
#
network --bootproto=dhcp

Installing a New Host

Now an example of configuring a brand-new host on $filestore so when it's connected to the network for the first time in a virgin state it'll netboot via PXE then automatically install itself with Whitebox EL 4 unattended.

Say a new Dell turns up with the MAC sn:ee:sn:ee:sn:ee (note: this is an invalid example MAC). We would need to modify one file and create another.

Edit /etc/dhcpd.conf and add...

host newbox {
  next-server $nfsserverip;
  filename "linux-install/pxelinux.0";
  hardware ethernet sn:ee:sn:ee:sn:ee;
  fixed-address $iptoassigninstallclient;
  }

Once that's done you'll need to restart the DHCP daemon, it doesn't re-read its config file when HUPed. Next create a file in /tftpboot/linux-install/pxelinux.cfg based on the DHCP assigned IP of the new machine, converted into UPPERCASE hex...

[root@$filestore root]# cd /tftpboot/linux-install/pxelinux.cfg/
[root@$filestore root]# gethostip $iptoassigninstallclient
$iptoassigninstallclient $iptoassigninstallclient $hostip
[root@$filestore pxelinux.cfg]# vi $hostip

Now edit /tftpboot/linux-install/pxelinux.cfg/$hostip to contain...

default 2
label 2
  kernel wbel4/vmlinuz
  append initrd=wbel4/initrd.img ramdisk_size=10000 ks=nfs:$nfsserverip:/opt/kickstart/wbel4-install-ks.cfg

When the machine with MAC address sn:ee:sn:ee:sn:ee boots via PXE it'll install itself according to the options outlined in the specified Kickstart config file.

One thing to bear in mind is if PXE is the first option in a machine's boot order, and "reboot" is specified in a kickstart file a machine can get stuck in a boot-install-reboot-install-reboot-install... cycle. If we want to force-install a mcchine then we could setup the IP/MAC-specific PXE boot file and DHCP, boot the machine, then once it's got its initial IP address from DHCP remove the PXE config for this host. The next time it boots it will attempt DHCP, receive an address and go through PXE, because no specific PXE boot is setup (i.e. boot, install from Kickstart) it will timeout to the default local disk.

References

Harnessing PXE Boot Services (http://www.dell.com/downloads/global/power/ps2q04-028.pdf)

http://syslinux.zytor.com/pxe.php#config

http://www.unixpeople.com/HOWTO/pxe.html

https://www.redhat.com/$filestores/nahant-list/2005-May/msg00064.html

https://www.redhat.com/$filestores/kickstart-list/2005-May/msg00029.html