FAI Lab With VirtualBox (Part II)
10 November 2011
Note: This post is the second in a series of posts about setting up an FAI lab using VirtualBox. The first post can be found here.
In Part I of this series we configured a VirtualBox virtual machine with a basic installation of FAI. We also configured a virtual network and connected our FAI server to it. Finally, we set up a DHCP/TFTP server to allow us to PXE boot clients into the FAI nfsroot. The next step is to boot up our first FAI client virtual machine to make sure the PXE process works correctly. Then, we’ll configure FAI to install and configure Ubuntu Server on our client.
Testing PXE Booting
Create a new VM to test PXE booting. These commands will be familiar from Part I:
1
2
3
4
5
6
VBoxManage createvm --name pxetest --ostype Ubuntu_64 --register
VBoxManage modifyvm pxetest --memory 512 --boot1 disk --boot2 dvd --boot3 net --rtcuseutc on
VBoxManage modifyvm pxetest --nic1 hostonly --hostonlyadapter1 vboxnet0
VBoxManage createhd --size 10000 --filename $HOME/Library/VirtualBox/HardDisks/pxetest-root
VBoxManage storagectl pxetest --name sata0 --add sata
VBoxManage storageattach pxetest --storagectl sata0 --device 0 --port 0 --type hdd --medium $HOME/Library/VirtualBox/HardDisks/pxetest-root.vdi
We’re going to need to know the MAC address of the host in order to configure dnsmasq to PXE boot it.
plathrop ~ » VBoxManage showvminfo pxetest | grep MAC
NIC 1: MAC: 080027928409, Attachment: Host-only Interface 'vboxnet0', Cable connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0 Mbps, Boot priority: 0, Promisc Policy: deny
As you can see, the MAC for the “pxetest” VM is
08:00:27:92:84:09
. Add the MAC to /etc/ethers
on the “faiserver”
VM, along with the hostname you want this system to use.
08:00:27:92:84:09 pxetest
You’ll need to add a record to /etc/hosts
as well, mapping the name
(pxetest) to an IP address from the range we configured dnsmasq to
pass out (192.168.0.10 onward):
192.168.0.10 pxetest
Restart dnsmasq on the “faiserver” VM and boot your “pxetest” VM. You should see something like this in the VirtualBox window:
Despite the error message, this means we’ve succeeded! The “pxetest”
VM received an IP address from dnsmasq, and the required options to
PXE boot. If you look at your dnsmasq logs (in /var/log/daemon.log
on Ubuntu) you’ll see something like this:
1
2
3
4
5
6
7
8
9
10
11
12
Nov 8 00:30:59 faiserver dnsmasq-tftp[5065]: sent /srv/tftp/fai/pxelinux.0 to 192.168.0.10
Nov 8 00:30:59 faiserver dnsmasq-tftp[5065]: file /srv/tftp/fai/pxelinux.cfg/2b176787-c273-4728-a8db-7af779beb2b3 not found
Nov 8 00:30:59 faiserver dnsmasq-tftp[5065]: file /srv/tftp/fai/pxelinux.cfg/01-08-00-27-92-84-09 not found
Nov 8 00:30:59 faiserver dnsmasq-tftp[5065]: file /srv/tftp/fai/pxelinux.cfg/C0A8000A not found
Nov 8 00:30:59 faiserver dnsmasq-tftp[5065]: file /srv/tftp/fai/pxelinux.cfg/C0A8000 not found
Nov 8 00:30:59 faiserver dnsmasq-tftp[5065]: file /srv/tftp/fai/pxelinux.cfg/C0A800 not found
Nov 8 00:30:59 faiserver dnsmasq-tftp[5065]: file /srv/tftp/fai/pxelinux.cfg/C0A80 not found
Nov 8 00:30:59 faiserver dnsmasq-tftp[5065]: file /srv/tftp/fai/pxelinux.cfg/C0A8 not found
Nov 8 00:30:59 faiserver dnsmasq-tftp[5065]: file /srv/tftp/fai/pxelinux.cfg/C0A not found
Nov 8 00:30:59 faiserver dnsmasq-tftp[5065]: file /srv/tftp/fai/pxelinux.cfg/C0 not found
Nov 8 00:30:59 faiserver dnsmasq-tftp[5065]: file /srv/tftp/fai/pxelinux.cfg/C not found
Nov 8 00:30:59 faiserver dnsmasq-tftp[5065]: file /srv/tftp/fai/pxelinux.cfg/default not found
As we can see, the PXE boot failed because no PXE config was located for the “pxetest” VM. Let’s fix that. The command we use is fai-chboot(8), like this:
1
2
3
4
5
6
7
faiserver ~ » sudo fai-chboot -I -F -v 192.168.0.10
Booting kernel vmlinuz-2.6.38-grml
append initrd=initrd.img-2.6.38-grml ip=dhcp
FAI_FLAGS=verbose,sshd,createvt
192.168.0.10 has 192.168.0.10 in hex C0A8000A
Writing file /srv/tftp/fai/pxelinux.cfg/C0A8000A for 192.168.0.10
Note: you can ignore the -grml stuff; I’m using a custom kernel and initrd in my environment, it should not affect the rest of this article.
The -F
option sets some useful flags for FAI, -I
tells FAI to run
an automatic installation, and -v
gives us verbose output. The IP
address is the IP we assigned to the “pxetest” VM. As you can see in
line 7, this command creates the file
/srv/tftp/fai/pxelinux.cfg/C0A8000A
, which is one of the files that
the TFTP server was looking for (see line 4 of the previous
listing). Now that this is in place, if you reboot the “pxetest” VM,
you should see the system PXE boot, mount the nfsroot, and then dump
you out to a prompt when FAI fails (because we haven’t created an FAI
configuration yet). If the machine PXE boots fine, but doesn’t get the
correct IP address from DHCP, you probably did not disable the
VirtualBox DHCP server on vboxnet0
as described in “Setting up the
FAI server VM” in Part I.
Installing Ubuntu via FAI
Now we need to configure FAI to actually perform an installation. To start with we’ll need to copy the example configuration provided by FAI. This will give us a simple FAI configuration to build on top of.
sudo cp -a /usr/share/doc/fai-doc/examples/simple/* /srv/fai/config
We’ll also need to NFS export our configuration directory, so we add
it to /etc/exports
:
/srv/fai/config 192.168.0.2/16(async,ro,no_subtree_check,no_root_squash)
Activate this export with sudo exportfs -a
. We also need to do one
last bit of network configuration to allow our FAI clients to speak to
the outside world during the install process. We’ll need to make sure
the “faiserver” VM is configured as a NAT gateway. Add the following
line to /etc/sysctl.conf
(or uncomment it, if you have the default
Ubuntu sysctl.conf
):
net.ipv4.ip_forward=1 in /etc/sysctl.conf
Activate this sysctl setting with sudo sysctl -p
. Next, we’ll
configure iptables:
1
2
3
sudo iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
As root
, save this iptables ruleset:
iptables-save >/etc/network/pxenet-nat.ipt
. Add a line to
/etc/network/interfaces
under the eth1
section to restore the
iptables rules when the interface comes up.
up /sbin/iptables-restore </etc/network/pxenet-nat.ipt
At this point our FAI server should be ready too bootstrap clients with Debian. You can go ahead and create a new virtual machine and give it a try if you’d like (or destroy and recreate the disk for the “pxetext” VM and try it there). As I said, though, I’d like to be able to bootstrap Ubuntu Server VMs. Although official support for “FAI multi-distribution” isn’t available in FAI 3.x, it works fine; we’ll just have to pull in a couple pieces of FAI 4.x.
The first thing we’ll need is a “basefile” for the version of Ubuntu
we’d like to install. The config examples for FAI 4.x (available
here) include a mk-basefile
shell script (under basefiles/
)
which can be used to build the basefiles for your distribution of
choice. Currently, it supports Debian 6.0 (which we can install
out-of-the-box with FAI 3.x), Ubuntu 10.04, CentOS 5/6, and Scientific
Linux Cern 5/6. I want to install Ubuntu 10.10, so I need to patch the
shell script to add support.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
--- mk-basefile.orig 2011-09-07 17:27:24.000000000 -0700
+++ mk-basefile 2011-11-09 11:55:25.000000000 -0800
@@ -30,3 +30,3 @@
MIRROR_DEBIAN=http://kueppers/debian/
-MIRROR_UBUNTU=http://ftp.halifax.rwth-aachen.de/ubuntu/
+MIRROR_UBUNTU=http://mirrors.kernel.org/ubuntu/
MIRROR_CENTOS=http://mirror.netcologne.de/
@@ -37,3 +37,4 @@
EXCLUDE_LUCID=dhcp3-client,dhcp3-common
-
+EXCLUDE_MAVERICK=dhcp3-client,dhcp3-common
+INCLUDE_MAVERICK=aptitude,tasksel
@@ -180,2 +181,12 @@
+maverick() {
+
+ local arch=$1
+
+ check
+ debootstrap --arch $arch --exclude=${EXCLUDE_MAVERICK} --include=${INCLUDE_MAVERICK} maverick $xtmp ${MIRROR_UBUNTU}
+ cleanup-deb
+ tarit
+}
+
@@ -191,2 +202,3 @@
LUCID32 LUCID64
+ MAVERICK32 MAVERICK64
SQUEEZE32 SQUEEZE64
@@ -224,2 +236,4 @@
LUCID64) lucid amd64 ;;
+ MAVERICK32) maverick i386 ;;
+ MAVERICK64) maverick amd64 ;;
SQUEEZE32) squeeze i386 ;;
You can download the patched file here
Create the ubuntu “basefile” (I want the 64-bit one):
sudo ./mk-basefile -J MAVERICK64
Add a section to /srv/fai/config/class/50-host-classes
for our test
Ubuntu installation:
--- 50-host-classes.orig 2011-11-09 14:16:09.000000000 -0800
+++ 50-host-classes 2011-11-09 14:14:15.000000000 -0800
@@ -31,2 +31,6 @@
exit 0 ;; # CentOS/SLC does not use the GRUB class
+ ubuntu)
+ echo "FAIBASE UBUNTU"
+ ifclass I386 && echo "MAVERICK MAVERICK32"
+ ifclass AMD64 && echo "MAVERICK MAVERICK64" ;;
*)
You can download the patched file here
Use the hostname you assigned earlier in /etc/hosts
.
Next, we need to get the requisite apt files for the Ubuntu version we
want to install. You are probably safest getting them from a live CD
for the version of Ubuntu you want to install. You need secring.gpg
,
sources.list
, trustdb.gpg
, and trusted.gpg
. You may want to
modify sources.list
to point at your favorite mirror (or a local
mirror if you’ll be installing a lot of VMs). Here’s a snippet that
will put these in the appropriate places in your FAI config:
for file in sources.list secring.gpg trustdb.gpg trusted.gpg; do sudo mkdir -p /srv/fai/config/files/etc/apt/${file}; sudo cp $file /srv/fai/config/files/etc/apt/${file}/MAVERICK; done
You’ll also need to create
/srv/fai/config/files/etc/network/interfaces/UBUNTU
:
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet dhcp
We also have to configure the packages we’ll need to install. In
/srv/fai/config/package_config/UBUNTU
:
PACKAGES aptitude
apt
apt-utils
console-setup
debconf-utils
dhcp3-client
fai-client
grub
less
linux-image-generic
locales
openssh-server
vi
PACKAGES aptitude GRUB
grub lilo-
PACKAGES aptitude GRUB_PC
grub-pc grub- lilo-
PACKAGES aptitude LILO
lilo grub-
Just the basics, for now, we can add more packages later if we need
them. The most important one here is the “linux-image-generic”
package. We’ll also want to rename
/srv/fai/config/package_config/DEFAULT
to
/srv/fai/config/package_config/DEBIAN
. The “DEFAULT” class is
applied to every FAI client, and since we’re going to be working with
multiple distributions, we don’t want to use the bundled DEFAULT
package_config
file, which assumes a Debian client.
Finally, we need to create a hook for the updatebase
step of
the installation to copy the apt files into place inside of the target
OS. The file should be /srv/fai/config/hooks/updatebase.UBUNTU
:
#! /bin/bash
echo "Preparing apt for Ubuntu"
fcopy -v /etc/apt/secring.gpg
fcopy -v /etc/apt/sources.list
fcopy -v /etc/apt/trustdb.gpg
fcopy -v /etc/apt/trusted.gpg
fcopy
is an FAI built-in that takes care of copying files from the
configuration space to the target OS for us.
At this point, you should be able to create a new VM similar to the
“pxetest” VM we created earlier, boot it, and watch FAI automagically
install Ubuntu onto the new VM. When the install completes, a message
is displayed telling you to hit Return to reboot. Before you do so you
may want to run fai-chboot -d 192.168.0.10
(substituting the IP you
used for the new VM) on the “faiserver”, and change the boot device
priority, so that the VM will boot from the disk instead of the
network. From here, you’ve got the basis of a pretty functional lab,
and you can start experimenting with your FAI configuration.
In Part III of this series, I’ll show you how to use FAI to bootstrap Redhat, and also set up our PXE server to allow us to boot a “live” system for debugging. Redhat will be more of an adventure for me since I’m pretty unfamiliar with the RPM-based distributions.