DevOps · K8s · Volleyball · Travel  •  DevOps · K8s · Volleyball · Travel  •  DevOps · K8s · Volleyball · Travel
Explore NY Stream

Deploying Operating Systems Using Cobbler - PXE Boot

— ny_wk

Deploying Operating Systems Using Cobbler - PXE Boot

Cobbler PXE boot turns a single Linux server into a complete network install factory: it wires together DHCP, TFTP, a bootloader, and kickstart so a bare-metal machine can power on, fetch a boot menu, and install an operating system with zero local media. Instead of hand-editing a dozen config files for every host, you describe distros, profiles, and systems once, then run cobbler sync and let Cobbler generate everything for you.

This guide walks through the full chain end to end on a Red Hat-family server (CentOS/RHEL/Fedora/Rocky/AlmaLinux), with the original legacy commands shown alongside their modern Cobbler 3.x equivalents so the workflow still works on current systems running dnf, systemd, and firewalld.

How a Cobbler PXE Boot Actually Works

Before installing anything, it helps to understand the boot chain that PXE (Preboot eXecution Environment) follows. Every successful network install is just these steps happening in order:

  1. Power on + NIC firmware: The client's network card has a PXE ROM. With no local disk to boot, the firmware broadcasts a DHCP request asking for an IP address and boot instructions.
  2. DHCP response: The DHCP server hands back an IP, plus two critical fields: next-server (the IP of the TFTP server) and filename (the network bootloader to download, e.g. pxelinux.0 for BIOS or a grub/shim binary for UEFI).
  3. TFTP transfer: The client uses the lightweight TFTP protocol (UDP port 69) to download that bootloader from the server.
  4. Bootloader + menu: The bootloader (PXELINUX or GRUB) loads its config, shows a boot menu, and pulls the matching vmlinuz kernel and initrd image for the distro you choose.
  5. Kernel + kickstart: The installer kernel starts, then fetches the kickstart file over HTTP. That answer file scripts the entire install: partitioning, packages, root password, network, timezone, and post-install steps.
  6. Unattended install: Anaconda reads the repository tree (also served over HTTP) and installs the OS with no human at the keyboard.

Cobbler's whole value is that it owns this chain. It renders the DHCP config, manages the TFTP root, copies install media into a web-served repository, and templates the kickstart with the right repository URL automatically. You stop touching config files and start managing objects: distros, profiles, and systems.

Why Use Cobbler Instead of Hand-Rolling PXE

Building a network install environment by hand means configuring DHCP, TFTP, DNS, HTTP/FTP/NFS, writing per-client entries, authoring kickstart files, and extracting installation media into repositories. Each step is error-prone, and a single change (say, a different OS for one machine) forces you back into multiple files. At scale, the TFTP directory becomes an unmanageable pile of kernels and initrds.

Cobbler creates a central point of management and a layer of abstraction over all of it:

  • It reconfigures services (DHCP, TFTP) by regenerating their config from templates.
  • It extracts and mirrors install media into a web repository automatically.
  • It templates kickstarts (modern versions call them autoinstall templates) so the install URL and metadata are filled in for you.
  • It can integrate with configuration management (Ansible, Puppet) and power management (IPMI) to fully automate provisioning.

The mental model: you say "add a distro" or "change this machine's profile," and Cobbler handles creating or updating config files, restarting services, and laying down files in the right directories.

Prerequisites

  • A dedicated Linux server (physical or VM) with a static IP. In the examples below the server is named cobbler at 192.168.75.222 on the 192.168.75.0/24 network.
  • Authority over DHCP on that subnet. Either no other DHCP server exists, or you can disable it. Two DHCP servers on one LAN is the single most common reason PXE "randomly" fails.
  • 5–10 GB of free space per distribution under /var. Cobbler mirrors media into /var/www/cobbler/ (legacy) or /var/www/cobbler/distro_mirror/ (Cobbler 3.x).
  • A full DVD ISO of the OS you want to deploy (not a Live CD or netinstall image).
  • Root or sudo access, and a client machine able to PXE boot on the same network for verification.

