By following this article to the end, you should be able to configure and use PXE and Kickstart server tools for Virtual Machine provisioning on KVM. KVM is an open source full virtualization solution for hardware architectures that support hardware virtualization. A library called libvirt provides a common API for managing KVM virtualization solution.
To create a fully automated installation of Virtual Machine on KVM, we need a network installation server that’s configured with TFTP, PXE, and a Kickstart file for initiating OS installation by booting from the network.
Preboot eXecution Environment (PXE) technology provides a mechanism for bootstrapping a computer using a network server. The computer where the operating system is installed should have a network interface that supports PXE, and the system firmware must enable PXE support.
The following list of services must be provided by the network boot infrastructure:
- TFTP Server – Provides the boot images to start the installer, with the command-line options.
- DHCP server – Provides initial client network configurations, and the location of TFTP server with a usable boot image
- Kickstart and Media server – This can be HTTP, FTP, or NFS server to provide the installation media and a shared Kickstart file for OS installation.
PXE Booting Process
The following series of actions takes place when using PXE for automated OS installation.
- A client machine at boot, through its network interface card, sends a DHCPDISCOVER broadcast packet in the network with required PXE options
- Configured DHCP server on the network will respond with a DHCPOFFER. The offer contains the IP address the client will get, and information about location of the PXE server.
- The client then responds with a DHCPREQUEST – requesting for IP assignment
- DHCP server sends a DHCPACK, with this is the TFTP (Trivial FTP) server URL of a network boot loader
- Client downloads the boot file from TFTP server and loads it (pxelinux.0)
- The loaded boot loader gets configuration file and Kickstart files from TFTP and HTTP/FTP/NFS server respectively. The files instructs it how to download and start OS installer.
- The files are used to boot the client
Configuring the PXE Boot Environment
Our setup is based on these configuration options.
System type | Hostname | IP Address |
DHCP/TFTP/HTTP Server | bastion-server.kvmlab.net | 192.168.177.2 |
Kickstart server | bastion-server.kvmlab.net | 192.168.177.2 |
Virtual Machine deployed via PXE | vm0.kvmlab.net | Assigned by DHCP Server |
KVM Hypervisor is required installed and configured on your host system. Check the guides in the following links for complete setup steps:
- Install KVM Hypervisor on Ubuntu
- How To Install KVM Hypervisor on Debian
- How To Install KVM on Fedora
- Install KVM on RHEL 8 / CentOS 8 / Rocky Linux 8 / AlmaLinux 8
- Install KVM on Arch Linux / Manjaro
Step 1 – Create Virtual Network (optional, you can use existing network without DHCP)
A bridge used should not have DHCP function as this will be handled by a DHCP Server virtual machine that we’ll install. These operations are to be performed on your KVM hypervisor host.
Ensure bridge utility package is installed.
### RHEL Based systems ###
sudo yum -y install vim bridge-utils
### Debian Based systems ###
sudo apt update
sudo apt install vim bridge-utils
Create a new virtual network creation configuration file.
vim br-pxe-net.xml
Modify these contents. You can replace IP information and bridge name to your liking and paste them inside the file.
br-pxe
Create a virtual network using this file file created; modify if need be:
$ sudo virsh net-define --file br-pxe-net.xml
Network br-pxe defined from br-pxe-net.xml
Enable automatic starting on the bridge created.
$ sudo virsh net-autostart br-pxe
Network br-pxe marked as autostarted
Then ensure the bridge interface is online
$ sudo virsh net-start br-pxe
Network br-pxe started
Confirm that the bridge is available and active:
$ sudo virsh net-list
Name State Autostart Persistent
--------------------------------------------
br-pxe active yes yes
default active yes yes
$ brctl show
bridge name bridge id STP enabled interfaces
br-pxe 8000.525400d64edf yes
virbr0 8000.525400929ef5 yes
OVS Bridge
If using Open vSwitch bridge instead of Linux bridge, network script configuration file will have contents similar to below
$ sudo vim /etc/sysconfig/network-scripts/ifcfg-br-pxe
DEVICE=br-pxe
BOOTPROTO=none
ONBOOT=yes
TYPE=OVSBridge
DEVICETYPE=ovs
USERCTL=yes
PEERDNS=yes
IPV6INIT=no
IPADDR=192.168.177.1
PREFIX=24
Start the interface and check IP configurations:
$ sudo ifup br-pxe
$ ip ad show dev br-pxe
12: br-pxe: mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:d6:4e:df brd ff:ff:ff:ff:ff:ff
inet 192.168.78.1/24 brd 192.168.78.255 scope global br-pxe
valid_lft forever preferred_lft forever
Allowing nating using IPtables firewall:
sudo iptables -t nat -A POSTROUTING -o enp0s31f6 -s 192.168.78.1/24 -j MASQUERADE
Step 2 – Create Bastion Virtual Machine (PXE,TFTP,HTTP and Kickstart Server)
Here we create a Virtual Machine that runs services to support network boot infrastructure.
- Apache httpd web server
- DHCP Server
- PXE/TFTP services
Install libguestfs-tools package which provides virt-builder
command line tool.
### RHEL Based systems ###
sudo yum -y install libguestfs-tools
### Fedora Linux systems ###
sudo dnf -y install guestfs-tools
### Debian Based systems ###
sudo apt -y install libguestfs-tools
List available OS templates:
sudo virt-builder -l
In this guide we’ll use Fedora template. Let’s create
sudo virt-builder fedora-36 --format qcow2 \
--size 30G -o /var/lib/libvirt/images/kvm-bastion-server.qcow2 \
--root-password password:StrongRootPassw0rd
Where:
- fedora-36 is the template used to create a new virtual machine
- /var/lib/libvirt/images/kvm-bastion-server.qcow2 is the path to VM qcow2 image
- StrongRootPassw0rd is the root user password
Command execution output:
[ 0.6] Downloading: http://builder.libguestfs.org/fedora-36.xz
############################################################################################################################################################################################### 100.0%############################################################################################################################################################################################### 100.0%
[ 14.7] Planning how to build this image
[ 14.7] Uncompressing
[ 18.8] Resizing (using virt-resize) to expand the disk to 30.0G
[ 42.7] Opening the new disk
[ 47.2] Setting a random seed
[ 47.2] Setting passwords
[ 48.2] Finishing off
Output file: /var/lib/libvirt/images/kvm-bastion-server.qcow2
Output size: 30.0G
Output format: qcow2
Total usable space: 30.0G
Free space: 28.9G (96%)
Create Virtual Machine from generated image.
Using Linux bridge:
sudo virt-install \
--name kvm-bastion-server \
--ram 2048 \
--vcpus 2 \
--disk path=/var/lib/libvirt/images/kvm-bastion-server.qcow2 \
--os-type linux \
--os-variant rhel8.0 \
--network bridge=br-pxe \
--graphics none \
--serial pty \
--console pty \
--boot hd \
--import
Using openVSwitch bridge: Ref How To Use Open vSwitch Bridge on KVM Virtual Machines
sudo virt-install \
--name bastion-server \
--ram 2048 \
--disk path=/var/lib/libvirt/images/kvm-bastion-server.qcow2 \
--vcpus 2 \
--os-type linux \
--os-variant rhel8.0 \
--network=bridge:br-pxe,model=virtio,virtualport_type=openvswitch \
--graphics none \
--serial pty \
--console pty \
--boot hd \
--import
Our bastion VM creation process is started. Once ready login with root and assigned password:
...omitted output ...
[ OK ] Reached target Preparation for Network.
Starting Network Manager...
[ OK ] Started Network Manager.
[ OK ] Reached target Network.
Starting Network Manager Wait Online...
Starting Permit User Sessions...
Starting Hostname Service...
[ OK ] Finished Permit User Sessions.
Starting Hold until boot process finishes up...
Starting Terminate Plymouth Boot Screen...
[ 4.160192] IPv6: ADDRCONF(NETDEV_CHANGE): enp1s0: link becomes ready
.....
fedora login: root
Password:
Reset root password:
[[email protected] ~]# passwd
Changing password for user root.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
You will notice the Virtual Machine doesn’t have IP address. The reason is that we disabled DHCP service in our natted bridge.
[[email protected] ~]# ip ad
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp1s0: mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:0d:c3:34 brd ff:ff:ff:ff:ff:ff
inet6 fe80::5054:ff:fe0d:c334/64 scope link noprefixroute
valid_lft forever preferred_lft forever
$ nmcli con show
NAME UUID TYPE DEVICE
enp1s0 50bdb463-8d8f-4053-9e3d-b3bbea6f5b1e ethernet --
Let’s create assign an IP address to the interface using NMCLI tool.
sudo nmcli con mod enp1s0 \
ipv4.method manual \
ipv4.address 192.168.177.2/24 \
ipv4.gateway 192.168.177.1 \
ipv4.dns 192.168.177.1 \
connection.autoconnect yes
Restart the interface to ensure it uses configured settings:
$ sudo nmcli con down enp1s0 && sudo nmcli con up enp1s0
Connection 'enp1s0' successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/5)
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/6)
Check network configs:
$ nmcli con show
NAME UUID TYPE DEVICE
enp1s0 50bdb463-8d8f-4053-9e3d-b3bbea6f5b1e ethernet enp1s0
$ ip ad
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp1s0: mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:0d:c3:34 brd ff:ff:ff:ff:ff:ff
inet 192.168.177.2/24 brd 192.168.177.255 scope global noprefixroute enp1s0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe0d:c334/64 scope link noprefixroute
valid_lft forever preferred_lft forever
Next we set the correct hostname of our Bastion server
sudo hostnamectl set-hostname bastion-server.kvmlab.net
Set correct timezone as well
sudo timedatectl set-timezone Africa/Nairobi
sudo chronyc sources
Enable Virtual Machine automatic start if you want on KVM:
sudo virsh autostart kvm-bastion-server
Step 3 – Setup DHCP Server for PXE Booting environment
Perform OS upgrade before deploying other services. The server being used here in this guide is Fedora.
sudo dnf -y upgrade
sudo dnf -y install git vim wget curl bash-completion tree tar libselinux-python3 firewalld
Reboot the server after the upgrade is done.
sudo reboot
Install DHCP server package
sudo dnf -y install dhcp-server
Move original DHCP server configuration file to backup:
sudo mv /etc/dhcp/dhcpd.conf,.bak
Create a new DHCP server configuration file
sudo vim /etc/dhcp/dhcpd.conf
Modify and paste the following data into the file
authoritative;
ddns-update-style interim;
default-lease-time 14400;
max-lease-time 14400;
allow booting;
allow bootp;
#Default gateway
option routers 192.168.177.1;
#DHCP network broadcast address
option broadcast-address 192.168.177.255;
#DHCP network subnet mask
option subnet-mask 255.255.255.0;
#IP address of DNS server
option domain-name-servers 192.168.177.1;
#Default NTP server
option ntp-servers time.google.com;
#Default domain name
option domain-name "kvmlab.net";
subnet 192.168.177.0 netmask 255.255.255.0
range 192.168.177.20 192.168.177.50;
# this is PXE specific
filename "pxelinux.0";
#PXE Server IP Address
next-server 192.168.177.2;
Save the configs and start dhcpd service:
$ sudo systemctl enable --now dhcpd
Created symlink /etc/systemd/system/multi-user.target.wants/dhcpd.service → /usr/lib/systemd/system/dhcpd.service.
Check service status to confirm it started without errors:
$ systemctl status dhcpd
● dhcpd.service - DHCPv4 Server Daemon
Loaded: loaded (/usr/lib/systemd/system/dhcpd.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2022-02-04 20:31:01 EAT; 23s ago
Docs: man:dhcpd(8)
man:dhcpd.conf(5)
Main PID: 3187 (dhcpd)
Status: "Dispatching packets..."
Tasks: 1 (limit: 2328)
Memory: 9.9M
CPU: 13ms
CGroup: /system.slice/dhcpd.service
└─3187 /usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid
Feb 04 20:31:01 bastion.kvmlab.net dhcpd[3187]: Config file: /etc/dhcp/dhcpd.conf
Feb 04 20:31:01 bastion.kvmlab.net dhcpd[3187]: Database file: /var/lib/dhcpd/dhcpd.leases
Feb 04 20:31:01 bastion.kvmlab.net dhcpd[3187]: PID file: /var/run/dhcpd.pid
Feb 04 20:31:01 bastion.kvmlab.net dhcpd[3187]: Source compiled to use binary-leases
Feb 04 20:31:01 bastion.kvmlab.net dhcpd[3187]: Wrote 0 leases to leases file.
Feb 04 20:31:01 bastion.kvmlab.net dhcpd[3187]: Listening on LPF/enp1s0/52:54:00:0d:c3:34/192.168.177.0/24
Feb 04 20:31:01 bastion.kvmlab.net dhcpd[3187]: Sending on LPF/enp1s0/52:54:00:0d:c3:34/192.168.177.0/24
Feb 04 20:31:01 bastion.kvmlab.net dhcpd[3187]: Sending on Socket/fallback/fallback-net
Feb 04 20:31:01 bastion.kvmlab.net dhcpd[3187]: Server starting service.
Feb 04 20:31:01 bastion.kvmlab.net systemd[1]: Started DHCPv4 Server Daemon.
Allow DHCPD service on the firewall
sudo firewall-cmd --add-service=dhcp --permanent
sudo firewall-cmd --reload
Step 4 – Configure TFTP and PXE environment
Install TFTP server and syslinux packages on the bastion host.
sudo dnf -y install tftp-server syslinux
Start and enable TFTP service using systemctl command:
sudo systemctl enable --now tftp.socket
Allow tftp service on firewall:
sudo firewall-cmd --add-service=tftp --permanent
sudo firewall-cmd --reload
Copy initial configurations files and create required directories:
sudo cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
sudo cp /usr/share/syslinux/menu.c32,vesamenu.c32,ldlinux.c32,libcom32.c32,libutil.c32 /var/lib/tftpboot/
sudo mkdir /var/lib/tftpboot/pxelinux.cfg
The pxelinux.cfg
directory contains the default configuration file used by any system PXE-booting from this TFTP service.
Step 5 – Install and configure httpd web server
A web server is needed to host installation media files used during PXE boot process. For this guide we’ve chosen Apache httpd as a web server of choice.
sudo dnf -y install httpd
Let’s edit httpd configuration file and set Listen port to 8080. This is to avoid any conflicts with other applications that can be hosted on the same server using port 80.
$ sudo vi /etc/httpd/conf/httpd.conf
#Around line 45
Listen 8080
Start and enable httpd service
sudo systemctl enable --now httpd
Allow port 8080 if you have firewalld service active on the server.
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
Remove welcome page and restart httpd service
sudo /etc/httpd/conf.d/welcome.conf
sudo systemctl restart httpd
Step 6 – Download OS installation DVD ISO files
We’ll create a directory where all ISO files are to be stored.
mkdir pxe_iso_files
cd pxe_iso_files
The ISO download process will depend on your desired OS to be installed using PXE server. As this guide is geared more to RHEL based systems, we have shared download URLs for standard EL systems.
Downloading CentOS Stream 8 ISO:
wget http://centos.mirror.liquidtelecom.com/8-stream/isos/x86_64/CentOS-Stream-8-x86_64-latest-dvd1.iso
Rocky Linux 8:
wget https://download.rockylinux.org/pub/rocky/8/isos/x86_64/Rocky-8.5-x86_64-dvd1.iso
AlmaLinux 8 DVD:
wget http://iad.mirror.rackspace.com/almalinux/8.5/isos/x86_64/AlmaLinux-8.5-x86_64-dvd.iso
Oracle Linux 8:
wget https://yum.oracle.com/ISOS/OracleLinux/OL8/u5/x86_64/OracleLinux-R8-U5-x86_64-dvd.iso
Fedora 36 Server:
wget https://fedora.mirror.liquidtelecom.com/fedora/linux/releases/36/Server/x86_64/iso/Fedora-Server-dvd-x86_64-36-1.5.iso
Step 7 – Mounting ISO files on a web server root directory
List downloaded ISO files to confirm which ones are available locally.
$ ls -1
AlmaLinux-8.5-x86_64-dvd.iso
CentOS-Stream-8-x86_64-latest-dvd1.iso
OracleLinux-R8-U5-x86_64-dvd.iso
Rocky-8.5-x86_64-dvd1.iso
Fedora-Server-dvd-x86_64-36-1.5.iso
Next we create a directory in our web server root where ISO files will be mounted.
sudo mkdir /var/www/html/pxe
Create directories for each Linux distribution ISO. Customize commands shared to suit your use scenario.
### Rocky Linux 8 ###
sudo mkdir /var/www/html/pxe/rockylinux8
sudo mount -t iso9660 -o loop,ro Rocky-8.5-x86_64-dvd1.iso /var/www/html/pxe/rockylinux8
### AlmaLinux 8 ###
sudo mkdir /var/www/html/pxe/almalinux8
sudo mount -t iso9660 -o loop,ro AlmaLinux-8.5-x86_64-dvd.iso /var/www/html/pxe/almalinux8
### Oracle Linux 8 ###
sudo mkdir /var/www/html/pxe/oraclelinux8
sudo mount -t iso9660 -o loop,ro OracleLinux-R8-U5-x86_64-dvd.iso /var/www/html/pxe/oraclelinux8
### CentOS 8 Stream ###
sudo mkdir /var/www/html/pxe/centos8stream
sudo mount -t iso9660 -o loop,ro CentOS-Stream-8-x86_64-latest-dvd1.iso /var/www/html/pxe/centos8stream
### Fedora Server ###
sudo mkdir /var/www/html/pxe/fedora
sudo mount -t iso9660 -o loop,ro Fedora-Server-dvd-x86_64-36-1.5.iso /var/www/html/pxe/fedora
Mounted images can be checked with df
command:
$ df -hT | grep /var/www/html/pxe
/dev/loop0 iso9660 10G 10G 0 100% /var/www/html/pxe/rockylinux8
/dev/loop1 iso9660 9.9G 9.9G 0 100% /var/www/html/pxe/almalinux8
/dev/loop2 iso9660 10G 10G 0 100% /var/www/html/pxe/oraclelinux8
/dev/loop3 iso9660 11G 11G 0 100% /var/www/html/pxe/centos8stream
/dev/loop4 iso9660 2.1G 2.1G 0 100% /var/www/html/pxe/fedora
List of files on each mount point:
$ ls /var/www/html/pxe/centos8stream
AppStream BaseOS EFI LICENSE TRANS.TBL images isolinux media.repo
$ ls /var/www/html/pxe/rockylinux8/
AppStream BaseOS EFI LICENSE TRANS.TBL images isolinux media.repo
$ ls /var/www/html/pxe/almalinux8
AppStream BaseOS EFI TRANS.TBL images isolinux media.repo
$ ls /var/www/html/pxe/oraclelinux8
AppStream BaseOS EFI EULA GPL RELEASE-NOTES-en RELEASE-NOTES-en.html RPM-GPG-KEY RPM-GPG-KEY-oracle TRANS.TBL extra_files.json images isolinux media.repo
$ ls /var/www/html/pxe/fedora
EFI Fedora-Legal-README.txt LICENSE Packages TRANS.TBL images isolinux media.repo repodata
View from a web browser:
Copy Linux and initrd images to PXE boot directory /var/lib/tftpboot
Copy the files as indicated in the following commands for each Linux distribution.
### Rocky Linux 8 ###
sudo mkdir /var/lib/tftpboot/rockylinux8
sudo cp /var/www/html/pxe/rockylinux8/images/pxeboot/vmlinuz,initrd.img /var/lib/tftpboot/rockylinux8
### AlmaLinux 8 ###
sudo mkdir /var/lib/tftpboot/almalinux8
sudo cp /var/www/html/pxe/almalinux8/images/pxeboot/initrd.img,vmlinuz /var/lib/tftpboot/almalinux8
### Oracle Linux 8 ###
sudo mkdir /var/lib/tftpboot/oraclelinux8
sudo cp /var/www/html/pxe/oraclelinux8/images/pxeboot/initrd.img,vmlinuz /var/lib/tftpboot/oraclelinux8
### CentOS 8 Stream ###
sudo mkdir /var/lib/tftpboot/centos8stream
sudo cp /var/www/html/pxe/centos8stream/images/pxeboot/initrd.img,vmlinuz /var/lib/tftpboot/centos8stream
### Fedora Server ###
sudo mkdir /var/lib/tftpboot/fedora
sudo cp /var/www/html/pxe/fedora/images/pxeboot/initrd.img,vmlinuz /var/lib/tftpboot/fedora
Where:
- initrd.img is the initial RAM disk image
- vmlinuz is the OS Kernel
Tree structure of /var/lib/tftpboot
after adding the directories and boot files.
$ sudo yum -y install tree
$ tree /var/lib/tftpboot/
/var/lib/tftpboot/
|-- almalinux8
| |-- initrd.img
| `-- vmlinuz
|-- centos8stream
| |-- initrd.img
| `-- vmlinuz
|-- fedora36
| |-- initrd.img
| `-- vmlinuz
|-- ldlinux.c32
|-- libcom32.c32
|-- libutil.c32
|-- menu.c32
|-- oraclelinux8
| |-- initrd.img
| `-- vmlinuz
|-- pxelinux.0
|-- pxelinux.cfg
| `-- default
|-- rockylinux8
| |-- initrd.img
| `-- vmlinuz
`-- vesamenu.c32
6 directories, 17 files
Step 8 – Configure PXE Boot for manual OS installation without Kickstart
Let’s open the default PXE configuration file for editing.
sudo vim /var/lib/tftpboot/pxelinux.cfg/default
The following contents can be modified to work for the operating system you intend to install.
default menu.c32
#default vesamenu.c32
prompt 0
timeout 600
ONTIMEOUT 1
menu title ######## PXE Boot Menu ########
label 1
menu label ^1) Install Rocky Linux 8
menu default
kernel rockylinux8/vmlinuz
append initrd=rockylinux8/initrd.img ip=dhcp inst.repo=http://192.168.177.2:8080/pxe/rockylinux8
label 2
menu label ^2) Install AlmaLinux 8
menu default
kernel almalinux8/vmlinuz
append initrd=almalinux8/initrd.img ip=dhcp inst.repo=http://192.168.177.2:8080/pxe/almalinux8
label 3
menu label ^3) Install Oracle Linux 8
menu default
kernel oraclelinux8/vmlinuz
append initrd=oraclelinux8/initrd.img ip=dhcp inst.repo=http://192.168.177.2:8080/pxe/oraclelinux8
label 4
menu label ^4) Install CentOS Stream 8
menu default
kernel centos8stream/vmlinuz
append initrd=centos8stream/initrd.img ip=dhcp inst.repo=http://192.168.177.2:8080/pxe/centos8stream
label 5
menu label ^5) Install Fedora Server
menu default
kernel fedora/vmlinuz
append initrd=fedora/initrd.img ip=dhcp inst.repo=http://192.168.177.2:8080/pxe/fedora
Step 9 – Configure PXE for Unattended installation using Kickstart
For better security, we generate encrypted root password:
python3 -c 'import crypt,getpass;pw=getpass.getpass();print(crypt.crypt(pw) if (pw==getpass.getpass("Confirm: ")) else exit())'
Inout and confirm password
Password:
Confirm:
$6$.4Cl.oED14zGg5qT$nDrjUFRjhDUS9L8dvYgsvhZLy20RykH7da.AiQspYDsvNJFYCchz9jbOmwY544WeC7exxrqGFb.Yea2YnaAMD1
Create a directory that will contain Kickstart files in your web server
sudo mkdir /var/www/html/ks
Creation of Kickstart file for each Linux distribution with ISO mounted.
### AlmaLinux 8 ###
sudo vim /var/www/html/ks/almalinux8-ks.cfg
### Rocky Linux 8 ###
sudo vim /var/www/html/ks/rockylinux8-ks.cfg
### Oracle Linux 8 ###
sudo vim /var/www/html/ks/oraclelinux8-ks.cfg
### CentoS 8 Stream ###
sudo vim /var/www/html/ks/centos8stream-ks.cfg
The following example shows a Kickstart file for an automatic installation of Rocky / AlmaLinux / Oracle / CentOS Stream 8 Linux. What is to be changed is installation source and AppStream baseurl.
# License agreement
eula --agreed
# Enable graphical installation
graphical
#Base installation source
url --url="http://192.168.177.2:8080/pxe/rockylinux8"
# AppStream installation source
repo --name="AppStream" --baseurl=http://192.168.177.2:8080/pxe/rockylinux8/AppStream
#Network bootproto and hostname
network --bootproto=dhcp --hostname=localhost.localdomain
# Encrypted root password
rootpw --iscrypted replace-me-with-encrypted-password
#rootpw --plaintext root_password_in_clear_text
# System Locale
lang en_US.UTF-8
# Keyboard layout
keyboard --vckeymap=us --xlayouts='us'
#Timezone
timezone Africa/Nairobi --isUtc
# Run the Setup Agent on first boot
firstboot --enable
#Initialize partition tables
ignoredisk --only-use=vda
zerombr
clearpart --none --initlabel
#Single / partion
##autopart
autopart --nohome --nolvm --noboot
#Reboot after installation
reboot
#Packages to install
%packages --ignoremissing --instLangs=en_US.utf8
@^graphical-server-environment
kexec-tools
vim
bash-completion
openssh-clients
selinux-policy-devel
net-tools
bzip2
rsync
dnf-utils
network-scripts
%end
Fedora Linux Kickstart file:
# License agreement
eula --agreed
# Enable graphical installation
graphical
#Base installation source
url --url="http://192.168.177.2:8080/pxe/fedora"
#Network bootproto and hostname
network --bootproto=dhcp --hostname=localhost.localdomain
# Encrypted root password
rootpw --iscrypted replace-me-with-encrypted-password
#rootpw --plaintext root_password_in_clear_text
# System Locale
lang en_US.UTF-8
# Keyboard layout
keyboard --vckeymap=us --xlayouts='us'
#Timezone
timezone Africa/Nairobi --isUtc
# Run the Setup Agent on first boot
firstboot --enable
#Initialize partition tables
ignoredisk --only-use=vda
zerombr
clearpart --none --initlabel
#Single / partion
##autopart
autopart --nohome --nolvm --noboot
#Reboot after installation
reboot
#Packages to install
%packages --ignoremissing --instLangs=en_US.utf8
@Desktop
kexec-tools
vim
bash-completion
openssh-clients
selinux-policy-devel
net-tools
bzip2
rsync
dnf-utils
network-scripts
%end
List of kickstart files as stored in the web server
For more reading on Kickstart, check out:
Update /var/lib/tftpboot/pxelinux.cfg/default file
Updated contents of /var/lib/tftpboot/pxelinux.cfg/default
file to include kickstart location.
#default menu.c32
default vesamenu.c32
prompt 0
timeout 600
ONTIMEOUT 1
display boot.msg
menu title ######## PXE Boot Menu ########
label 1
menu label ^1) Install Rocky Linux 8
menu default
kernel rockylinux8/vmlinuz
append initrd=rockylinux8/initrd.img ip=dhcp inst.repo=http://192.168.177.2:8080/pxe/rockylinux8 inst.ks=http://192.168.177.2:8080/ks/rockylinux8-ks.cfg
label 2
menu label ^2) Install AlmaLinux 8
menu default
kernel almalinux8/vmlinuz
append initrd=almalinux8/initrd.img ip=dhcp inst.repo=http://192.168.177.2:8080/pxe/almalinux8 inst.ks=http://192.168.177.2:8080/ks/almalinux8-ks.cfg
label 3
menu label ^3) Install Oracle Linux 8
menu default
kernel oraclelinux8/vmlinuz
append initrd=oraclelinux8/initrd.img ip=dhcp inst.repo=http://192.168.177.2:8080/pxe/oraclelinux8 inst.ks=http://192.168.177.2:8080/ks/oraclelinux8-ks.cfg
label 4
menu label ^4) Install CentOS Stream 8
menu default
kernel centos8stream/vmlinuz
append initrd=centos8stream/initrd.img ip=dhcp inst.repo=http://192.168.177.2:8080/pxe/centos8stream inst.ks=http://192.168.177.2:8080/ks/centos8stream-ks.cfg
label 5
menu label ^5) Install Fedora Server
menu default
kernel fedora/vmlinuz
append initrd=fedora/initrd.img ip=dhcp inst.repo=http://192.168.177.2:8080/pxe/fedora inst.ks=http://192.168.177.2:8080/ks/fedora-ks.cfg
Explanation of key directives used:
- ip=dhcp to obtain an IP address using DHCP
- inst.ks directive points to a shared URL for the Kickstart file.
Save the file and proceed to usage step.
Step 10 – Create a Virtual Machine using PXE Boot
We’ll consider both command-line and Graphical interface installation.
PXE Booting through Virt-install
Installation from Virt-install command line interface:
sudo virt-install --connect qemu:///system \
--name testvm \
--network=bridge:br0 --pxe \
--ram=2048 \
--vcpus=2 \
--os-type=linux --os-variant=rhl8.0 \
--disk path=/var/lib/libvirt/images/testvm.qcow2,size=40
Installation through PXE using Virt-manager
Access Virt-Manager and create new Virtual Machine. Choose “Manual install“.
Choose operating system type, assign resources and give it a name.
Finish creation and Power-off the Virtual Machine. Once the VM is down, edit its settings under “Boot Options“
Tick “NIC” in the Boot device menu check boxes.
Start the Virtual Machine and it should start requesting IP address
You should see PXE Boot menu, choose your OS from the list to initiate installation.
The normal OS installation screen should be presented to you after few seconds.
Manual installation without Kickstart
When using Kickstart automation, manual intervention is not required.
All pre-configurations and OS installation process begins automatically.
Relax as the automated installation takes effect. In a few minutes your system will be ready for use.
Below is a screenshot of automated Fedora Server installation.
Conclusion
It is a fact that when installing Enterprise Linux operating systems on a large number of systems simultaneously, a better approach is to boot from a PXE server with installation files hosted in shared network location(FTP,HTTP,NFS). For unattended deployment, Kickstart gives you a way to fully automate the installation process of the OS. The Kickstart files contain answers to all questions normally asked by the installation program.