Setup PXE Boot Server using cloud-init for Ubuntu 20.04 [Step-by-Step]


Written By - admin
Advertisement

In this tutorial I will share step by step instructions to setu PXE boot server using cloud-init on Ubuntu 20.04.

 

Why not using kickstart to perform automated install in Ubuntu?

If you are coming from Red Hat or CentOS background then you are most likely familiar with using Kickstart for automated installation. Now we can also perform automated installation of Ubuntu 20.04 or older version using Kickstart but it is not completely supported. The official Ubuntu documentation talks about this very briefly with not much clear instructions on how this can be performed.

Now all the parameters in the Red Hat kickstart are not supported with Ubuntu, so you will end up using preseed for many things such as configuring partitions, networking etc.

But the biggest problem with using Kickstart for Ubuntu is that the normal Ubuntu Desktop and Live image do not support kickstart based installation so you have to use their legacy server release. These legacy server release images will be released only for Ubuntu 20.04 and will not be released for any future releases in Ubuntu as they want to promote their in-house cloud-init feature to perform the automated installation.

 

What is cloud-init or auto-install in Ubuntu?

This is a newly added feature in Ubuntu 20.04 which supersedes the preseeded mode of installation which was performed using debian-installer. The one big advantage of using cloud-init over debian-installer is that you don't need to specify answer to each installation option in cloud-init. By default cloud-init will consider the default value and proceed with the installation. It will fail only when there are no default values assigned unlike debian-installer (preseed) which will halt the installation for any and every missing input.

Although since this is a new feature so there is a lack of good documentation and debugging can be quite time consuming. You can read more about this on cloud-init official page.

 

Brief steps involved to configure PXE Boot Server with cloud-init

We will be performing the following steps to setup our PXE boot server to perform an automated installation of Ubuntu 20.04 using cloud-init.

  1. Download Ubuntu Image (We will use ubuntu-20.04.3-live-server-amd64.iso)
  2. Install and Configure TFTP
  3. Install and Configure DHCP
  4. Install and Configure HTTP
  5. Prepare cloud-init file
  6. Perform PXE Boot

 

Lab Environment

I have two physical servers running with Legacy BIOS wherein on one server I have manually installed Ubuntu 20.04 which will act as our server where we will install all TFTP, DHCP and other services. While we will use the other server as our client where we will perform the PXE boot for automated installation.

Advertisement

The server specs are as follows:

  • IP Address: 10.43.138.8
  • Hostname: ubuntu
  • Release: Ubuntu 20.04.3 LTS
  • Version: 20.04.3 LTS (Focal Fossa)

 

Pre-requisite

  • You will need an active internet connection on the server where we will have to download and install some packages.
  • You can place the downloaded Ubuntu image either on this server where we can use HTTP to load the image on the client or you can also mount the image directly on the client. But in this case the configuration may slightly differ. In this article we will assume that you have downloaded the Ubuntu live-server ISO and placed on your server.

 

Steps to configure PXE Boot Server using cloud-init on Ubuntu 20.04

Step-1: Install and Configure Apache Server

First of all, let's bring up our Apache server as we will need this to host our Ubuntu image and our configuration files required to perform PXE Boot.

# apt install apache2 -y

Next we created a new file ks-server.conf under /etc/apache2/sites-available/ with the following content:

# cat /etc/apache2/sites-available/ks-server.conf
<VirtualHost 10.43.138.8:80>
    ServerAdmin root@server1.example.com
    DocumentRoot /
    ServerName server.example.com
    ErrorLog ${APACHE_LOG_DIR}/ks-server.example.com-error_log
    CustomLog ${APACHE_LOG_DIR}/ks-server.example.com-access_log common
    <Directory /ks>
        Options Indexes MultiViews
        AllowOverride All
        Require all granted
    </Directory>
    <Directory /images>
        Options Indexes MultiViews
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

So, here basically we have configured virtual hosting for 2 directories i.e. /ks which will contain our cloud-init files and /images where we will place our ubuntu live-server iso image.

