Creating KVM Virtual Machines with Kickstart: A Step-by-Step Guide

|
Published:
|
|
kickstart ks cfg

In this tutorial, we will walk you through the steps of creating KVM virtual machines with Kickstart. If you are working with virtualized workloads, you will realize that creating virtual machines repeatedly is a time consuming task, especially if you are dealing with large scale virtualization. Going over the same installation steps every now and then, installing packages on those virtual machines is cumbersome and can easily lead to inconsistencies. This is where Kickstart can come in to help automate the deployment and save you sometime to do other tasks. Let’s dive into how you can utilize Kickstart to automate Linux Virtual machines creation on KVM.

Creating KVM Virtual Machines with Kickstart

What is Kickstart?

To begin with, what is Kickstart? Kickstart is a tool created by RedHat to automate deployment of RedHat based OS such as RHEL, CentOS, Fedora and of course other OSes such Ubuntu and the likes, on KVM virtual manager as virtual machines. It provides a method of performing unattended installations of Linux virtual machines through the use Kickstart text file that stores answers to the questions that the installer usually asks as you do the manual installation.

Through the use Kickstart file, you can be able to specify the packages to be installed on the VM, automatic partitioning, user creation, network configuration and other usual VM setup configurations. Using Kickstart is like using a template for deployment as it ensures that the machines are deployed with consistent settings.

Reference for Kickstart Configuration File Options

A whole documentation explaining the various configuration options used in the Kickstart configuration file is available on the Kickstart Documentation page. For any options used above that is not clear to you, refer to the documentation to read more.

Create the Kickstart Configuration File

As already mentioned, Kickstart configuration file is a text file that stores answers to the usual installer questions. The Kickstart file can be passed to either virt-install cli tool or to GUI installer for automating the process.

The are different ways of creating Kickstart configuration file.

Create Kickstart file using Kickstart Generator tool

If you have access to RedHat Customer Portal, then you can utilize their Kickstart generator tool to generate the Kickstart configuration file for the deployment of your specific RHEL OS version on KVM. Once you have the file, you can customize it further to suit your needs.

Creating KVM Virtual Machines with Kickstart
Sample RedHat Kickstart Generator

When you manually deploy a RHEL based OS on KVM, the Anaconda installer records all the answers you provide during installation in a Kickstart configuration file called anaconda-ks.cfg that is usually saved under the root user home directory as /root/anaconda-ks.cfg.

So, if you have deployed RHEL 9 for example, you should have seen such a file on the server.

Here is a sample configuration;

sudo cat /root/anaconda-ks.cfg
#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Use CDROM installation media
cdrom
# Use graphical install
graphical
# Run the Setup Agent on first boot
firstboot --enable
ignoredisk --only-use=vda
# Keyboard layouts
keyboard --vckeymap=us --xlayouts='us'
# System language
lang en_US.UTF-8

# Network information
network  --bootproto=dhcp --device=eth0 --ipv6=auto --activate
network  --hostname=localhost.localdomain

repo --name="Server-HighAvailability" --baseurl=file:///run/install/repo/addons/HighAvailability
repo --name="Server-ResilientStorage" --baseurl=file:///run/install/repo/addons/ResilientStorage
# Root password
rootpw --iscrypted $6$XrYFMAXaTG7iyFBZ$EHqNNWerRsqEt9JIpL6oVmEWph2x7TBYUIW2ss59/jPiEIe6Cjthq2zaqXJDY8Fh9K3mbfQGvwnuCjglk3GLS0
# System services
services --enabled="chronyd"
# System timezone
timezone America/New_York --isUtc
user --name=kifarunix --password=$6$sVC9CWRNJxqPoIYu$jEoA8YOO5RThlFKQgNG5se396lMMVIXPwDeY//8imM7QiwL.Xs132HlRn1ex2av/NXCoxf8f5bUycP53k5vsT0 --iscrypted --gecos="kifarunix"
# System bootloader configuration
bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=vda
autopart --type=lvm
# Partition clearing information
clearpart --none --initlabel

