PXE/Kickstart Rough Howto

From RSWiki
Revision as of 10:48, 5 July 2006 by Robert (talk | contribs)
Jump to navigation Jump to search

Reproduced courtesy of a mail sent to the Cork Linux Users Group by Ronan Kirby

PXE (pronounced PiXiE) is a protocol compliments of our friends in Intel, though you find it on pretty much every "PC" these days. When you see 'F12 to network boot' and so on as you boot your servers / desktops / laptops etc, that's what this is.

When you choose this option, the machine sends out a specially formed DHCP request. The DHCP server replies as normal giving it a DHCP lease but additionally points it to a server to go talk to for a boot image. This is defined in your dhcpd.conf similar to the following.

filename "linux-install/pxelinux.0";

That IP which it is pointing to above needs to be running a TFTP server. This is not as complicated as it may sound. It's controlled by xinetd, so really you just need to install (up2date / yum) the package and enable it.

The directory above (linux-install, or what ever you call it) will contain various PXE related files, such as a menu for display and an actual configuration file. The configuration file points to boot images, which when selected get passed over the network to the client PC. These images are shipped with each distro, with Red Hat / Fedora it's going to be in /images/pxeboot on the first CD / ISO image. The PXE configuration file in this directory will have machine entries similar to the following, after some basic config at the top.

label my-testserver-1
kernel RHEL4/U3/AS/x86_64/vmlinuz
append initrd=RHEL4/U3/AS/x86_64/initrd.img text

Line 1 is the label for that entry, so it's what you'd choose at the boot prompt. Line two is the location of the kernel (i.e. what you took from the images/pxeboot on the distro's ISO) the location is relative to the tftp directory you used. Line 3 is the initial ram disk for the option plus any boot options you want to apply, i.e. like as if you were doing it from a CD and wanted to go in to single user mode (1 / single), or wanted a text mode install (text). All the anaconda options can be specified here. So in this case, as we don't want an interactive install, we want to kickstart, we point it to the kickstart file, which in this case is on a web server. So line 3 would read.

append initrd=RHEL4/U3/AS/x86_64/initrd.img    ks=

So now the booting is out of the way, and it knows where to get the install details from. Everything else is contained within the kickstart file more or less. There are some additional things / appends which you may want to specify above, for example ip=, gateway= etc if you were not using DHCP / PXE as we are here. These options would be used, for example, in the scenario I mentioned in an earlier post about $LARGE_BANK_01 posting branches a USB key which boots a machine and then does a network install.

Another useful append here is "ksdevice=eth0" for when you have multiple NICs. Beyond the ones which are interpreted by anaconda and are valid install options, you can add anything of your own as you like. For example "college=UCC lab=cs101 station=acb123". During the actual kickstart, these are then available to you as variables (read them in from /proc/cmdline), and as such will allow you to make decisions regarding the build automatically based on this information. i.e. the hostname of the machine may be a permutation or combination of these variables.

The install tree, as pointed to by the kickstart, can be a number of things - samba share, cd, harddisk, ftp, nfs, http (though these are changing). Personally I use NFS and HTTP myself.


Mount each ISO image for the distribution one at a time, performing a recursive copy of each in to an appropriately named directory which is within the document root of your webserver. There are a few files in each ISO which it will over-write each other, that's fine.

For NFS:

Just put the .iso files in a directory on their own for each distribution. Make sure it's readable by your intended clients. There's no need to unpack the ISOs.

Then there's the kickstart file its self. You can break it down in to three sections. Pre-install, which is a script section where you can do lots of funky things, like determine various things on the existing system before you rebuild it, or gather specific info in the hardware (if needed), or read /proc/cmdline in to variables as we mentioned earlier. Then there is the main install section and finally post-install, where the magic happens - you can script anything you like here (chrooted or not), allowing for infinate customization.

Here is a simple basic kickstart as an example with some inline comments

install         # rather than upgrade
url --url
              # Location of the install media, http, nfs etc
lang en_US.UTF-8
langsupport --default en_US.UTF-8
keyboard uk
mouse generic3usb --device input/mice
network --bootproto=dhcp
              # we could specify static IP info too instead
rootpw --iscrypted $1$GLeIMyV5$FIzpEKu4RF1is.diARElt1
              # encrypted password (no, not a real one above)
firewall --disabled
selinux --permissive
authconfig --enableshadow --enablemd5
timezone Europe/London
bootloader --location=mbr --append="noexec=off hda=noide"
              # Any boot time options you wan to add
              # I specified noide here as I was booting
              # from SAN in this case.
              # do not configure X Windows
zerombr yes
              #Clear the Master Boot Record
clearpart --all --initlabel
              #Partition clearing information
part /boot --fstype ext3 --size=150 --ondisk=sdb
part pv.01 --size=1 --grow --ondisk=sdb
part pv.02 --size=1 --grow --ondisk=sda
volgroup rootvg pv.01
volgroup satvg pv.02
logvol /tmp --vgname=rootvg --size=1500 --name=tmpvol
logvol /    --vgname=rootvg --size=4000 --grow --name=rootvol
logvol swap --vgname=rootvg --size=2000 --name=swapvol
logvol /store1 --vgname=satvg --size=14000 --name=store1vol
logvol /store2 --vgname=satvg --size=1 --grow --name=store2vol
              # In the above partition layout (with LVM) I have
              # used two disks, sda and sdb for different volumes.
              # You don't need to use LVM etc. HDA for IDE etc.
auth  --useshadow  --enablemd5
              #System authorization information
%packages --resolvedeps
              # This is the actual package install section. The
              # resolvedeps option allows you to make mistakes and
              # have anaconda sort it out for you, i.e. resolving
              # package dependencies.
@ Base
@ Compatibility Arch Support
@ Development Tools
@ Legacy Software Development
              # base channels
              # individual packages to add
              # individual packages to add
              # And so begins the post-install section.
              # this is currently in a chroot to / on the
              # new file system.
              # Various variables I like to set first to use later
              # I run everything in this, so I can log it
/bin/echo "Welcome to $HOSTNAME Server " > /etc/motd 
/bin/echo "Built from kickstart version $VER " >> /etc/motd
/bin/echo " " >> /etc/motd
              # One way of adding to files
cat >> /etc/sysctl.conf <<EOF
fs.aio-max-size = 1048576
fs.file-max = 327680
net.core.rmem_max = 262144
net.core.wmem_max = 262144
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.ip_forward = 0
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
              # Another way of inputing to files
              # Here doing some system settings
useradd -c "Some lone user" -d /home/luser luser
echo luserpass | passwd --stdin luser
              # Add a user if you like
# Setup hosts file
cat > /etc/hosts << EOF       localhost.localdomain           localhost     install-server.some.domain      install-server     another.machine.some.domain     another
              # Edit the hosts file if you like
wget $SERVER/iptables.$lab -O /etc/sysconfig/iptables
              # Here using the server variable we set at the
              # top of the post-install section to pull some
              # custom files we stored, in this case a firewall.
              # In this case using a variable which could have been
              # pulled from /proc/cmdline to get a specific one for
              # each lab.
/sbin/chkconfig ip6tables off
/sbin/chkconfig isdn off
/sbin/chkconfig sendmail off
/sbin/chkconfig ntpd on
              # Turn some services on and off
) > /tmp/kickstart-install.log 2>&1
              # The aforementioned log.

So this is just a quick example and doesn't even touch the surface of what you can do. But I hope it gives a good idea of how to get started and the principles involved. The above kickstart is a mockup, so E&OE.