Next make sure these directories exist (you can create if not present) and have world readable permission:

root@ubuntu:~# ls -ld /images/
drwxr-xr-x 3 root root 4096 Jan  3 11:38 /images/

root@ubuntu:~# ls -ld /ks/
drwxr-xr-x 2 root root 4096 Jan 11 23:07 /ks/

Next start/restart and enable the apache service to start automatically on reboot:

# systemctl enable apache2 --now
Synchronizing state of apache2.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable apache2

Check the status of the service to make sure it has started successfully:

# systemctl status apache2

Setup PXE Boot Server using cloud-init for Ubuntu 20.04 [Step-by-Step]

If you face any issues then you can check the Error Log file which you have added in your virtual hosting configuration block under  /var/log/apache2/ directory.

root@ubuntu:/etc/apache2# ls -l /var/log/apache2/ks-server.example.com-*
-rw-r--r-- 1 root root 17891 Jan 11 23:10 /var/log/apache2/ks-server.example.com-access_log
-rw-r--r-- 1 root root 12859 Jan 11 21:59 /var/log/apache2/ks-server.example.com-error_log

Enable firewall for Apache web server:

# ufw allow Apache
Rules updated
Rules updated (v6)

Verify the status:

# ufw status
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
Apache                     ALLOW       Anywhere
22/tcp (v6)                ALLOW       Anywhere (v6)
Apache (v6)                ALLOW       Anywhere (v6)

 

I have created one more sub-directory inside /images for my testing:

Setup PXE Boot Server using cloud-init for Ubuntu 20.04 [Step-by-Step]

Here is the content of /ks accessed via apache server, you can for now ignore those files. We will discuss about them in the next section:

Setup PXE Boot Server using cloud-init for Ubuntu 20.04 [Step-by-Step]

So we know that our apache server is working properly

 

Step-2: Prepare cloud-init autoinstall file

This is the most tricky part of automating ubuntu installation using cloud-init as unlike Red Hat, we don't have a sample cloud-init configuration file to start with. For example, in Red Hat or CentOS we used to pick /root/anaconda.cfg as our base template and then we used to modify the required parameters for our network installation. But here we don't have any such template to pick as default.

I have written a detailed article covering the steps required to create this autoinstall configuration file. So you can follow the same to create one for your environment.

Here is my sample /ks/user-data file which I will be using for this installation:

root@ubuntu:/srv/tftp# cat /ks/user-data
#cloud-config
autoinstall:
  apt:
    geoip: true
    preserve_sources_list: false
    primary:
    - arches: [amd64, i386]
      uri: http://archive.ubuntu.com/ubuntu
    - arches: [default]
      uri: http://ports.ubuntu.com/ubuntu-ports
  identity: {hostname: ubuntu-server, password: $6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0,
    realname: ubuntu, username: ubuntu}
  keyboard: {layout: us, toggle: null, variant: ''}
  locale: en_US.UTF-8
  network:
    ethernets:
      eno49: {dhcp4: true}
      eno50: {critical: true, dhcp-identifier: mac, dhcp4: true}
    version: 2
  ssh: {allow-pw: true, authorized-keys: [], install-server: true}
  storage:
    config:
    - {ptable: gpt, serial: 3600508b1001c576619b6670156e25877, wwn: '0x600508b1001c576619b6670156e25877',
      path: /dev/sda, wipe: superblock, preserve: false, name: '', grub_device: true,
      type: disk, id: disk-sda}
    - {device: disk-sda, size: 1048576, flag: bios_grub, number: 1, preserve: false,
      grub_device: false, type: partition, id: partition-0}
    - {device: disk-sda, size: 1073741824, wipe: superblock, flag: '', number: 2,
      preserve: false, grub_device: false, type: partition, id: partition-1}
    - {fstype: ext4, volume: partition-1, preserve: false, type: format, id: format-0}
    - {device: disk-sda, size: 899074228224, wipe: superblock, flag: '', number: 3,
      preserve: false, grub_device: false, type: partition, id: partition-2}
    - name: ubuntu-vg
      devices: [partition-2]
      preserve: false
      type: lvm_volgroup
      id: lvm_volgroup-0
    - {name: ubuntu-lv, volgroup: lvm_volgroup-0, size: 214748364800B, wipe: superblock,
      preserve: false, type: lvm_partition, id: lvm_partition-0}
    - {fstype: ext4, volume: lvm_partition-0, preserve: false, type: format, id: format-1}
    - {path: /, device: format-1, type: mount, id: mount-1}
    - {path: /boot, device: format-0, type: mount, id: mount-0}
  updates: security
  version: 1

