Cobbler (v3.3.7) Ubuntu Deployment Guide
This guide assumes that you have a Fedora 34 server or workstation system configured to run Cobbler v3.3.7 similarly to the Cobbler v3.3.6 Beginner’s guide.
Table of Contents
- Objective
- Cobbler Server Prep
- Ubuntu 20.04 PXE Deployment
- Ubuntu 22.04 PXE Deployment
- Ubuntu 24.04 PXE Deployment
- Tips & Troubleshooting
Objective
Starting where the Beginner’s guide left off, further configure the Cobbler v3.3.7 server to deploy the latest 3 releases of Ubuntu Server LTS (Ubuntu 20.04, 22.04, 24.04) via PXE network boot, using the same system and network environment. This guide assumes that you still have selinux
and firewalld
configured and enabled as described in the Beginner’s guide.
Caveats
-
starting with Ubuntu 20.04, Canonical switched to using their in-house
cloud-init
autoinstall solution, which Cobbler 3.3.7 does not support natively, requiring a few advanced configurations.- Ubuntu did offer compatability/support with the Debian’s preseed autoinstallation model in the Ubuntu 20.04 Legacy release, but this guide only provides procedures for deploying Ubuntu systems using
cloud-init
.
- Ubuntu did offer compatability/support with the Debian’s preseed autoinstallation model in the Ubuntu 20.04 Legacy release, but this guide only provides procedures for deploying Ubuntu systems using
-
Despite my efforts (and unlike the Beginner’s Guide) Ubuntu 20.04 PXE clients will require an internet connection at the time of installation, since the
fallback: offline-install
option is not available in that version’scloud-init
implementation and was only introduced as of Ubuntu 22.04 release..- Also unlike my other guides, this PXE deployment will use the installation media (ISO file) instead of a repo mirror when installing the target OS (except for Ubuntu 20.04, however it still requires to use the ISO file in PXE process, so it’s very similar and consistent), so even though the distribution will be imported as usual, it’s important to make the ISO file available over HTTP as well.
Cobbler Server Prep
Cobbler v3.3.7 does not come with a sample template for the cloud-init
autoinstall files, so create those before getting started, as well as some Cobbler sync-triggers to correct the bootloader configurations for compatability with cloud-init
.
Dependencies
Create the new Cobbler template and snippets necessary to generate the cloud-init
autoinstall config file by copying the 3 text blocks below to new files with the name and path noted above each text block:
-
/var/lib/cobbler/templates/cloud-init_user-data
#cloud-config autoinstall: version: 1 apt: preserve_sources_list: true primary: - arches: [amd64, i386] uri: http://$http_server/cblr/links/$distro ## uri: http://us.archive.ubuntu.com/ubuntu - arches: [default] ## uri: http://$http_server/cblr/links/$distro uri: http://ports.ubuntu.com/ubuntu-ports fallback: offline-install identity: $SNIPPET('cloud-init_hostname') password: $default_password_crypted realname: ubuntu username: ubuntu kernel: package: linux-generic keyboard: layout: us toggle: null variant: '' locale: en_US.UTF-8 $SNIPPET('cloud-init_network') ssh: allow-pw: true install-server: true storage: layout: name: lvm sizing-policy: all package_update: false package_upgrade: false late-commands: ## Figure out if we're automating OS installation for a system or a profile #if $getVar('system_name','') != '' #set $what = "system" #else #set $what = "profile" #end if - wget -O /target/tmp/autoinstall-user-data.yaml http://$http_server/cblr/svc/op/autoinstall/$what/$name - chroot /target /bin/bash -s ssh-keygen -t rsa -b 2048 -m ssh2 -N "" -f /root/.ssh/id_rsa
-
/var/lib/cobbler/snippets/cloud-init_hostname
#if $getVar("system_name","") != "" #if $hostname != "" hostname: $hostname #else #set $myhostname = $getVar('name','').replace("_","-") hostname: $myhostname #end if #else ## profile based install so just provide one interface for starters #set $myhostname = $getVar('hostname',$getVar('name','cobbler')).replace("_","-") hostname: $myhostname #end if
-
/var/lib/cobbler/snippets/cloud-init_network
#if $getVar("system_name","") != "" network: ethernets: #set ikeys = $interfaces.keys() #import re #for $iname in $ikeys #set $idata = $interfaces[$iname] ## Ignore BMC interface #if $idata["interface_type"].lower() == "bmc" #continue #end if #end for #for $iname in $ikeys #set $idata = $interfaces[$iname] #set $mac = $idata["mac_address"] #set $static = $idata["static"] #set $ip = $idata["ip_address"] #set $netmask = $idata["netmask"] #set $type = $idata["interface_type"] ## Ignore BMC interface #if $type == "bmc" #continue #end if $iname: match: macaddress: $mac #if $static == True: #if $ip != "": #if $netmask != "": #set $mask = sum([bin(int(x)).count('1') for x in $netmask.split('.')]) dhcp4: false addresses: - $ip/$mask #else dhcp4: false addresses: - $ip/24 #end if #if $gateway != "": gateway4: $gateway #end if #if $name_servers and $name_servers[0] != "": nameservers: addresses: #for $dns in $name_servers - $dns #end for #end if #else dhcp4: true #end if #else dhcp4: true #end if #end for version: 2 #else ## profile based install so use DHCP network: ethernets: eth0: dhcp4: true version: 2 #end if
The above section should resemble the standard netplan YAML configuration file for Ubuntu once generated.
Assumptions: For automated Cobbler System deployments (not Profiles…), each system interface defined should have the corresponding MAC address defined (a standard requirement in Cobbler). Less intuitively, this solution only adds DNS servers to static interfaces with an IP address defined, since DNS servers are set per-system in Cobbler, but per-interface in Ubuntu cloud-init/netplan; the above snippet will revert any interface to DHCP if it is set to static but has no IP defined.
Create 2 Cobbler sync-triggers to correct the GRUB and PXELINUX boot configurations to support Ubuntu cloud-init
installations, which will run each time the cobbler sync
action is performed:
-
/var/lib/cobbler/triggers/sync/post/fix-ubuntu-profiles-GRUB_PXE.sh
#!/bin/bash for PROFILE in $(cobbler profile list); do DIST=$(cobbler profile report --name $PROFILE | grep ^Distribution | awk {' print $3 '}); VER=$(cobbler distro report --name $DIST | grep "OS Version" | awk {' print $4 '}); [[ ($VER == "focal" || $VER == "jammy" || $VER == "noble") ]] || continue; sed -i "s,auto-install/enable=true priority=critical netcfg/choose_interface=auto url=http://10.0.0.10/cblr/svc/op/autoinstall/profile/${PROFILE} hostname=.* domain=local.lan suite=${VER},," /var/lib/tftpboot/grub/x86_64_menu_items.cfg; sed -i "s,auto-install/enable=true priority=critical netcfg/choose_interface=auto url=http://10.0.0.10/cblr/svc/op/autoinstall/profile/${PROFILE} hostname=.* domain=local.lan suite=${VER},," /var/lib/tftpboot/pxelinux.cfg/default; DIST="" && VER=""; done
-
/var/lib/cobbler/triggers/sync/post/fix-ubuntu-systems-GRUB_PXE.sh
#!/bin/bash for SYSTEM in $(cobbler system list); do PROFILE=$(cobbler system report --name $SYSTEM | grep ^Profile | awk {' print $3 '}) DIST=$(cobbler profile report --name $PROFILE | grep ^Distribution | awk {' print $3 '}); VER=$(cobbler distro report --name $DIST | grep "OS Version" | awk {' print $4 '}); [[ ($VER == "focal" || $VER == "jammy" || $VER == "noble") ]] || continue; MAC=$(cobbler system report --name $SYSTEM | grep "MAC Addr" | awk {' print $4 '}) sed -i "s,auto-install/enable=true priority=critical netcfg/choose_interface=auto url=http://10.0.0.10/cblr/svc/op/autoinstall/system/${SYSTEM} hostname=.* domain=local.lan suite=${VER},," /var/lib/tftpboot/grub/system/$MAC; MAC=$(echo $MAC | sed 's,:,-,g'); sed -i "s,auto-install/enable=true priority=critical netcfg/choose_interface=auto url=http://10.0.0.10/cblr/svc/op/autoinstall/profile/${PROFILE} hostname=.* domain=local.lan suite=${VER},," /var/lib/tftpboot/pxelinux.cfg/01-$MAC; PROFILE="" && DIST="" && VER="" && MAC=""; done
Mark the above 2 cobbler sync-triggers as executable
chmod u+x /var/lib/cobbler/triggers/sync/post/fix-ubuntu-profiles-GRUB_PXE.sh
chmod u+x /var/lib/cobbler/triggers/sync/post/fix-ubuntu-systems-GRUB_PXE.sh
More info on cobbler triggers in the Tips & Troubleshooting section below
Download the latest 3 releases of Ubuntu Server LTS
cd ~/Downloads && wget https://releases.ubuntu.com/24.04/ubuntu-24.04.1-live-server-amd64.iso
cd ~/Downloads && wget https://releases.ubuntu.com/22.04/ubuntu-22.04.5-live-server-amd64.iso
cd ~/Downloads && wget https://releases.ubuntu.com/20.04/ubuntu-20.04.6-live-server-amd64.iso
Ubuntu 20.04 PXE Deployment
Mount the Ubuntu 20.04 live server installer and import to Cobbler
[ -d /mnt/Ubuntu] || mkdir /mnt/Ubuntu
mount -t iso9660 -o loop,ro ~/Downloads/ubuntu-20.04.6-live-server-amd64.iso /mnt/Ubuntu
cobbler import --name Ubuntu20 --path /mnt/Ubuntu
Copy the installation media to the public HTTP share (The location of this file will be used in the kernel-options
for relavent Cobbler Distros/Profiles/Systems)
mkdir -p /var/www/cobbler/pub/cloud-init/Ubuntu20
cp ~/Downloads/ubuntu-20.04.6-live-server-amd64.iso /var/www/cobbler/pub/cloud-init/Ubuntu20/.
Edit the kernel options for the new Cobbler Distro to install Ubuntu automatically by default:
NAME="Ubuntu20-casper-x86_64" && cobbler distro edit --name $NAME --kernel-options "root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url=http://10.0.0.10/cblr/pub/cloud-init/Ubuntu20/ubuntu-20.04.6-live-server-amd64.iso autoinstall cloud-config-url=http://10.0.0.10/cblr/svc/op/autoinstall/profile/$NAME" && unset NAME
alternatively, use the following kernel-options to install Ubuntu manually via PXE network boot
cobbler distro edit --name Ubuntu20-casper-x86_64 --kernel-options 'root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url=http://10.0.0.10/cblr/pub/cloud-init/Ubuntu20/ubuntu-20.04.6-live-server-amd64.iso cloud-config-url=/dev/null'
More info on these configs in the Tips & Troubleshooting section below.
Since the PXE client will install the OS from the internet, create a new autoinstall (cloud-init
) template from the file created above, changing the apt
uri.
sed -z 's, uri: http://$http_server/cblr/links/$distro\n## uri: http://us.archive.ubuntu.com/ubuntu,## uri: http://$http_server/cblr/links/$distro\n uri: http://us.archive.ubuntu.com/ubuntu,' /var/lib/cobbler/templates/cloud-init_user-data | tee /var/lib/cobbler/templates/Ubuntu20_cloud-init_user-data
Then configure it as the autoinstallation template for the Ubuntu 20.04 Cobbler Profile
cobbler profile edit --name Ubuntu20-casper-x86_64 --autoinstall Ubuntu20_cloud-init_user-data
Create a new Cobbler System to install Ubuntu 20.04 automatically based on the system’s (PXE client’s) MAC address, replacing the “aa:bb:cc:dd:ee:ff” with the MAC address of your PXE client, and being sure not to use a duplicate MAC or IP address of any other Cobbler System:
NAME="Ubuntu20-auto" && cobbler system add --name $NAME --profile Ubuntu20-casper-x86_64 --kernel-options "root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url=http://10.0.0.10/cblr/pub/cloud-init/Ubuntu20/ubuntu-20.04.6-live-server-amd64.iso autoinstall cloud-config-url=http://10.0.0.10/cblr/svc/op/autoinstall/system/$NAME" --mac-address "aa:bb:cc:dd:ee:ff" --static true --ip-address "10.0.0.20" --netmask "255.255.255.0" --gateway "10.0.0.1" --name-servers "10.0.0.1 1.1.1.1 10.0.0.10" --hostname "Ubuntu20" --netboot-enabled true && unset NAME
Alternatively, configure the Cobbler System kernel-options to run as a manual installation:
cobbler system add --name Ubuntu20 --profile Ubuntu20-casper-x86_64 --kernel-options 'root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url=http://10.0.0.10/cblr/pub/cloud-init/Ubuntu20/ubuntu-20.04.6-live-server-amd64.iso autoinstall cloud-config-url=/dev/null' --mac-address "aa:bb:cc:dd:ee:ff"
Finally, sync up Cobbler, then the PXE Client VM can be powered on and should automatically boot to PXE and install Ubuntu 20.04 to the VM HDD using the “Ubuntu20_cloud-init_user-data” cloud-init
template created above.
- The resulting system will have the
root
super-user account disabled, and will only be accessible with theubuntu
user specified in the cloud-init config file.
cobbler sync
the PXE Client will not install Ubuntu from the local mirror @
/var/www/cobbler/distro_mirror
, and since thefallback: ofline-install
option was not available for Ubuntu 20.04cloud-init
, this distro requires an internet connection to install, as detailed in this guide.
Ubuntu 22.04 PXE Deployment
Take similar steps as above to import and automatically deploy Ubuntu 22.04 LTS Server over PXE, using the original cloud-init_user-data
autoinstall template created above.
[ -d /mnt/Ubuntu ] || mkdir /mnt/Ubuntu
mount -t iso9660 -o loop,ro /home/fedora/Downloads/ubuntu-22.04.5-live-server-amd64.iso /mnt/Ubuntu
cobbler import --name Ubuntu22 --path /mnt/Ubuntu
mkdir -p /var/www/cobbler/pub/cloud-init/Ubuntu22
cp ~/Downloads/ubuntu-22.04.5-live-server-amd64.iso /var/www/cobbler/pub/cloud-init/Ubuntu22/.
NAME="Ubuntu22-casper-x86_64" && cobbler distro edit --name $NAME --kernel-options "root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url=http://10.0.0.10/cblr/pub/cloud-init/Ubuntu22/ubuntu-22.04.5-live-server-amd64.iso autoinstall cloud-config-url=http://10.0.0.10/cblr/svc/op/autoinstall/profile/$NAME" && unset NAME
cobbler profile edit --name Ubuntu22-casper-x86_64 --autoinstall cloud-init_user-data
NAME="Ubuntu22-auto" && cobbler system add --name $NAME --profile Ubuntu22-casper-x86_64 --kernel-options "root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url=http://10.0.0.10/cblr/pub/cloud-init/Ubuntu22/ubuntu-22.04.5-live-server-amd64.iso autoinstall cloud-config-url=http://10.0.0.10/cblr/svc/op/autoinstall/system/$NAME" --mac-address "aa:bb:cc:dd:ee:ff" --static true --ip-address "10.0.0.22" --netmask "255.255.255.0" --gateway "10.0.0.1" --name-servers "10.0.0.1 1.1.1.1 10.0.0.10" --hostname "Ubuntu22" --netboot-enabled true && unset NAME
cobbler sync
Again, the PXE Client is not installing via the local repo @
/var/www/cobbler/distro_mirror
, but now that thefallback: offline-install
option is available with Ubuntu 22.04cloud-init
, the installer will NOT require and internet connection to install, instead installing using the live server installer (.iso file) available on Cobbler’s public HTTP share and specified in the kernel options.
Ubuntu 24.04 PXE Deployment
First, modify /var/lib/cobbler/distro_signatures.json
to suppport Ubuntu 24.04 (which is not included with Cobbler at the time of writing) by pasting the following code block immediately following the Ubuntu 22 jammy
signature definition:
"noble": {
"signatures": [
"dists",
".disk"
],
"version_file": "Release|info",
"version_file_regex": "Suite: noble|Ubuntu 24.04",
"kernel_arch": "linux-headers-(.*)\\.deb",
"kernel_arch_regex": null,
"supported_arches": [
"i386",
"amd64"
],
"supported_repo_breeds": [
"apt"
],
"kernel_file": "(linux|vmlinuz(.*))",
"initrd_file": "initrd($|.gz$|.lz$)",
"isolinux_ok": false,
"default_autoinstall": "",
"kernel_options": "",
"kernel_options_post": "",
"template_files": "",
"boot_files": [],
"boot_loaders": {}
},
With this modification made, be careful not to use the
cobbler signature update
command on the Cobbler server, which will remove any user-defined signatures.
Sync up Cobbler in order to apply the changes
cobbler sync
Take similar steps as above to import and automatically deploy Ubuntu 24.04 LTS Server over PXE
[ -d /mnt/Ubuntu ] || mkdir /mnt/Ubuntu
mount -t iso9660 -o loop,ro /home/fedora/Downloads/ubuntu-24.04.1-live-server-amd64.iso /mnt/Ubuntu
cobbler import --name Ubuntu24 --path /mnt/Ubuntu
mkdir -p /var/www/cobbler/pub/cloud-init/Ubuntu24
cp ~/Downloads/ubuntu-24.04.1-live-server-amd64.iso /var/www/cobbler/pub/cloud-init/Ubuntu24/.
NAME="Ubuntu24-casper-x86_64" && cobbler distro edit --name $NAME --kernel-options "root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url=http://10.0.0.10/cblr/pub/cloud-init/Ubuntu24/ubuntu-24.04.1-live-server-amd64.iso autoinstall cloud-config-url=http://10.0.0.10/cblr/svc/op/autoinstall/profile/$NAME" && unset NAME
cobbler profile edit --name Ubuntu24-casper-x86_64 --autoinstall cloud-init_user-data
NAME="Ubuntu24-auto" && cobbler system add --name $NAME --profile Ubuntu24-casper-x86_64 --kernel-options "root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url=http://10.0.0.10/cblr/pub/cloud-init/Ubuntu24/ubuntu-24.04.1-live-server-amd64.iso autoinstall cloud-config-url=http://10.0.0.10/cblr/svc/op/autoinstall/system/$NAME" --mac-address "aa:bb:cc:dd:ee:ff" --static true --ip-address "10.0.0.24" --netmask "255.255.255.0" --gateway "10.0.0.1" --name-servers "10.0.0.1 1.1.1.1 10.0.0.10" --hostname "Ubuntu24" --netboot-enabled true && unset NAME
cobbler sync
Again, if using the
fallback: offline-install
option in thecloud-init
template for this System, the PXE Client will use the .iso file hosted by Cobbler as the source for installation.
Tips & Troubleshooting
-
The Cobbler 3.3.6 Beginner’s Guide Tips & Troubleshooting section contains some basic recommendations and limitations of Cobbler which will not be repeated here.
-
Cobbler triggers
-
Cobbler is normally a dynamic and responsive app that implements many options, parameters, and configurations on-demand through
edit|add|remove|etc...
actions, not requiring acobbler sync
to commit most changes. However, it is recommended to runcobbler sync
after any changes to a Cobbler Distro/Profile/System when using Cobbler sync-triggers in this manner (editing DHCP configs, boot options, etc…), unless you’re absolutely certain otherwise. -
Cobbler recommends writing triggers as Python modules and has a lot of good info in their docs, but the “old-style” bash script triggers used in this guide will get the job done, slowly.
-
-
Troubleshooting the installation
-
The Ubuntu installer will reboot the system automatically upon completing a
cloud-init
auto-install. To prevent this, append the following line to the end of the autoinstall template (cloud-init_user-data
) as the final command in thelate-commands:
section (be sure the spacing/indentation aligns with the rest of thelate-command
entries):rm /target/etc/apt/apt.conf.d/99needrestart
-
-
More info on
cloud-init
-
The
kernel-options
used above were based off of Ubuntu’s official docs -
Additional references:
-
(https://github.com/cobbler/cobbler/discussions/3573)[https://github.com/cobbler/cobbler/discussions/3573]
-
https://louwrentius.com/understanding-the-ubuntu-2004-lts-server-autoinstaller.html
-
https://cdimage.ubuntu.com/ubuntu-legacy-server/releases/20.04/release/
-
https://cloudinit.readthedocs.io/en/latest/howto/disable_cloud_init.html
-
https://vinfrastructure.it/2024/03/how-to-disable-cloud-init-on-ubuntu-server/
-
https://discourse.ubuntu.com/t/netbooting-the-live-server-installer/14510
-
https://askubuntu.com/questions/1406685/22-04-jammy-pxe-booting-help
-
https://www.molnar-peter.hu/en/ubuntu-jammy-netinstall-pxe.html
-
https://cloudinit.readthedocs.io/en/24.1/howto/run_cloud_init_locally.html
-
These all seem pretty legacy, no mention of recent releases or cloud-init
-
Enjoy Reading This Article?
Here are some more articles you might like to read next: