Escaping TFTP's Limitations
TFTP is adequate for transferring a 20KB bootloader, but an Ubuntu Server kernel (vmlinuz) is around 10MB, and a full OS disk image can be several gigabytes. Transferring that over TFTP's stop-and-wait UDP protocol would take an impractical amount of time.
Modern provisioning uses a chain-loading trick to escape TFTP as quickly as possible:
- Stage 1 (Hardware PXE): The NIC firmware uses TFTP to download a small program called iPXE (typically
ipxe.efifor UEFI systems orundionly.kpxefor legacy BIOS). This file is only ~300KB. - Stage 2 (iPXE takes over): iPXE replaces the dumb NIC firmware stack with a full software network stack running in RAM. It can now speak TCP, HTTP, and HTTPS.
- Stage 3 (Script execution): iPXE fetches an iPXE script from an HTTP server. This script tells it exactly what kernel and initrd to download and how to boot them.
A typical iPXE script is only three meaningful lines: one that fetches the Linux kernel over HTTP, one that fetches the initial RAM disk (a minimal filesystem the kernel uses during startup), and one that boots the machine with both loaded. This entire process happens in seconds over HTTP, compared to minutes over TFTP.
Why This Matters for Automation
Because iPXE scripts are just text files served over HTTP, you can make them dynamic. A provisioning server can inspect the MAC address of the requesting machine (passed in the HTTP request headers by iPXE) and serve a different script depending on which server is booting. Server A gets Ubuntu 22.04. Server B gets Rocky Linux 9. This is the foundation of how tools like Tinkerbell work.
Key Point: iPXE is the standard in any serious provisioning system. If you see a provisioning setup that transfers OS kernels directly over TFTP, it is either very old or misconfigured. The correct pattern is always: TFTP delivers iPXE, iPXE delivers everything else over HTTP.