PXE Booting Ubuntu 20.04 Installer

With Ubuntu 20.04, Canonical switched from the Debian installer to their own autoinstaller. This means that you have to build a new PXEBoot environment.

When I started setting up my environment I was surprised at the sparseness of the Ubuntu documentation. Here is how I got it working.

0 – Getting Ready

Before you start, you need to have:

  • Working TFTP Server
  • Working HTTP Server
  • Working DHCP Server
  • Ubuntu 20.04 ISO
  • Ubuntu 20.04 running VM. (Yes, you need a 20.04 VM to build a PXEBoot environment.)

Your TFTP/HTTP/DHCP servers don’t have to be on Ubuntu 20.04. Nor do they all have to be on the same host, but for these instructions I will assume they are as it makes it easier to write…

In your 20.04 VM install the following two packages

$ sudo apt-get install syslinux-common pxelinux

Then copy the file ldlinux.c32 & pxelinux.0 files to to your TFTP server:

$ scp /usr/lib/syslinux/modules/bios/ldlinux.c32 <SERVER>:/tmp
$ scp /usr/lib/PXELINUX/pxelinux.0 <SERVER>:/tmp

Whilst you’re logged into your 20.04 copy off the file /var/log/installer/autoinstall-user-data:

$ sudo scp /var/log/installer/autoinstall-user-data <SERVER>:/tmp

We’ll discuss this file later on.

1 – HTTP Server Prep.

Put the 20.04 ISO into a directory on your HTTP server:

# mkdir -p /var/www/html/ubuntu2004/autoinstall/test/
# mv /path/to/iso/ubuntu-20.04-live-server-amd64.iso /var/www/html/ubuntu2004

We also need to create two files in our newly created directory. One is empty, the other has minimal content:

# touch /var/www/html/ubuntu2004/autoinstall/test/meta-data
# cat >/var/www/html/ubuntu2004/autoinstall/test/user-data <<EOF
#cloud-config
autoinstall:
  version: 1
  identity:
    hostname: ubuntu2004
    password: "$6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96
xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0"
    username: ubuntu
EOF

Note that the password is one line, not split over two.

2 – TFTP Server Prep

In the directory of your TFTP server services, create a directory to hold our 20.04 PXE Boot environment:

# mkdir /var/lib/tftpboot/ubuntu2004

Move the ldlinux.c32 & pxelinux.0 files into this directory:

# mv /tmp/ldlinux.c32 /var/lib/tftpboot/ubuntu2004
# mv /tmp/pxelinux.0 /var/lib/tftpboot/ubuntu2004

Mount the 20.04 ISO and copy off the kernel & root filesystem:

# mount -o ro /var/www/html/ubuntu2004/ubuntu-20.04-live-server-amd64.iso /mnt
# cp /mnt/casper/initrd /var/lib/tftpboot/ubuntu2004
# cp /mnt/casper/vmlinuz /var/lib/tftpboot/ubuntu2004
# umount /mnt

Create a starter PXEBoot configuration file:

# mkdir /var/lib/tftpboot/ubuntu2004/pxelinux.cfg

In that directory, create a file called “default” and give it the following contents:

# cat >/var/lib/tftpboot/ubuntu2004/pxelinux.cfg/default <<EOF
DEFAULT install
 LABEL install
 KERNEL vmlinuz
 INITRD initrd
 APPEND autoinstall ip=dhcp ds=nocloud-net;s=http://<IP_ADDRESS_SERVER>/ubuntu2004/autoinstall/test/ url=http://<IP_ADDRESS_SERVER>/ubuntu2004/ubuntu-20.04-live-server-amd64.iso
EOF

Replace the <IP_ADDRESS_SERVER> string with the IP address of your HTTP server.

3 – DHCP Server Prep

Edit your dhcpd.conf file and add an entry for your machine:

# cat >>/etc/dhcp/dhcpd.conf <EOF

host ubuntu2004 {
  hardware ethernet xx:xx:xx:xx:xx:xx;
  fixed-address y.y.y.y;
  next-server z.z.z.z;
  filename "ubuntu2004/pxelinux.0" 
}
EOF
  • Replace the “xx:xx:xx:xx:xx:xx” string with the MAC address of your machine.
  • Replace the “y.y.y.y” string with the IP address you want the machine to have
  • Replace the “z.z.z.z” string with the IP address of your TFTP Server.

Restart the DHCP service:

# systemctl restart isc-dhcp-server

4 – GO!

You should be able to power-on your (virtual) machine and it should boot the installer. Places to check if it doesn’t start the installer:

  • DHCP Server log (/var/log/dhcpd.log) to check that the machine is getting its IP address and boot settings.
  • The TFTP server log to make sure the machine is getting its PXEBoot files (tail -f /var/log/syslog | grep tftp )
  • The HTTP server log to make sure the machine is getting its ISO and configuration files.

Once the installer has completed, you should have an Ubuntu 20.04 machine with a user called “ubuntu” and password “ubuntu”

5 – Advanced.

Other than getting the PXEBoot environment setup, our installer hasn’t really done much. This is where we need to configure the installer. In the old Debian based installer this was done by editing the preseed file. With 20.04’s autoinstaller, we have to configure the user-data file (that we created on our HTTP server)

The official Ubuntu documentation for this is at https://ubuntu.com/server/docs/install/autoinstall-reference The problem with the documentation is it’s incomplete. (And the occasional error in it too)

The docs say you can take the configuration file from a 20.04 install (the autoinstall-user-data file we copied off our 20.04 VM right at the start). The problem is that this file is the idealized file and doesn’t match what the installer actually wants.

Note that so far I’ve not seen mention of what needs to be in the meta-data file. It just has to exist.

5.1 – Network Configuration

There’s a bug in the installer. The documentation says the configuration file should look something like:

#cloud-config
autoinstall:
  verson: 1
  network:
    version: 2
    ethernets:
      ens160:
      critical: true
      dhcp-identifier: mac
      dhcp4: true

However, if you try this you’ll get an error from autoinstall. If you dig through the log file from the installer, you’ll find reference to a missing key “network”. This is due to the installer having a bug. To work around this, you have to add an extra “network” level/section to the configuration

#cloud-config
autoinstall:
  verson: 1
  network:
   network:
    version: 2
    ethernets:
      ens160:
      critical: true
      dhcp-identifier: mac
      dhcp4: true

5.2 – Disc Configuration

To quote Jonathan Corbett, this section is ruthlessly undocumented. If you look at the autoinstall-user-data file from your 20.04 VM, you’ll see that the configuration isn’t exactly user friendly. This is from my basic VM which had a 30GB HDD:

#cloud-config
autoinstall:
  verson: 1
  storage:
    config:
    - {ptable: gpt, path: /dev/sda, wipe: superblock-recursive, preserve: false, name: '', grub_device: true, type: disk, id: disk-sda}
    - {device: disk-sda, size: 1048576, flag: bios_grub, number: 1, preserve: false, type: partition, id: partition-0}
    - {device: disk-sda, size: 32209108992, wipe: superblock, flag: '', number: 2, preserve: false, type: partition, id: partition-1}
    - {fstype: ext4, volume: partition-1, preserve: false, type: format, id: format-0}
    - {device: format-0, path: /, type: mount, id: mount-0}

6 – Going Further

The observant will have noticed that our “default” PXE Boot configuration file referenced a specific directory for the installer. The way to specify a per machine configuration is to name the file with the machine’s booting MAC address. e.g.

# cd  /var/lib/tftpboot/ubuntu2004/pxelinux.cfg
# mv default xx-xx-xx-xx-xx-xx

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s