%packages
@^minimal
@core
chrony
kexec-tools

%end

%addon com_redhat_kdump --enable --reserve-mb='auto'

%end

%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end

For all the options used, counter check them from the reference documentation in the link given above. Some of the have deprecated and will no longer be supported already or in the future versions.

To give a brief explanation of the Kickstart configuration file above;

Version Declaration

#version=DEVEL:

  • Indicates the version of the installer or Kickstart syntax being used. DEVEL is used for development/testing purposes.

Authorization

auth --enableshadow --passalgo=sha512

  • Enables shadow passwords (more secure password storage).
  • Specifies SHA-512 as the password hashing algorithm.
  • This options is deprecated.

Installation Source

cdrom

  • Specifies the installation source as the CD/DVD media.

Installation Mode

graphical

  • Indicates a graphical installation interface.

First Boot Configuration

firstboot --enable

  • Enables the first-boot setup wizard after the system is installed.

Disk Configuration

ignoredisk --only-use=vda

  • Ignores all disks except for the virtual disk vda during installation.

Keyboard and Language

keyboard --vckeymap=us --xlayouts='us'
lang en_US.UTF-8

  • Keyboard layout is set to US.
  • Language is set to US English.

Networking

network --bootproto=dhcp --device=eth0 --ipv6=auto --activate network --hostname=localhost.localdomain

  • Configures eth0 to use DHCP for IPv4 and automatically configure IPv6.
  • Sets the hostname to localhost.localdomain.

Repositories

repo --name="Server-HighAvailability" --baseurl=file:///run/install/repo/addons/HighAvailability repo --name="Server-ResilientStorage" --baseurl=file:///run/install/repo/addons/ResilientStorage

  • Adds local repositories for High Availability and Resilient Storage.

Root Password

rootpw --iscrypted $6$XrYFMAXaTG7iyFBZ$EHqNNWerRsqEt9JIpL6oVmEWph2x7TBYUIW2ss59/jPiEIe6Cjthq2zaqXJDY8Fh9K3mbfQGvwnuCjglk3GLS0

  • Sets the root password using a hashed value.
  • You can use tools such as mkpasswd to generate such a password.
  • mkpasswd –method=sha512crypt (will ask you to enter the password)
  • If you want to allow remote root logins via ssh using only the password, add the --allow-ssh option.

System Services

services --enabled="chronyd"

  • Enables the chronyd service for time synchronization.

System Timezone

timezone America/New_York --isUtc

  • Sets the system timezone to America/New_York and configures it to use UTC.
  • --isUtc is deprecated as from RHEL 8

User Configuration

user --name=kifarunix --password=$6$sVC9CWRNJxqPoIYu$jEoA8YOO5RThlFKQgNG5se396lMMVIXPwDeY//8imM7QiwL.Xs132HlRn1ex2av/NXCoxf8f5bUycP53k5vsT0 --iscrypted --gecos="kifarunix"

  • Creates a user named kifarunix with a hashed password and full name. Similar

Bootloader Configuration

bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=vda

  • Configures the bootloader to append crashkernel=auto, installs it to the MBR, and sets the boot drive to vda.

Partitioning

autopart --type=lvm

  • Automatically partitions the disk using LVM.

Partition Clearing

clearpart --none --initlabel

  • Clears existing partitions without initializing a new partition table.

Package Selection

%packages
@^minimal
@core
chrony
kexec-tools

%end
  • Installs minimal and core package groups, along with additional specified packages.

Kdump Configuration

%addon com_redhat_kdump --enable --reserve-mb='auto'
%end

  • Enables kdump and reserves memory automatically.

Password Policies

%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end

  • Sets password policies for root, user, and LUKS encrypted volumes passwords.
  • All this %anaconda section is deprecated.

Create Kickstart Configuration File Manually