Step 1 — Handle SELinux

For a first build, setting SELinux to permissive avoids AVC denials that can quietly break Cobbler, because the shipped policy sometimes lags behind Cobbler's feature set. Disabling it entirely also works for a lab box.

Legacy (CentOS 6, edit and reboot):

  1. Edit /etc/sysconfig/selinux and set SELINUX=disabled (or SELINUX=permissive).
  2. Reboot to apply: reboot.

Modern equivalent (no reboot needed to switch to permissive):

  1. setenforce 0 to switch immediately.
  2. Make it persistent in /etc/selinux/config with SELINUX=permissive.

If you want to keep SELinux enforcing in production, that is fully supported — just be prepared to read AVC logs (ausearch -m avc) and adjust booleans/policy as Cobbler reports them.

Step 2 — Install Cobbler and Its Dependencies

On EL6 the packages came from EPEL. Legacy install:

  1. Add EPEL: rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
  2. Install the stack: yum install -y dhcp cobbler pykickstart mod_python tftp tftp-server

Modern equivalent (EL8/EL9, Fedora). The package set changed — mod_python is gone, xinetd is gone, and TFTP is a systemd socket:

  1. Enable EPEL: dnf install -y epel-release
  2. Install Cobbler: dnf install -y cobbler dhcp-server tftp-server pykickstart

On modern releases Cobbler talks to Apache through WSGI (the cobbler package pulls in what it needs), so you no longer install mod_python manually.

Step 3 — Enable TFTP and rsync

Legacy (xinetd-managed): EL6 ran TFTP and rsync under xinetd. You edited each unit and flipped disable = yes to disable = no:

  1. Edit /etc/xinetd.d/tftp → set disable = no.
  2. Edit /etc/xinetd.d/rsync → set disable = no.

Modern (systemd socket): there is no xinetd. Enable the socket-activated service instead:

  1. systemctl enable --now tftp.socket
  2. systemctl enable --now rsyncd.service (only if you mirror over rsync)

Step 4 — Start Core Services

Legacy (SysV init):

  1. for i in xinetd httpd cobblerd; do service $i restart; chkconfig $i on; done
  2. chkconfig tftp on and chkconfig rsync on

Modern (systemd; Apache is httpd on EL, apache2/httpd on Fedora):

  1. systemctl enable --now httpd
  2. systemctl enable --now cobblerd

Step 5 — Download the Network Bootloaders

Cobbler needs the actual bootloader binaries (pxelinux.0, GRUB EFI images, etc.) staged in its TFTP tree.

  • Legacy: cobbler get-loaders fetched them from a remote source.
  • Modern (Cobbler 3.x): cobbler get-loaders still exists, but the recommended command is cobbler mkloaders, which builds the bootloader files locally from the grub2-efi/syslinux packages already on the system. Install grub2-efi-x64, grub2-efi-x64-modules, and syslinux first if PXE clients are missing their loader.

Step 6 — Edit Cobbler Settings

Settings live in /etc/cobbler/settings (legacy, YAML) or /etc/cobbler/settings.yaml (Cobbler 3.x, strict YAML). Because it is YAML, a stray tab or bad indent will stop cobblerd from starting — edit carefully. The three settings that matter most for a basic PXE build:

SettingValueWhy
server192.168.75.222IP clients contact for HTTP/TFTP. Never 0.0.0.0 — it is not a listening address.
next_server192.168.75.222TFTP server IP advertised over DHCP/PXE. Usually identical to server. (Cobbler 3.x splits this into next_server_v4.)
manage_dhcp1 (or true)Lets Cobbler generate dhcpd.conf from its template.

Two more worth setting now:

  • Default root password: set default_password_crypted to a hash you control. Generate one with openssl passwd -6 (SHA-512; the older -1 MD5 hashes are obsolete) and paste the output, keeping the surrounding quotes.
  • DHCP management module (Cobbler 3.x): in /etc/cobbler/modules.conf confirm module = managers.isc under [dhcp] so Cobbler writes ISC dhcpd.conf.

Step 7 — Customize the DHCP Template

Cobbler does not edit /etc/dhcp/dhcpd.conf directly; it renders it from /etc/cobbler/dhcp.template (a Cheetah template) every time you run cobbler sync. Back up the original first, then adapt the subnet block to your LAN:

  1. cp /etc/cobbler/dhcp.template /etc/cobbler/dhcp.template.orig
  2. Edit /etc/cobbler/dhcp.template so the subnet matches your network:

The key block to adjust looks like this (note the $next_server token — leave it intact so Cobbler injects your next_server setting):

  • subnet 192.168.75.0 netmask 255.255.255.0 {
  •   option routers 192.168.75.1;
  •   option subnet-mask 255.255.255.0;
  •   option domain-name-servers 192.168.75.1;
  •   range dynamic-bootp 192.168.75.100 192.168.75.254;
  •   default-lease-time 21600;
  •   max-lease-time 43200;
  •   next-server $next_server;
  • }

The shipped template also contains a class "pxeclients" block that matches the PXE vendor-class identifier and chooses the right bootloader by architecture (BIOS gets pxelinux.0; UEFI variants get the appropriate grub/elilo EFI binary). Leave that logic alone unless you have a specific reason to change it. Critically, do not edit anything below the #for dhcp_tag in ... line — that is template machinery, not config.

Step 8 — Import a Distribution

The cobbler import command is the workhorse. It detects the OS type/version, copies the full media tree into the web-served mirror, and auto-creates one or more distro/profile pairs with sane defaults.

  1. Mount the DVD or ISO:
    • Physical disc: mount /dev/sr0 /mnt
    • ISO file: mount -t iso9660 -o loop,ro /path/to/CentOS-DVD.iso /mnt
  2. Run the import (this copies several GB, so be patient):
    cobbler import --path=/mnt --name=CentOS_6.5_x86_64 --arch=x86_64

The --arch flag is optional but useful: full DVDs sometimes ship multiple architectures, and pinning the arch stops Cobbler from creating duplicate i386 and x86_64 objects. After import, inspect what was created:

  • List distros: cobbler distro list
  • List profiles: cobbler profile list
  • See full detail: cobbler distro report --name=CentOS_6.5_x86_64

In the distro report, notice the Kickstart Metadata field carrying a tree variable — that is the HTTP URL where install files live, and it gets substituted into your kickstart template automatically. Fields shown as <<inherit>> fall back to the settings file or to a parent object (profile/system), which is how Cobbler's inheritance keeps things DRY.

Step 9 — Create a Kickstart (Autoinstall) Template

The kickstart is the unattended-install answer file. A good starting point is the anaconda-ks.cfg generated by a manual install. Copy it into Cobbler's templates directory:

  • Legacy path: /var/lib/cobbler/kickstarts/centos65.ks
  • Cobbler 3.x path: /var/lib/cobbler/templates/centos65.ks (the concept was renamed from kickstart to autoinstall)

A minimal, working EL kickstart looks like this:

  • install
  • url --url http://192.168.75.222/cobbler/ks_mirror/CentOS_6.5_x86_64/
  • lang en_US.UTF-8
  • keyboard us
  • zerombr
  • network --onboot yes --device eth0 --bootproto dhcp --noipv6
  • rootpw --iscrypted $6$REPLACE_WITH_YOUR_HASH
  • firewall --service=ssh
  • authconfig --enableshadow --passalgo=sha512
  • selinux --enforcing
  • timezone Asia/Kolkata
  • bootloader --location=mbr --driveorder=sda --append="crashkernel=auto rhgb quiet"
  • clearpart --linux --drives=sda
  • %packages --nobase ... @core ... %end

Better still, replace the hard-coded URL with Cobbler's template variable $tree (e.g. url --url=$tree) so the same kickstart works for any distro — Cobbler fills in the correct mirror path per profile. Generate the password hash with openssl passwd -6 and never reuse the example hash from any tutorial.

