Installing VMWare ESXi via PXE

We’re going down the route of virtualising our infrastructure at Timico, which means I’m having to get my hands dirty with VMWare. We’ve tried the Xen route, and not really got on with it – so it’s time to move on to something a little more polished.

In this article, I’ll outline how I plan on speeding up the provisioning of new tin to run as VM machines. The plan is to be able to plug in a new node whenever one is needed, and have it fully auto-provisioned from start to end. The first step in doing that is to automate the installation of vmware ESXi – which is done by PXE booting.

I am using ubuntu as my bootstrapping server, which which be responsible for running the DNS for the management network (DNS setup not covered here), providing DHCP, and serving the files needed for PXE. At the time of writing this, the installation documentation for ESXi does cover PXE booting, but I found this document hard to find (in hindsight, it’s easy to find – that’s always the way!), and doesn’t’ quite provide a step by step guide I aim to provide here. It is however essential reading – find the install documents for ESXi 4.1 here

Having done a basic install of Ubuntu on my server, the first step was to install the required packages:

  # apt-get install syslinux tftpd-hpa dhcp3-server apache2

The packages above are used as follows:

Provides pxelinux.0 – see the syslinux homepage for more info.
A TFTP server to serve pxelinux, and the VMWare kernel etc.
The DHCP server is used for assigning addresses to nodes
This is used to serve the kickstart config, along with the vmware installation files

As you can see from above, I use apache to serve the VMWare ESXi install files. This is optional, you can also install the files over NFS if you wish.

Configuring DHCP

When a server PXE boots, the first thing it does is DHCP for an address. If you are VLANing your environment (which you really should be!) – keep in mind that this will be done over the access VLAN. The configuration below