If you are a pro, of course you can create your own Kickstart configuration file. However, manual creation process is prone to mistakes. Be sure to find a way to validate your Kickstart configuration file. You can use ksvalidator commands provided by pykickstart package on RHEL systems. See below.

Validate Kickstart Configuration file

To ensure that the syntax of the Kickstart configuration file is correct and that the file does not include deprecated options, use ksvalidator command against the file. Kindly note that the validator does not attempt to validate the %pre%post and %packages sections of the Kickstart file. So be sure to check those sections manually. Similarly, it is good to note that validating the syntax of the Kickstart file does not guarantee successful installation!

Install Kickstart Validator Commands on RHEL/CentOS

If you are on RHEL/CentOS or similar OSes, you can install the pykickstart package;

sudo yum install pykickstart

This provides the ksvalidator command that you can now use;

ksvalidator --help
usage: ksvalidator [options] ksfile [ksfile...]

positional arguments:
  ksfile                filename or URL to read from

options:
  -e, --firsterror      halt after the first error or warning
  -i, --followincludes  parse include files when %include is seen
  -l, --listversions    list the available versions of kickstart syntax
  -v VERSION, --version VERSION
                        version of kickstart syntax to validate against
  -h, --help            show this help message and exit

For example;

ksvalidator -v RHEL9 ~/rhel-ks.cfg

Sample output;


Checking kickstart file /home/kifarunix/rhel-ks.cfg

The following problem occurred on line 1 of the kickstart file:

auth has been removed.

Ignoring deprecated option on line 19: The --isUtc option has been deprecated and no longer has any effect. It may be removed from future releases, which will result in a fatal error from kickstart. Please mod
ify your kickstart file to remove this option.

You can fix any identified issue and revalidate the configuration file.

Install Kickstart Validator Command on Ubuntu/Debian

Unfortunately, pykickstart is not available in the default Ubuntu repositories, so you need to install it via pip in a virtual environment.

Install Python and Virtual Environment Tools

sudo apt update
sudo apt install python3 python3-pip python3-venv -y

Create a new directory for your virtual environment and activate it:

mkdir ksvalidator_env
cd ksvalidator_env
python3 -m venv venv
source venv/bin/activate

Use pip to install the pykickstart package inside the virtual environment:

pip install pykickstart

Run ksvalidator to check your kickstart file:

ksvalidator /path/to/rhel-ks.cfg

Making Kickstart Available for Installation

Once your Kickstart is ready, you can make it available for the various types of installation, be it network-based or local installation.

Some of the network-based installation methods you can explore include:

  • use of HTTP(S) server to serve Kickstart file
  • use of NFS shares
  • use of FTP/TFTP servers

For local installation, you can make Kickstart available on the local system from where you launch the installation.

Creating RHEL 9 Virtual Machine with Kickstart on KVM

To demonstrate how to use Kickstart file to automate the installation of Virtual machines on KVM, let’s create a RHEL 9 virtual machine.

Prepare Kickstart Configuration file

Here is our sample Kickstart configuration file.

cat /home/kifarunix/rhel-ks.cfg
authselect select sssd --password-hashing=sha512
cdrom
text
firstboot --enable
ignoredisk --only-use=vda
keyboard --vckeymap=us --xlayouts='us'
lang en_US.UTF-8

network  --bootproto=dhcp --device=eth0 --ipv6=auto --activate
network  --hostname=rhel9.kifarunix.com

#repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream
#repo --name="BaseOS" --baseurl=file:///run/install/sources/mount-0000-cdrom/BaseOS
#repo --name="Server-HighAvailability" --baseurl=file:///run/install/repo/addons/HighAvailability
#repo --name="Server-ResilientStorage" --baseurl=file:///run/install/repo/addons/ResilientStorage

rootpw --iscrypted $6$XrYFMAXaTG7iyFBZ$EHqNNWerRsqEt9JIpL6oVmEWph2x7TBYUIW2ss59/jPiEIe6Cjthq2zaqXJDY8Fh9K3mbfQGvwnuCjglk3GLS0 --allow-ssh

