dotlinux blog

Automated Installations of Multiple RHEL/CentOS 7 Distributions using PXE Server and Kickstart Files

In enterprise environments, deploying multiple Linux servers manually is time-consuming, error-prone, and inconsistent. Whether you’re managing a data center, a cloud infrastructure, or a lab, automating operating system (OS) installations ensures scalability, repeatability, and adherence to organizational standards.

This blog will guide you through setting up a PXE (Preboot Execution Environment) server to automate the installation of multiple RHEL (Red Hat Enterprise Linux) and CentOS 7 distributions. We’ll use Kickstart files to define installation parameters (e.g., partitioning, packages, network settings), enabling hands-free, unattended deployments. By the end, you’ll be able to boot bare-metal or virtual machines over the network and automatically install RHEL/CentOS 7 with custom configurations.

2026-05

Table of Contents#

  1. Prerequisites
  2. Understanding PXE and Kickstart
  3. Setting Up the PXE Server
    • 3.1 Install Required Services (DHCP, TFTP, HTTP)
    • 3.2 Configure DHCP Server
    • 3.3 Configure TFTP Server
    • 3.4 Configure HTTP Server (for Installation Media)
  4. Preparing the PXE Boot Environment
    • 4.1 Copy Boot Files from RHEL/CentOS 7 ISO
    • 4.2 Configure PXE Menu (pxelinux.cfg/default)
  5. Creating Kickstart Files
    • 5.1 Kickstart File Structure
    • 5.2 Example Kickstart for RHEL 7
    • 5.3 Example Kickstart for CentOS 7
  6. Testing the PXE Installation
  7. Troubleshooting Common Issues
  8. Advanced Customizations
  9. References

Prerequisites#

Before starting, ensure you have the following:

  • A Linux Server: A physical or virtual machine running RHEL/CentOS 7 (this will act as the PXE server).
  • Static IP Address: The PXE server must have a static IP (e.g., 192.168.1.100/24).
  • Network Access: The server must be on the same subnet as the clients (or use a DHCP relay if clients are on a different subnet).
  • RHEL/CentOS 7 ISO Files: Download the ISO images for the distributions you want to deploy (e.g., rhel-server-7.9-x86_64-dvd.iso, CentOS-7-x86_64-DVD-2009.iso).
  • Packages: Install dhcp, tftp-server, syslinux, httpd, and vsftpd (optional, for FTP) on the PXE server.
  • Client Machines: Target machines must support PXE booting (enable PXE/Network Boot in BIOS/UEFI).

Understanding PXE and Kickstart#

What is PXE?#

PXE is a protocol that allows a client machine to boot from a network server. It uses DHCP to obtain an IP address and locate the PXE server, then downloads a bootloader (e.g., pxelinux.0) via TFTP (Trivial File Transfer Protocol) to start the OS installation.

What is Kickstart?#

A Kickstart file is a text file containing installation instructions (e.g., disk partitioning, user accounts, package selection). When combined with PXE, Kickstart automates the entire OS installation process, eliminating manual input.

Setting Up the PXE Server#

The PXE server requires three core services:

  • DHCP: Assigns IP addresses to clients and points them to the TFTP server.
  • TFTP: Transfers the bootloader and kernel/initrd files to the client.
  • HTTP/FTP/NFS: Hosts the OS installation media and Kickstart files. We’ll use HTTP for simplicity.

3.1 Install Required Services#

First, install the necessary packages on the PXE server:

# Update system packages
sudo yum update -y
 
# Install DHCP, TFTP, HTTP, and Syslinux (for PXE bootloader)
sudo yum install -y dhcp tftp-server syslinux httpd

3.2 Configure DHCP Server#

The DHCP server will assign IP addresses to clients and specify the location of the PXE bootloader.

Step 1: Edit the DHCP Configuration File#

Create/modify /etc/dhcp/dhcpd.conf:

sudo vi /etc/dhcp/dhcpd.conf

Add the following configuration (adjust values for your network):

# Define the subnet and range of IPs to assign
subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.200 192.168.1.250;  # Client IP range
  option routers 192.168.1.1;         # Default gateway
  option subnet-mask 255.255.255.0;
  option domain-name-servers 8.8.8.8, 8.8.4.4;  # DNS servers
 
  # PXE-specific options
  next-server 192.168.1.100;  # IP of the PXE/TFTP server
  filename "pxelinux.0";      # Bootloader file (from Syslinux)
}

Step 2: Start and Enable DHCP Service#

sudo systemctl start dhcpd
sudo systemctl enable dhcpd
sudo systemctl status dhcpd  # Verify it’s running

3.3 Configure TFTP Server#

TFTP is used to transfer the PXE bootloader and kernel files to clients.

Step 1: Configure TFTP via xinetd#

TFTP is often managed by xinetd (a super-server). Edit /etc/xinetd.d/tftp:

sudo vi /etc/xinetd.d/tftp

Set disable = no and ensure the server_args point to the TFTP root directory (/var/lib/tftpboot):

service tftp
{
  socket_type             = dgram
  protocol                = udp
  wait                    = yes
  user                    = root
  server                  = /usr/sbin/in.tftpd
  server_args             = -s /var/lib/tftpboot
  disable                 = no
  per_source              = 11
  cps                     = 100 2
  flags                   = IPv4
}

Step 2: Start TFTP and xinetd#

sudo systemctl start xinetd
sudo systemctl enable xinetd
sudo systemctl status xinetd  # Verify

3.4 Configure HTTP Server (for Installation Media)#

HTTP will host the RHEL/CentOS 7 ISO contents and Kickstart files, making them accessible to clients during installation.

Step 1: Create a Directory for Installation Media#

Mount the RHEL/CentOS 7 ISO and copy its contents to the HTTP root (/var/www/html):

# Create directories for each distribution
sudo mkdir -p /var/www/html/rhel7 /var/www/html/centos7
 