ddns-update-style none;
default-lease-time 600;
max-lease-time 7200;
allow booting;
allow bootp;
class "pxeclients" {
  match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
  filename = "pxelinux.0";


subnet netmask {
  pool {
    allow members of "pxeclients";

Notice the use of the pool and class in the above, which allows for IP addresses of servers in the process of provisioning to use a different range than that used by active servers. This is completely optional, but I thought it was pretty neat, so I did it!

The ‘next-server’ in the configuration above needs to be the IP address of your TFTP server.

Feel free to test the setup at this point, whilst it won’t work- you should at least see your server PXE boot and complain about a lack of config. On the Dell R210 I’m using, you press F12 at boot to start a PXE boot.

Configuring TFTP and PXE

There’s not really much to configuring TFTP, it works out of the box. It is configured to serve files from /var/lib/tftpboot, which to avoid confusion I didn’t change. Copy pxelinux.0 into there, or symlink it.

  cp /usr/lib/syslinux/pxelinux.0 /var/lib/tftpboot/pxelinux.0

When the server has booted via PXE, and loaded pxelinux, it will attempt to find a configuration file for instructions as to what to do next. We use the ‘default’ configuration file, which needs to be placed in /var/lib/tftpboot/pxelinux.cfg/default. The contents of the file are:

default 1
prompt 1
menu title VMware VMvisor Boot Menu
timeout 50

label 1
kernel esxi/mboot.c32
append esxi/vmkboot.gz ks= --- esxi/vmkernel.gz --- esxi/sys.vgz --- esxi/cim.vgz --- esxi/ienviron.vgz --- esxi/install.vgz

label 0
localboot 0x80

As you can see from the above, there is reference to the ESXi files, and a URL to a kick start configuration. To get the ESXi files, download the ISO image from the VMWare website, and mount the ISO via loopback so you can get the files out, and copy the files over to your TFTP folder.

# mount -o loop ./VMware-VMvisor-Installer-4.1.0-260247.x86_64.iso /mnt/vmware/
# mkdir /var/lib/tftpboot/esxi/
# cp /mnt/vmware/*  /var/lib/tftpboot/esxi/

I copy over the whole CD in the above, because I’m lazy – you only need to copy the files shown in the config for pxe.


Here is my kickstart script.

# Accept the VMware End User License Agreement
# Set the root password for the DCUI and Tech Support Mode
rootpw mypassword
# Choose the first discovered disk to install onto
autopart --firstdisk --overwritevmfs
# The installation media is in the CD-ROM drive
install url
# Set the network to DHCP on teh first network adapater
network --bootproto=dhcp --device=vmnic0

%post --unsupported --interpreter=busybox

The purpose of the post install section (the last 2 lines) is that the installer by default will wait until you press enter to continue, simply putting a script in to reboot prevents this. One other thing it prevents is the CD ROM being ejected, which was driving me nuts!

This file should be available via HTTP at the URL specified in the PXE configuration file (above). Notice above that I have a ‘install url’ line, followed by a URL – this can also be used to get the install files from NFS instead, see the documentation.

To make the install files available via apache, I symlinked from the TFTP path we copied the ISO content to earlier:

# ln -s /var/lib/tftpboot/esxi/ /var/www/vmware

That’s it!

That’s all there is to it. Reboot your node, PXE boot it, and watch it install ESXi! In the syslog you should see something similar to this:

Sep 29 13:34:06 site1-store1 dhcpd: DHCPDISCOVER from b8:ac:6f:8b:9a:29 via eth1.1011
Sep 29 13:34:07 site1-store1 dhcpd: DHCPOFFER on to b8:ac:6f:8b:9a:29 via eth1.1011
Sep 29 13:34:11 site1-store1 dhcpd: DHCPREQUEST for ( from b8:ac:6f:8b:9a:29 via eth1.1011
Sep 29 13:34:11 site1-store1 dhcpd: DHCPACK on to b8:ac:6f:8b:9a:29 via eth1.1011
Sep 29 13:34:11 site1-store1 in.tftpd[31072]: RRQ from filename pxelinux.0
Sep 29 13:34:11 site1-store1 in.tftpd[31072]: tftp: client does not accept options
Sep 29 13:34:11 site1-store1 in.tftpd[31073]: RRQ from filename pxelinux.0
Sep 29 13:34:11 site1-store1 in.tftpd[31074]: RRQ from filename pxelinux.cfg/44454c4c-5a00-104e-8057-b7c04f56344a
Sep 29 13:34:11 site1-store1 in.tftpd[31075]: RRQ from filename pxelinux.cfg/01-b8-ac-6f-8b-9a-29
Sep 29 13:34:11 site1-store1 in.tftpd[31076]: RRQ from filename pxelinux.cfg/C0A86FCA
Sep 29 13:34:11 site1-store1 in.tftpd[31077]: RRQ from filename pxelinux.cfg/C0A86FC
Sep 29 13:34:11 site1-store1 in.tftpd[31078]: RRQ from filename pxelinux.cfg/C0A86F
Sep 29 13:34:11 site1-store1 in.tftpd[31079]: RRQ from filename pxelinux.cfg/C0A86
Sep 29 13:34:11 site1-store1 in.tftpd[31080]: RRQ from filename pxelinux.cfg/C0A8
Sep 29 13:34:11 site1-store1 in.tftpd[31081]: RRQ from filename pxelinux.cfg/C0A
Sep 29 13:34:11 site1-store1 in.tftpd[31082]: RRQ from filename pxelinux.cfg/C0
Sep 29 13:34:11 site1-store1 in.tftpd[31083]: RRQ from filename pxelinux.cfg/C
Sep 29 13:34:11 site1-store1 in.tftpd[31084]: RRQ from filename pxelinux.cfg/default
Sep 29 13:34:16 site1-store1 in.tftpd[31085]: RRQ from filename esxi/mboot.c32
Sep 29 13:34:16 site1-store1 in.tftpd[31086]: RRQ from filename esxi/vmkboot.gz
Sep 29 13:34:16 site1-store1 in.tftpd[31087]: RRQ from filename esxi/vmkernel.gz
Sep 29 13:34:16 site1-store1 in.tftpd[31088]: RRQ from filename esxi/sys.vgz
Sep 29 13:34:34 site1-store1 in.tftpd[31089]: RRQ from filename esxi/cim.vgz
Sep 29 13:34:38 site1-store1 in.tftpd[31090]: RRQ from filename esxi/ienviron.vgz
Sep 29 13:34:39 site1-store1 in.tftpd[31091]: RRQ from filename esxi/install.vgz

6 thoughts on “Installing VMWare ESXi via PXE”

  1. tiny remark:

    in pxelinux.cfg/default you have to have:

    default 1
    prompt 1
    menu title VMware VMvisor Boot Menu
    timeout 50

    label 1
    kernel /esxi/mboot.c32
    append -c /esxi/boot.cfg /esxi/vmkboot.gz ks= — esxi/vmkernel.gz — esxi/sys.vgz — esxi/cim.vgz — esxi/ienviron.vgz — esxi/install.vgz

    label 0
    localboot 0x80

    otherwise you get the following:
    Configuration error while parsing /esxi/boot.cfg”
    Fatal error : 15 not found.

    thanks for the guide!!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.