Next we will create /ks/meta-data file with the hostname of our server which we will assign to the client. You can also just create an empty file and place it under /ks directory.

Advertisement
# cat > /ks/meta-data <<EOF
instance-id: ubuntu-server
EOF

 

Step-3: Install and Configure TFTP Server

Next we will install and configure TFTP server to host the PXE boot files required to trigger the network installation.

apt install tftpd-hpa -y

To list the content of the installed package you can use dpkg command:

# dpkg -L tftpd-hpa
/.
/etc
/etc/init
/etc/init/tftpd-hpa.conf
/etc/init.d
/etc/init.d/tftpd-hpa
/usr
/usr/sbin
/usr/sbin/in.tftpd
/usr/share
/usr/share/doc
/usr/share/doc/tftpd-hpa
/usr/share/doc/tftpd-hpa/README
/usr/share/doc/tftpd-hpa/README.Debian
/usr/share/doc/tftpd-hpa/README.security
/usr/share/doc/tftpd-hpa/changelog.Debian.gz
/usr/share/doc/tftpd-hpa/copyright
/usr/share/doc/tftpd-hpa/examples
/usr/share/doc/tftpd-hpa/examples/sample.rules
/usr/share/man
/usr/share/man/man8
/usr/share/man/man8/in.tftpd.8.gz
/usr/share/man/man8/tftpd.8.gz

You can check the default configuration for TFTP in /etc/default/tftpd-hpa file:

# cat /etc/default/tftpd-hpa
# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure"

So, by default the TFTP server will look into /srv/tftp, so if you want to use any alternate path then you can update the same here. Verify that this path already exist, if not you can create the same and assign 755 permission to this directory to make sure everyone can access it.

# ls -ld /srv/tftp/
drwxr-xr-x 5 tftp root 4096 Jan 11 23:59 /srv/tftp/

Nest start/restart and enable the service to automatically start on server reboot:

# systemctl enable tftpd-hpa --now
tftpd-hpa.service is not a native service, redirecting to systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable tftpd-hpa

Check the status of the service to make sure it is started and running successfully:

# systemctl status tftpd-hpa

Setup PXE Boot Server using cloud-init for Ubuntu 20.04 [Step-by-Step]

 

Step-4: Configure PXE Boot Server

Next to perform automated installation over network, we will need some PXE boot files. These files can be collected from the Ubuntu live-server image which we have already downloaded and kept on our server.

Mount the image to some temporary mount path to be able to access the content:

# mount /home/ubuntu-20.04.3-live-server-amd64.iso /mnt
mount: /mnt: WARNING: device write-protected, mounted read-only.

Next search for initrd, vmlinux, and ldlinux.c32 inside this image.

# find /mnt/ \( -name "initrd" -o -name "vmlinuz" -o  -name "ldlinux.c32" \) -exec cp -apv {} /srv/tftp/ \;
'/mnt/casper/initrd' -> '/srv/tftp/initrd'
'/mnt/casper/vmlinuz' -> '/srv/tftp/vmlinuz'
'/mnt/isolinux/ldlinux.c32' -> '/srv/tftp/ldlinux.c32'

Now we also need pxelinux.0 to complete our PXE server configuration. This file is delivered with pxelinux package so you can install the same using apt command:

# apt install pxelinux -y

Next locate for pxelinux.0 file using find command.

# find /usr/ -name pxelinux.0
/usr/lib/PXELINUX/pxelinux.0