# Mount RHEL 7 ISO (replace /path/to/rhel7.iso with your ISO path)
sudo mount -o loop /path/to/rhel7.iso /mnt
sudo cp -r /mnt/* /var/www/html/rhel7/
sudo umount /mnt
 
# Mount CentOS 7 ISO (replace /path/to/centos7.iso with your ISO path)
sudo mount -o loop /path/to/centos7.iso /mnt
sudo cp -r /mnt/* /var/www/html/centos7/
sudo umount /mnt

Step 2: Start and Enable HTTP Service#

sudo systemctl start httpd
sudo systemctl enable httpd
sudo systemctl status httpd  # Verify

Step 3: Configure Firewall and SELinux#

Allow HTTP and TFTP through the firewall:

# Allow HTTP (port 80)
sudo firewall-cmd --add-service=http --permanent
# Allow TFTP (port 69)
sudo firewall-cmd --add-service=tftp --permanent
# Reload firewall
sudo firewall-cmd --reload
 
# Set SELinux contexts for TFTP and HTTP (if SELinux is enforcing)
sudo chcon -R -t tftpdir_t /var/lib/tftpboot/
sudo chcon -R -t httpd_sys_content_t /var/www/html/

Preparing the PXE Boot Environment#

Now, we’ll walk through setting up the PXE bootloader and menu to let clients select which distribution to install.

4.1 Copy Boot Files from RHEL/CentOS 7 ISO#

The PXE boot process requires kernel (vmlinuz), initial RAM disk (initrd.img), and the Syslinux bootloader (pxelinux.0).

Step 1: Copy Syslinux Bootloader to TFTP Root#

Syslinux provides the pxelinux.0 bootloader. Copy it to /var/lib/tftpboot:

sudo cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/

Step 2: Copy Kernel and Initrd Files#

Copy vmlinuz (kernel) and initrd.img (initial RAM disk) from the RHEL/CentOS 7 ISO to the TFTP root. We’ll organize them into subdirectories for clarity:

# For RHEL 7
sudo mkdir -p /var/lib/tftpboot/rhel7
sudo cp /var/www/html/rhel7/isolinux/vmlinuz /var/lib/tftpboot/rhel7/
sudo cp /var/www/html/rhel7/isolinux/initrd.img /var/lib/tftpboot/rhel7/
 
# For CentOS 7
sudo mkdir -p /var/lib/tftpboot/centos7
sudo cp /var/www/html/centos7/isolinux/vmlinuz /var/lib/tftpboot/centos7/
sudo cp /var/www/html/centos7/isolinux/initrd.img /var/lib/tftpboot/centos7/

4.2 Configure PXE Menu (pxelinux.cfg/default)#

The PXE menu (default) lets clients select which distribution to install. Create the menu directory and file:

sudo mkdir -p /var/lib/tftpboot/pxelinux.cfg
sudo vi /var/lib/tftpboot/pxelinux.cfg/default

Add the following configuration (customize labels and paths as needed):

default menu.c32  # Use Syslinux menu system
prompt 0           # Hide "boot:" prompt
timeout 300        # Auto-boot after 30 seconds (300 tenths of a second)
 
MENU TITLE PXE Boot Menu - Select Distribution to Install
 
# RHEL 7 Installation
LABEL rhel7
  MENU LABEL Install RHEL 7 (Automated)
  KERNEL /rhel7/vmlinuz
  APPEND initrd=/rhel7/initrd.img inst.repo=http://192.168.1.100/rhel7 inst.ks=http://192.168.1.100/ks/rhel7-ks.cfg
 
# CentOS 7 Installation
LABEL centos7
  MENU LABEL Install CentOS 7 (Automated)
  KERNEL /centos7/vmlinuz
  APPEND initrd=/centos7/initrd.img inst.repo=http://192.168.1.100/centos7 inst.ks=http://192.168.1.100/ks/centos7-ks.cfg
 
# Fallback: Local Boot
LABEL local
  MENU LABEL Boot from Local Drive
  LOCALBOOT 0
  • inst.repo: Path to the HTTP-hosted installation media.
  • inst.ks: Path to the Kickstart file (we’ll create these next).

Creating Kickstart Files#

Kickstart files define installation parameters. We’ll create separate files for RHEL 7 and CentOS 7 (save them in /var/www/html/ks/ for HTTP access).

5.1 Kickstart File Structure#

A typical Kickstart file includes:

  • install: Specifies a fresh install (not upgrade).
  • url: Path to the installation repository (HTTP in our case).
  • lang, keyboard: Language and keyboard settings.
  • network: Network configuration (e.g., static IP or DHCP).
  • rootpw: Encrypted root password.
  • firewall, selinux: Security settings.
  • timezone: System timezone.
  • bootloader: Bootloader installation (e.g., GRUB).
  • part: Disk partitioning (e.g., LVM, ext4).
  • %packages: List of packages to install (e.g., @core, vim).
  • %post: Post-installation scripts (e.g., enable services, add users).

5.2 Example Kickstart for RHEL 7 (/var/www/html/ks/rhel7-ks.cfg)#

# RHEL 7 Kickstart File
install
url --url=http://192.168.1.100/rhel7  # HTTP repo path
 
lang en_US.UTF-8
keyboard us
network --bootproto=dhcp --device=eth0 --onboot=yes
 
rootpw --iscrypted $6$abc123...  # Replace with encrypted root password (generate with `openssl passwd -6`)
firewall --enabled --ssh
selinux --enforcing
timezone America/New_York
 
bootloader --location=mbr --driveorder=sda --append="crashkernel=auto rhgb quiet"
 
# Disk partitioning (LVM example: 50GB disk)
part /boot --fstype=xfs --size=500
part pv.01 --size=49500
volgroup vg_root pv.01
logvol / --fstype=xfs --name=lv_root --vgname=vg_root --size=40000
logvol swap --fstype=swap --name=lv_swap --vgname=vg_root --size=9500
 
%packages
@core
@base
vim
wget
net-tools
%end
 
%post
# Post-install scripts
systemctl enable sshd
useradd -m -G wheel devops
echo "devops:devops123" | chpasswd  # Replace with secure password
%end

5.3 Example Kickstart for CentOS 7 (/var/www/html/ks/centos7-ks.cfg)#

CentOS 7 Kickstart files are nearly identical to RHEL 7. Adjust the url and package groups if needed:

# CentOS 7 Kickstart File
install
url --url=http://192.168.1.100/centos7  # HTTP repo path
 
lang en_US.UTF-8
keyboard us
network --bootproto=dhcp --device=eth0 --onboot=yes
 
rootpw --iscrypted $6$abc123...  # Encrypted root password
firewall --enabled --ssh
selinux --enforcing
timezone America/New_York
 
bootloader --location=mbr --driveorder=sda --append="crashkernel=auto rhgb quiet"
 
# Partitioning (same as RHEL 7 example)
part /boot --fstype=xfs --size=500
part pv.01 --size=49500
volgroup vg_root pv.01
logvol / --fstype=xfs --name=lv_root --vgname=vg_root --size=40000
logvol swap --fstype=swap --name=lv_swap --vgname=vg_root --size=9500
 
%packages
@core
@base
epel-release  # CentOS-specific: EPEL repo
htop
%end
 
%post
systemctl enable sshd
%end

Testing the PXE Installation#

  1. Prepare a Client Machine: Ensure the client is on the same subnet as the PXE server. Enable PXE/Network Boot in BIOS/UEFI (usually by pressing F12, F2, or Del during boot).
  2. Boot the Client: The client will:
    • Request an IP via DHCP.
    • Download pxelinux.0 from the TFTP server.
    • Display the PXE menu (from pxelinux.cfg/default).
  3. Select a Distribution: Choose "Install RHEL 7" or "Install CentOS 7" from the menu.
  4. Automated Installation: The client will download the kernel/initrd, fetch the Kickstart file, and proceed with unattended installation.

Troubleshooting Common Issues#

  • DHCP Not Assigning IPs: Check /var/log/messages for DHCP errors. Ensure the DHCP server has a valid subnet and next-server is set.
  • TFTP Timeouts: Verify xinetd is running and the firewall allows TFTP (port 69). Use tftp 192.168.1.100 -c get pxelinux.0 to test TFTP connectivity.
  • Kickstart File Not Found: Ensure the inst.ks path in pxelinux.cfg/default is correct (e.g., http://192.168.1.100/ks/rhel7-ks.cfg). Test access via curl http://192.168.1.100/ks/rhel7-ks.cfg.
  • Partitioning Errors: Validate Kickstart partitioning syntax with ksvalidator (install via yum install pykickstart): ksvalidator rhel7-ks.cfg.

Advanced Customizations#

  • Multiple Kickstart Files: Create separate Kickstart files for different environments (e.g., rhel7-dev-ks.cfg, rhel7-prod-ks.cfg) and add menu entries in pxelinux.cfg/default.
  • UEFI Support: For UEFI clients, use grubx64.efi instead of pxelinux.0 and configure UEFI-specific DHCP options.
  • Driver Injection: Add custom drivers to initrd.img for hardware not supported by default.
  • Integration with Ansible: Use post-install scripts in Kickstart to run Ansible playbooks for further configuration.

References#


By following this guide, you’ve built a scalable PXE server to automate RHEL/CentOS 7 installations. This setup reduces deployment time, ensures consistency, and simplifies managing large fleets of servers. Let us know in the comments if you encountered any issues or have tips to share!