Modern note: RHEL/CentOS Stream 8+ deprecated several legacy kickstart commands. The bare install keyword and authconfig are gone — use authselect directives and drop the install line. Validate any kickstart with ksvalidator centos65.ks before relying on it.

Step 10 — Register the Distro and Profile

If cobbler import already created a distro/profile, you may only need to attach your custom kickstart. To do it explicitly:

  1. Add (or confirm) the distro, pointing at the kernel and initrd inside the mirror:
    cobbler distro add --name=CentOS_6.5_x86_64 --kernel=/var/www/cobbler/ks_mirror/CentOS_6.5_x86_64/isolinux/vmlinuz --initrd=/var/www/cobbler/ks_mirror/CentOS_6.5_x86_64/isolinux/initrd.img
  2. Create a profile that binds the distro to your kickstart:
    cobbler profile add --name=CentOS_6.5_KS --distro=CentOS_6.5_x86_64 --kickstart=/var/lib/cobbler/kickstarts/centos65.ks

Cobbler 3.x flag change: --kickstart= became --autoinstall=, and you pass the template's basename (e.g. --autoinstall=centos65.ks) rather than a full path. So the modern form is cobbler profile add --name=CentOS_6.5_KS --distro=CentOS_6.5_x86_64 --autoinstall=centos65.ks.

Step 11 — Sync Everything

Nothing you have configured takes effect until Cobbler renders it out. First run the built-in sanity check, then sync:

  1. cobbler check — lists suggestions (firewall, SELinux, missing packages). Most are advisory, but pay attention to anything about iptables/firewalld and SELinux.
  2. Restart the daemon if check told you to: systemctl restart cobblerd (legacy: service cobblerd restart).
  3. cobbler sync — this is the moment of truth. Cobbler renders /etc/dhcp/dhcpd.conf, writes the TFTP boot files and PXE menus, validates the DHCP config with dhcpd -t, and restarts dhcpd. A clean run ends with TASK COMPLETE.

A failed sync here almost always points to a real problem (bad YAML in settings, a broken DHCP template, or a missing bootloader) — fix it now rather than after a client fails to boot.

Step 12 — Open the Firewall

PXE needs several ports reachable from the client subnet: DHCP (UDP 67/68), TFTP (UDP 69), and HTTP (TCP 80) for the kickstart and repo.

Legacy (iptables):

  1. iptables -I INPUT -p tcp -s 192.168.75.0/24 --dport 80 -j ACCEPT
  2. iptables -I INPUT -p udp -s 192.168.75.0/24 --dport 69 -j ACCEPT
  3. service iptables save

Modern (firewalld):

  1. firewall-cmd --permanent --add-service={dhcp,tftp,http,https}
  2. firewall-cmd --reload

After any firewall change, re-run your services and one more cobbler sync to be sure everything is consistent.

Step 13 — Optional: Add a System Object

A profile alone is enough to PXE boot any machine that picks it from the menu. But for repeatable, hands-off provisioning of a specific host, create a system object keyed to the client's MAC address. The more detail you give it, the more Cobbler automates.

  1. Create the system from a profile (only name + profile are required):
    cobbler system add --name=web01 --profile=CentOS_6.5_KS
  2. Pin a static NIC by MAC and IP:
    cobbler system edit --name=web01 --interface=eth0 --mac=00:11:22:AA:BB:CC --ip-address=192.168.75.50 --netmask=255.255.255.0 --static=1 --dns-name=web01.example.com
  3. Add gateway and hostname (set per-system, not per-NIC):
    cobbler system edit --name=web01 --gateway=192.168.75.1 --hostname=web01.example.com

Editing a system triggers a lite sync that regenerates the PXE file in the TFTP root, but it does not rewrite dhcpd.conf or bounce the DHCP service. After adding a static interface, run a full cobbler sync so the static lease lands in dhcpd.conf and DHCP restarts.