Now that we have the path of pxelinux.0, we can copy the same to our TFTP server location:

# cp -apv /usr/lib/PXELINUX/pxelinux.0 /srv/tftp/
'/usr/lib/PXELINUX/pxelinux.0' -> '/srv/tftp/pxelinux.0'

Here is the final content of our TFTP path and all of them have world readable permission:

root@ubuntu:/srv/tftp# ls -l
total 98088
drwxr-xr-x 5 tftp root     4096 Jan 11 23:59  ./
drwxr-xr-x 3 root root     4096 Jan  2 22:07  ../
-r--r--r-- 1 root root 86017541 Aug 24 14:30  initrd
-r--r--r-- 1 root root   120820 Aug 24 14:39  ldlinux.c32
-rw-r--r-- 1 root root    43140 Dec 23  2019  pxelinux.0
-r--r--r-- 1 root root 11772160 Aug 24 14:30  vmlinuz

 

Step-5: Create Boot Menu for automated installation

Next you can either decide to use Ubuntu's default boot menu which would require libcom32.c32, libutil.c32, vesamenu.c32 files. You can get these files from /usr/lib/syslinux/modules/bios/. In some cases it is recommended to just copy all the files from this location in case you find some graphical interface issue.

I personally prefer to create my own boot menu, here is the content of my boot.msg file which I have placed inside /srv/tftp:

Advertisement
root@ubuntu:/srv/tftp# cat boot.msg
Welcome to the installation of "My Ubuntu Server" !
Ubuntu 20.04 (Focal Fossa)
Version: 1.0
Architecture: x86_64

To start the installation enter :
    '1', '2' and press .

Available boot options:

  1 - Install Ubuntu 20.04 (Focal Fossa)
  2 - Boot from Harddisk (this is default)

Have a lot of fun...

 

Step-6: Create PXE configuration file

  • Once the client retrieves and executes pxelinux.0, it is hard-coded to look for a file from the pxelinux.cfg/ sub directory relative to where pxelinux.0 was found
  • In large deployments we create individual PXE configuration file per node.
  • The naming syntax of these PXE configuration file is very important
  • First, it will look for a file named after the MAC address, in the form 01-xx-xx-xx-xx-xx-xx
  • For example, in this example my client't NIC MAC Address is 08:00:27:83:1e:2a so my PXE configuration file will be 01-08-00-27-83-1e-2a
  • Next, it will look for a file named by the IP address as provided by the DHCP server.
  • The IP address is looked up in hexadecimal format.
  • You can use printf to get the hexadecimal format of an IP Address, for example to get the hexadecimal value of 10.10.10.12
# printf "%02x%02x%02x%02xn" 10 10 10 12
0a0a0a0cn
  • Since I am not assigning any static IP Address, I cannot use the hexadecimal format file. Although I can use MAC address based file.
  • If both MAC Address and hexadecimal format file are not found under pxelinux.cfg then the installer will look for "default" file

We will create a new directory /srv/tftp/pxelinux.cfg

root@ubuntu:/srv/tftp# mkdir pxelinux.cfg

Create the PXE configuration file /srv/tftp/pxelinux.cfg/default. Below is a sample content from my default file:

root@ubuntu:/srv/tftp# cat pxelinux.cfg/default
display boot.msg
timeout=60
ontimeout focal-live-install-autoinstall
default 1
prompt 0

label 1
  menu label ^Install Ubuntu 20.04
  kernel vmlinuz
  initrd initrd
  append url=http://10.43.138.8/images/ubuntu20/ubuntu-20.04.3-live-server-amd64.iso autoinstall ds=nocloud-net;s=http://10.43.138.8/ks/ cloud-config-url=/dev/null ip=dhcp fsck.mode=skip ---

label 2
  menu label Boot from ^local drive
  localboot 0x80

menu end