services --enabled="chronyd"

timezone America/New_York
user --name=kifarunix --password=$6$sVC9CWRNJxqPoIYu$jEoA8YOO5RThlFKQgNG5se396lMMVIXPwDeY//8imM7QiwL.Xs132HlRn1ex2av/NXCoxf8f5bUycP53k5vsT0 --iscrypted --gecos="kifarunix" --groups wheel

bootloader --append="  net.ifnames=0 biosdevname=0 crashkernel=auto" --location=mbr --boot-drive=vda
autopart --type=lvm

clearpart --none --initlabel

%packages
@^minimal-environment
@core
chrony
kexec-tools
container-tools
nfs-utils
autofs
vim
cloud-init
cloud-utils-growpart

%end

%addon com_redhat_kdump --enable --reserve-mb='auto'

%end

%post --nochroot
rsync -avP /run/install/repo/{AppStream,BaseOS} /mnt/sysimage/mnt/
%end

%post
cat > /etc/yum.repos.d/local.repo << 'EOL'
[AppStream]
name = AppStream
baseurl = file:///mnt/AppStream
gpgcheck = 0
enabled = 1

[BaseOS]
name = BaseOS
baseurl = file:///mnt/BaseOS
gpgcheck = 0
enabled = 1
EOL
%end

There are a few things that I have introduced in my Kickstart configuration file to deploying RHEL 9.4 on KVM;

  • commented out all repo lines
  • Force the naming of the network interfaces into the traditional way of ethX for predictability; bootloader --append=" net.ifnames=0 biosdevname=0 crashkernel=auto" --location=mbr --boot-drive=vda
  • Copied the repositories from the installation media and created custom repos, see the %post section (If you want, you can enable your subscriptions to enable some repos).

Validate the file;

ksvalidator ~/rhel-ks.cfg

Looks good;


Checking kickstart file /home/kifarunix/rhel-ks.cfg

Start Kickstart installation

You can start Kickstart installation either by editing the boot options during PXE boot installation or by providing a path to the local Kickstart file. In this guide, we will run the installation via the Virt Manager/virt-install.

Before you can proceed, you need to have the installation ISO medium already. We are using RHEL 9.4 ISO file located under ~/Downloads/rhel-9.4-x86_64-dvd.iso.

To deploy the VM with virt-install and Kickstart file;

sudo virt-install \
	--name rhel9.4-server \
	--ram 2048 \
	--vcpus 2 \
	--disk path=/mnt/vol01/kvm/images/rhel9.4-server.qcow2,format=qcow2,size=20 \
	--network network=default \
	--location /home/kifarunix/Downloads/rhel-9.4-x86_64-dvd.iso \
	--graphics none \
	--initrd-inject=/home/kifarunix/rhel-ks.cfg \
	--extra-args "inst.ks=file:/rhel-ks.cfg console=tty0 console=ttyS0,115200n8"

Ensure the name of the Kickstart file used in the --initrd-inject option matches the one specified on the extra arguments line.

If all goes well, this should create the virtual machine and begin installation automatically.

This is a snippet of the beginning and towards to the end of installation:

Starting installer, one moment...
anaconda 34.25.4.9-1.el9_4 for Red Hat Enterprise Linux 9.4 started.
 * installation log files are stored in /tmp during the installation
 * shell is available on TTY2
 * if the graphical installation interface fails to start, try again with the
   inst.text bootoption to start text installation
 * when reporting a bug add logs from /tmp as separate text/plain attachments
15:44:41 Not asking for VNC because of an automated install
15:44:41 Not asking for VNC because text mode was explicitly asked for in kickstart
15:44:41 Not asking for VNC because we don't have a network
Starting automated install.Saving storage configuration...
.Checking storage configuration...
.
....
================================================================================

================================================================================
Installation

1) [x] Language settings                 2) [x] Time settings
       (English (United States))                (America/New_York timezone)
