I’ve been doing some recent work on building virtual machine images to a position where I can pretty much automate the whole process from end-to-end.  My favourite route is to use PXE booting and I’ve had builds of all the current Linux builds in place for some years.  This also includes automated builds of ESXi too, to allow for easier upgrades where attaching physical or remote media is a problem.  My current infrastructure (see this page) has three virtual environments.  One is based on Scale Computing’s HC3 (3-node KVM-based), one is vSphere based ESXi 6 & vCenter (3 nodes) and I also have a single server running Microsoft Hyper-V 2012. What I want to achieve is the ability to boot a VM from the command line (easy enough with PowerShell) and have the build complete through to login prompt.  Note: this is a Linux-based discussion; I also run WDS separately for Windows builds.

Building a VM with PXE is pretty easy.  I have a single Linux server that runs DHCP and a dedicated VLAN 11 for Linux boots that presents a menu of choices (multiple operating systems) and sub-menus with specific releases.  Builds are 100% automated with Kickstart, so I don’t need to enter any options once I’ve chosen the image I want.  However I also want to go that last mile and have the boot process identify the O/S and release from some parameters set when I built the VM.

Looking at the PXELINUX guide, my choices are limited to client UUID, MAC address or IP address.  The scanning order looks for specific files in the pxelinux.cfg directory checking for a specific UUID file, a file based on MAC address, then progressively the IP address in hex, removing one byte at a time, making the search more generic.  If none of these are found, then the file default is used.  Using either UUID or MAC address would require me to create specific files and even with the MAC address option, I’d have to manually generate a MAC address rather than taking the pseudo random ones generated by vSphere and HC3.  Each one of those files would have the boot instructions for a particular O/S, with (for example) the MAC address address space divided up by O/S versions/releases.  IP address isn’t really a good choice either, as I’d have to the same partitioning and that changes my entire networking schema.

In the end, the technique I used was to  base selections on MAC address.  vSphere uses a OUI prefix of 00:50:56, followed by three octets that can range from 00:00:00 to 3F:FF:FF.  As I build a VM, I assign a static MAC address and divide the three octets into ranges (e.g.):

  • 00:00:00 – CentOS 6.5
  • 00:01:00 – CentOS 7.0
  • 00:02:00 – Ubuntu 15.04

Each O/S gets a 256 device range, which is easily sufficient.  My DHCP entries look like this (example rather than full config shown):

 shared-network "VLAN11" {
 subnet 172.17.11.0 netmask 255.255.255.0 {
 class "CentOS65" { match if substring(hardware,0,6) = 01:00:50:56:00:00; }
 class "CentOS70" { match if substring(hardware,0,6) = 01:00:50:56:01:00; }
       option domain-name-servers 172.17.11.2;
       option domain-name "brookendlab.com";
       option broadcast-address 172.17.11.255;
       default-lease-time 3600;
       max-lease-time 3600;
       next-server 172.17.11.1;
       pool { range 172.17.11.100 172.17.11.119;
              allow members of "CentOS65";
              filename "/CentOS65/pxelinux.0";
            }
       pool { range 172.17.11.120 172.17.11.129;
              allow members of "CentOS70";
              filename "/CentOS70/pxelinux.0";
            }
       pool { range 172.17.11.130 172.17.11.250;
              deny members of "CentOS65";
              deny members of "CentOS70";
            }
       }
 }

With this, my TFTP server (that delivers the files for the PXE process) has a directory for each O/S release that holds pxelinux.0, pxelinux.cfg and a default file with the single boot option. Building out the PXE settings for a new O/S release is quite simple; amend DHCP for a new range of IP & MAC addresses and create a new directory on the TFTP server.  Of course now I’ve just shifted the problem and I have to create a manual MAC address for each VM.  This isn’t a problem, but keeping track of which ones are in use is an issue.

Comments are always welcome; please read our Comments Policy first.  If you have any related links of interest, please feel free to add them as a comment for consideration.  

Copyright (c) 2009-2016 – Chris M Evans, first published on https://blog.architecting.it, do not reproduce without permission.

Please consider sharing!Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInBuffer this pageEmail this to someoneShare on RedditShare on StumbleUpon

Written by Chris Evans