Let us understand the individual option used in our kernel menu

  • url: provide the ubuntu live-server image link
  • autoinstall: This will make sure that the server installer will not ask for any confirmation before writing to the disks
  • ds=nocloud-net: Means the instance is booting on a cloud of some sort, however do not expect the cloud metadata service to be available! This helps cloud-init not wait for the metadata service to appear. You can pass a custom metadata network service by passing the s= parameter
  • s=<seedlocation>: This allows you to set the 'seed location'. The value can be a url of 'file:///' format, or of 'http://' format. If you want to use http or another network based seed, then 'nocloud-net' must be used as the data source, rather than 'nocloud'. meta-data and user-data will be read from <seedlocation>meta-data and <seedlocation>user-data respectively. For more details you can read UEC/Images/KVMKernelOptions and NoCloud
  • cloud-config-url: Adding cloud-config-url=/dev/null to the kernel arguments does prevent cloud-init from downloading the ISO, and the ISO is only downloaded once.
  • ip=dhcp: This will assign the address via DHCP server
  • fsck.mode=skip: By default ubuntu installer will perform integrity check of the ISO which takes up some time so we will disable that.

 

Step-7: Install and configure DHCP

We will also need one DHCP server to provide our client with an IP Address. So let's go ahead and install required package:

# apt install isc-dhcp-server -y

This will install the dhcp package on your Ubuntu host. Next you can update /etc/dhcp/dhcpd.conf file to with the configuration details. Here is a sample input file from my setup:

allow bootp;
allow booting;
max-lease-time 1200;
default-lease-time 900;
log-facility local7;

option ip-forwarding    false;
option mask-supplier    false;

   subnet 10.43.138.0 netmask 255.255.255.224 {

       option routers 10.43.138.30;
       option domain-name-servers 127.0.0.1;
       range 10.43.138.20 10.43.138.26;
       next-server 10.43.138.8;
       filename "pxelinux.0";
   }

Here we have basically defined our subnet and netmask value. You can get this using different linux commands such as:

root@ubuntu:/srv/tftp# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.43.138.30    0.0.0.0         UG    20100  0        0 eno49
10.43.138.0     0.0.0.0         255.255.255.224 U     100    0        0 eno49
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eno49

Here eno49 is our primary interface which has 10.43.138.0 as the subnet and 255.255.255.224 as the netmask value. The option routers contain the gateway of your server IP, which we can again get using following command:

root@ubuntu:/srv/tftp# ip route
default via 10.43.138.30 dev eno49 proto static metric 20100
10.43.138.0/27 dev eno49 proto kernel scope link src 10.43.138.8 metric 100
169.254.0.0/16 dev eno49 scope link metric 1000

Here 10.43.138.30 is our default gateway which will act as a router for all incoming DHCP request.

The filename directive is used to define the PXE file which will be used to perform the autoinstall i.e. pxelinux.0 for legacy bios. If you had created any sub directory inside /srv/tftp such as /srv/tftp/pxelinux then you should add filename as "pxelinux/pxelinux.0"

We have defined a range between 10.43.138.20 and 10.43.138.26 to assign the IP address to our destination nodes which will be installed over the network. This range must be free and must not be in use by any other server.

Next enable and start the DHCP server service:

# systemctl enable isc-dhcp-server.service --now
Synchronizing state of isc-dhcp-server.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable isc-dhcp-server

Check the status of DHCP service to make sure it is started successfully:

root@ubuntu:/srv/tftp# systemctl status isc-dhcp-server.service
● isc-dhcp-server.service - ISC DHCP IPv4 server
     Loaded: loaded (/lib/systemd/system/isc-dhcp-server.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2022-01-12 09:22:41 IST; 4h 12min ago
       Docs: man:dhcpd(8)
   Main PID: 57854 (dhcpd)
      Tasks: 4 (limit: 154489)
     Memory: 4.5M
     CGroup: /system.slice/isc-dhcp-server.service
             └─57854 dhcpd -user dhcpd -group dhcpd -f -4 -pf /run/dhcp-server/dhcpd.pid -cf /etc/dhcp/dhcpd.conf

 

Step-8: Configure firewall

We already configured firewall for Apache as I wanted to show you the screenshot of apache server. But just to consolidate, add the following rule to allow Apache service:

# ufw allow Apache

Add the following rule to allow TFTP

# ufw allow from any to any proto udp port 69

Add the following rule to allow DHCP

# ufw allow bootps
# ufw allow from any to any port 53

Check the status ( I have some more firewall rules for other features):

# ufw status
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
Apache                     ALLOW       Anywhere
69/udp                     ALLOW       Anywhere
67/udp                     ALLOW       Anywhere
53/udp                     ALLOW       Anywhere
22/tcp (v6)                ALLOW       Anywhere (v6)
Apache (v6)                ALLOW       Anywhere (v6)
69/udp (v6)                ALLOW       Anywhere (v6)
67/udp (v6)                ALLOW       Anywhere (v6)
53/udp (v6)                ALLOW       Anywhere (v6)

 

Step-9: Perform PXE Boot using cloud-init

Now we are done with our configuration and we are ready to perform the automated installation using autoinstall configuration file.

Boot your client node and perform a network based installation. Now the shortcut button to boot over network may vary for different hardware but on most cases we are expected to press F12 to boot from network:

If your PXE Boot Server configuration is proper, then you should see the content of boot.msg file:

Setup PXE Boot Server using cloud-init for Ubuntu 20.04 [Step-by-Step]

 

Next we press 1 to initiate the installation and the TFTP files should get successfully downloaded as shown below

Setup PXE Boot Server using cloud-init for Ubuntu 20.04 [Step-by-Step]

 

Next the installer will pick the image from url we added in our grub file and if everything is good, then the installation will start:

Setup PXE Boot Server using cloud-init for Ubuntu 20.04 [Step-by-Step]

 

Now we wait for some time for the installation to complete and then we finally have our login prompt:

Setup PXE Boot Server using cloud-init for Ubuntu 20.04 [Step-by-Step]

 

Step-10: Verify target node connectivity

Try to connect to the target node using SSH:

root@ubuntu:~# ssh ubuntu@10.43.138.26
The authenticity of host '10.43.138.26 (10.43.138.26)' can't be established.
ECDSA key fingerprint is SHA256:7XHp99tX+slqyeAl6aI/Z8xXFcu0e8hf7KGw8duPCvQ.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.43.138.26' (ECDSA) to the list of known hosts.
ubuntu@10.43.138.26's password:
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-81-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Wed 12 Jan 2022 02:31:39 PM UTC

  System load:            0.0
  Usage of /:             5.1% of 195.86GB
  Memory usage:           0%
  Swap usage:             0%
  Temperature:            43.0 C
  Processes:              363
  Users logged in:        1
  IPv4 address for eno49: 10.43.138.26
  IPv6 address for eno49: 2001:1:1:1442:217:a4ff:fe77:32
  IPv4 address for eno50: 10.43.138.21
  IPv6 address for eno50: 2001:1:1:1442:217:a4ff:fe77:34


0 updates can be applied immediately.

Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Wed Jan 12 14:31:11 2022
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

So, our automate installation using PXE Boot Server configured with cloud-init is successful.

 

Troubleshooting autoinstaller related issues

It is possible you may face issues with the autoinstall configuration file, in which case you will most likely get a shell to debug the issue. You can navigate inside /var/log/installer/ where you can find all the autoinstaller log files which are quiet detailed and is helpful is troubleshooting.

Advertisement
# ls -l /var/log/installer/
total 812
-rw------- 1 root root   2017 Jan 12 11:24 autoinstall-user-data
drwxr-xr-x 2 root root   4096 Jan 12 11:21 block
-rw-r--r-- 1 root root     23 Jan 12 11:23 casper-md5check.json
-r-------- 1 root root   3856 Jan 12 11:23 curtin-install-cfg.yaml
-r-------- 1 root root 109362 Jan 12 11:24 curtin-install.log
-rw-r--r-- 1 root root 558728 Jan 12 11:24 installer-journal.txt
-rw-r--r-- 1 root root     66 Jan 12 11:23 media-info
lrwxrwxrwx 1 root root     31 Jan 12 11:21 subiquity-client-debug.log -> subiquity-client-debug.log.2649
-rw-r--r-- 1 root root    352 Jan 12 11:21 subiquity-client-debug.log.2649
lrwxrwxrwx 1 root root     30 Jan 12 11:21 subiquity-client-info.log -> subiquity-client-info.log.2649
-rw-r--r-- 1 root root    180 Jan 12 11:21 subiquity-client-info.log.2649
-rw-r--r-- 1 root root   3300 Jan 12 11:22 subiquity-curtin-install.conf
lrwxrwxrwx 1 root root     31 Jan 12 11:21 subiquity-server-debug.log -> subiquity-server-debug.log.2634
-rw-r--r-- 1 root root 108401 Jan 12 11:24 subiquity-server-debug.log.2634
lrwxrwxrwx 1 root root     30 Jan 12 11:21 subiquity-server-info.log -> subiquity-server-info.log.2634
-rw-r--r-- 1 root root  12388 Jan 12 11:24 subiquity-server-info.log.2634

 

Summary

In this tutorial I covered the step by step instructions to install and configure PXE boot server to perform automated installation of Ubuntu 20.04 using cloud-init configuration file. We were successfully able to bring up our Linux server using autoinstall configuration file from cloud-init without any manual intervention.

Now cloud-init autoinstall configuration file is a vast topic and I have just covered basic automated installation steps, I am yet to analyse the parts where we can further customise the user-data file to add or remove packages, execute pre and post scripts or commands etc which I will be slowly covering in upcoming articles.

Let me know your success or failures using the comment section.

 

Further Reading

Automated Server Installs
Netbooting the server installer on amd64

 

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

27 thoughts on “Setup PXE Boot Server using cloud-init for Ubuntu 20.04 [Step-by-Step]”

  1. Excellent brother,
    Will give this a try. There are very few posts regarding PXE setups. Yours is the best
    Thank you for the post

    Reply
  2. Hai. While fetching the iso its stating
    (initramfs) wget: short write: No space left on device
    done.
    Unable to find a live file system on the network

    Reply
      • Hai admin.
        No No im not executing wget. Once PXE starts, Client will receive the iso from server, it shows 5% , 10%, 15% (fetching from http) at 75% at this point of time it fails stating the above mentioned error

        Reply
        • But again why client is using wget and downloading the ISO. It should be used directly from the server? Or you have very less memory on your client? But I have actually never seen this error

          Reply
    • The PXE with cloud-init works only with LIVE version of the image. You can use packages section to specify custom packages to be installed.

      Reply
  3. Can you give a try with package session?
    Cos when i use package section or late command/early command, my automated installation does’nt work. It shows up manual installation

    Reply
  4. To whom it may concern, I am new to Linux and I followed step-by-step your guide and it didn’t work for me. Even the basic apache configuration results were not the same as you described with the screenshots. Perhaps you should be more specific with the relative paths on where to create folders. I am trying to replicate your configuration on a ubuntu server 20.04.03 on a VMware workstation and it is not working. Did you validate your own steps and documentation on a brand new server installation?

    Reply
    • The article already contains everything required to configure cloud-init. The article is not about apache.

      I also did mentioned where to look incase you face issues with apache configuration.

      And regarding your last comment, no I didn’t tested the steps. I just did the writing and the screenshots appeared magically with the working setup.

      Stop spamming.

      If you face issues, then describe the issue if you want help or else no need to give your value less comment.

      Reply
    • new to linux? and you are playing blame game?. haha funny. Post where you got stuck we can help you out rather than being dramatic.
      PS: I have followed the article works for me very well and doing lot more additional stuffs on the concept

      Reply
  5. First of all, I apologize if my candid feedback offended you by any means. The fact that you got very defensive shows something else. Spamming?
    What am I doing to spam you? Providing a feedback is spamming now?
    With all due respect. Be nice and professional to all you fellows. Rather them be lame when someone provides you a honest feedback. Going forward, if I use google to find something and your website shows up, I make sure to click on the next URL. There a lot of professional people out there that are polite and help. Have a great day, sir.

    Reply
    • Just saying that article didn’t work with no details is basically spamming. And then going ahead and asking if the article is tested or not is not rude in your terms?
      Do you realize the amount of time and effort we invest in writing and testing these articles, the least you can do is appreciate. Did you happen to check the screenshots before saying it was not tested? Do you expect me to test on every minor version of Ubuntu? on every platform? VMware workstation, virtualbox?

      You ask me to be more clear about where to create folders? Did you checked the virtual hosting config file. It clearly contains the path I have used for my setup. The ls -l output also contains the same and is added so you can check the permission required. If still you face issue then just describe the issue rather then giving un-necessary feedbacks.

      You never asked for help, you basically gave a judgmental feedback based on what you understood.

      I will stop discussion on this thread now, any further comments will be deleted.

      Reply
  6. Hi admin, I’m not getting home directory for the user which we created in identity section of cloud-init. Even manually I’m not able to create it when I use “usermod -m -d /home/ubuntu ubuntu”(tried with root) It states process is running with process id 1916. Also tried to kill the process no luck. Can u please help me out im badly stuck

    Reply
    • That’s weird. So are you able to login from the console using the specified user? If Yes, after login your are not logging into any home directory (I assume)?
      Does /home exists? If yes, are the permissions correct on /home?
      Can you share the output of ls -ld /home and df -h command
      What is the process running with PID 1916?

      Reply
  7. Yes from the console(ctrl+alt+f3) i am able to login. Yes after login i am not logging into any home directory. Getting no directory logging in with HOME=/

    /home exists.---> testlab@testlab:/$ ls -ld /home
                                 drwxr-xr-x 2 root root 0 Feb 14 16:43 /home
    df -h
    
    Filesystem                         Size  Used Avail Use% Mounted on
    udev                               1.9G     0  1.9G   0%           /dev
    tmpfs                              394M  1.6M  393M   1%    /run
    /dev/mapper/ubuntu--vg-ubuntu--lv   39G  9.2G   28G  26% /
    tmpfs                              2.0G     0  2.0G   0%        /dev/shm
    tmpfs                              5.0M     0  5.0M   0%      /run/lock
    tmpfs                              2.0G     0  2.0G   0%     /sys/fs/cgroup
    /dev/sda2                          976M  112M  798M  13%    /boot
    /dev/loop0                          33M   33M     0 100%    /snap/snapd/13804
    /dev/loop1                          56M   56M     0 100%    /snap/core18/2227
    /dev/loop2                          71M   71M     0 100%    /snap/lxd/22139
    tmpfs                              394M   36K  394M   1%    /run/user/140
    tmpfs                              394M  4.0K  394M   1%    /run/user/1000
    /dev/loop3                          44M   44M     0 100% /snap/snapd/24644

    1916 process is nothing but the users(testlab) login session. As per my guess, in ubuntu there’s no separate root login. we login with a user and then go root. Hence if i kill the process im out. Cant do usermod.

    Reply
    • What is the home directory assigned to your user? can you provide the output of

      grep user /etc/passwd

      What if you manually create the home directory, assign the required permission and then perform switch user?

      mkdir /home/user
      cp /etc/skel/.bashrc /home/user/
      chown -R user:user /home/user

      The HOME variable should be set to /home inside /etc/default/useradd
      I don’t see any other issue as such.

      Reply
  8. Hi Admin,

    i am new to Linux. Could you please let me know where exactly i should create the images and ks folder? when i just gave mkdir /images/ , it creates a folder but when i try to access the images folder from http:///image/ page reports “Not found” error.

    can you please help me here?

    Next make sure these directories exist (you can create if not present) and have world readable permission:

    root@ubuntu:~# ls -ld /images/
    drwxr-xr-x 3 root root 4096 Jan  3 11:38 /images/
    
    root@ubuntu:~# ls -ld /ks/
    drwxr-xr-x 2 root root 4096 Jan 11 23:07 /ks/
    Reply

Leave a Comment