3) [x] Installation source               4) [x] Software selection
       (Local media)                            (Minimal Install)
5) [x] Installation Destination          6) [x] Kdump
       (Automatic partitioning                  (Kdump is enabled)
       selected)
7) [x] Network configuration
       (Unknown)

================================================================================
================================================================================
Progress

.
Setting up the installation environment
Configuring storage
Creating disklabel on /dev/vda
Creating xfs on /dev/vda1
Creating lvmpv on /dev/vda2
Creating swap on /dev/mapper/rhel_rhel9-swap
Creating xfs on /dev/mapper/rhel_rhel9-root
...
Running pre-installation scripts
.
Running pre-installation tasks
....
Installing.
Starting package installation process
Downloading packages
...

.
Configuring Red Hat subscription
....
Configuring installed system
..............
Writing network configuration
.
Creating users
.....
Configuring addons
.
Generating initramfs
....
Storing configuration files and kickstarts
.
Running post-installation scripts
.
Installation complete

Use of this product is subject to the license agreement found at:
/usr/share/redhat-release/EULA

Installation complete. Press ENTER to quit: 
[anaconda]1:main* 2:shell  3:log  4:storage-log >Switch tab: Alt+Tab | Help: F1

You can press Enter to reboot the Virtual machine. The installer connects to the VM via console.

Verify VM installation

Login with the user credentials specified in the Kickstart;

Red Hat Enterprise Linux 9.4 (Plow)
Kernel 5.14.0-427.13.1.el9_4.x86_64 on an x86_64

rhel9 login: kifarunix
Password:
[kifarunix@rhel9 ~]$ id
uid=1000(kifarunix) gid=1000(kifarunix) groups=1000(kifarunix),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[kifarunix@rhel9 ~]$ hostnamectl 
 Static hostname: rhel9.kifarunix.com
       Icon name: computer-vm
         Chassis: vm 🖴
      Machine ID: ea77cb4a665648b093aa6369e5675505
         Boot ID: 3826016f1c24493ebfb54339dcc0b4d9
  Virtualization: kvm
Operating System: Red Hat Enterprise Linux 9.4 (Plow)     
     CPE OS Name: cpe:/o:redhat:enterprise_linux:9::baseos
          Kernel: Linux 5.14.0-427.13.1.el9_4.x86_64
    Architecture: x86-64
 Hardware Vendor: QEMU
  Hardware Model: Standard PC _Q35 + ICH9, 2009_
Firmware Version: 1.16.2-debian-1.16.2-1
[kifarunix@rhel9 ~]$ dnf repolist
Not root, Subscription Management repositories not updated
repo id                                 repo name
AppStream                               AppStream
BaseOS                                  BaseOS
[kifarunix@rhel9 ~]$ ip a
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: eth0:  mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:5e:44:c6 brd ff:ff:ff:ff:ff:ff
    altname enp1s0
    inet 192.168.122.54/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0
       valid_lft 3511sec preferred_lft 3511sec
    inet6 fe80::b515:b22:e552:1edf/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
[kifarunix@rhel9 ~]$

Conclusion

By following the steps outlined in this guide, you can successfully deploy a VM on KVM automatically through Kickstart. Once you have the virtual machine running, you can now use the image to provision other vms for for your various workloads. You can see how Terraform can you provision multiple KVM virtual machines automatically. Check the guide below;

Automate Virtual Machine Creation on KVM with Terraform

SUPPORT US VIA A VIRTUAL CUP OF COFFEE

We're passionate about sharing our knowledge and experiences with you through our blog. If you appreciate our efforts, consider buying us a virtual coffee. Your support keeps us motivated and enables us to continually improve, ensuring that we can provide you with the best content possible. Thank you for being a coffee-fueled champion of our work!

Photo of author
Kifarunix
Linux Certified Engineer, with a passion for open-source technology and a strong understanding of Linux systems. With experience in system administration, troubleshooting, and automation, I am skilled in maintaining and optimizing Linux infrastructure.

Leave a Comment