Common Pitfalls and How to Fix Them

  • A rogue second DHCP server. If a home router or another server also answers DHCP, clients may get a lease from it with no PXE options and the boot stalls. Disable the other DHCP server or isolate the install network.
  • SELinux denials. If TFTP downloads or HTTP fetches fail despite correct config, check ausearch -m avc -ts recent. Set permissive while building, then re-enable with proper booleans.
  • Closed firewall ports. The classic symptom is the client getting an IP and bootloader but timing out on TFTP or the kickstart fetch — open UDP 69 and TCP 80.
  • Forgot to sync. Object changes are invisible until cobbler sync (or a lite sync) runs. When in doubt, sync.
  • BIOS vs UEFI bootloader mismatch. UEFI clients need a GRUB/shim EFI binary, not pxelinux.0. Run cobbler mkloaders and confirm the DHCP pxeclients class serves the right file per architecture.
  • Secure Boot. On modern hardware, Secure Boot rejects unsigned loaders. Use signed shim+GRUB or disable Secure Boot in firmware for lab use.
  • Out of disk under /var. Each imported distro consumes 5–10 GB. If /var is small, relocate the Cobbler data directories or mount more storage before importing.

Verification — PXE Boot a Test Client

The real test is booting a fresh machine over the network:

  1. In the client's firmware/BIOS, set network/PXE as the first boot device (or hit the one-time boot menu key and pick the NIC).
  2. Power on. Watch for the DHCP lease, then a line showing it downloading pxelinux.0 (or the EFI loader) over TFTP.
  3. When the Cobbler boot menu appears, select your profile (e.g. CentOS_6.5_KS).
  4. The installer kernel loads, pulls the kickstart, and the unattended install proceeds to completion with no further input.

If the menu never appears, work backward through the chain: confirm the lease (journalctl -u dhcpd or /var/log/messages), then TFTP (test with tftp 192.168.75.222 -c get pxelinux.0), then HTTP (open http://192.168.75.222/cobbler/ks_mirror/ in a browser). Whichever step fails tells you exactly which service to fix.

Key Takeaways

  • Cobbler automates the entire PXE chain — DHCP, TFTP, bootloader, and kickstart — so you manage objects (distros, profiles, systems) instead of editing config files.
  • The boot order is fixed and worth memorizing: DHCP → TFTP → bootloader → kernel/initrd → kickstart over HTTP → unattended install.
  • Three settings make or break a build: server, next_server, and manage_dhcp — and the DHCP subnet template must match your real network.
  • Nothing applies until cobbler sync runs. Use cobbler check first, fix what it flags about SELinux and the firewall, then sync.
  • On Cobbler 3.x, expect modern equivalents: dnf/systemd/firewalld, settings.yaml, --autoinstall instead of --kickstart, cobbler mkloaders, and no xinetd.

Frequently Asked Questions

What is the difference between a Cobbler profile and a system?

A profile binds a distro to a kickstart and represents a reusable build recipe — any machine can pick it from the PXE menu. A system is a specific host keyed to a MAC address; it can carry static IP, gateway, hostname, and power-management details, enabling fully hands-off, repeatable provisioning of that exact machine.

Does Cobbler still work on RHEL 9, Rocky, and AlmaLinux?

Yes. Cobbler 3.x runs on current EL 8/9 and Fedora. The workflow is the same, but the tooling is modern: install with dnf, manage services with systemd, open ports with firewalld, edit /etc/cobbler/settings.yaml, use --autoinstall templates, and build loaders with cobbler mkloaders.

Why does my client get an IP but never load the boot menu?

That points to the TFTP step. Common causes are a closed UDP port 69, a missing or wrong bootloader (BIOS vs UEFI), or SELinux blocking TFTP reads. Verify with tftp <server> -c get pxelinux.0, check the firewall, and confirm cobbler mkloaders staged the right loader for the client's architecture.

Do I need DNS, FTP, and NFS to use Cobbler?

No. A minimal PXE install needs only DHCP, TFTP, and HTTP — Cobbler serves the kickstart and the repository tree over HTTP via Apache. DNS, FTP, and NFS are optional and only relevant for larger environments or specific install methods.

Found this useful? Subscribe on YouTube @explorenystream for more hands-on Linux and sysadmin walkthroughs.