This article shows how to create a CentOS Virtual Machine (VM) in unattended mode using a shell script and illustrates the main steps and options to reproduce the process manually.

The following script and commands will create a base image that can be used to deploy multiple nodes from a system like Ansible to define roles for each node. It is very useful for creating clustered virtual environments such as the vCluster stack.

Getting Started

You will need to install virtualisation tools on your RPM based Linux node before following this guide.

yum -y groupinstall "Virtualization Tools"
yum -y install virt-manager libvirt libvirt-python python-virtinst virt-top libguestfs-tools
reboot

You must also clone this project from GitHub for the unattended script to work correctly. This is because it references a Kickstart file on your local filesystem in the cloned project directory structure.

git clone git://github.com/fubralimited/CentOS-KVM-Image-Tools.git
Cloning into CentOS-KVM-Image-Tools...
remote: Counting objects: 437, done.
remote: Compressing objects: 100% (251/251), done.
remote: Total 437 (delta 184), reused 425 (delta 173)
Receiving objects: 100% (437/437), 84.72 KiB, done.
Resolving deltas: 100% (184/184), done.

When the clone is complete take a look at the Kickstart directory contents. You will see a number of Kickstart files.

  • The centos6x-vm-gpt-selinux.cfg is the Kickstart file to create a CentOS 64bit Virtual Machine guest.
  • The centos6x-i386-vm-gpt-selinux.cfg is the Kickstart file to create a CentOS 32bit Virtual Machine guest.
  • The centos6x-hypervisor-gpt-selinux.cfg is the Kickstart file to create a CentOS 64bit Virtual Machine hypervisor.

All the Kickstart files contain the following common packages. In addition all the Kickstart configuration files enable the SELinux and the firewall, and do not install the graphic environment X.

  • @core
  • @server-policy
  • vim-enhanced
  • nano
  • aide

Note that by default we install the AIDE (Advanced Intrusion Detection Environment) package, a file and directory integrity checker.

The CentOS hypervisor Kickstart is the same as the 64bit version, but with the following additional packages included.

  • kvm
  • virt-manager
  • libvirt
  • libvirt-python
  • python-virtinst
  • virt-top
  • libguestfs-tools

You can learn more about the specific contents of each file by viewing the comments in the files.

At this point you should note that the default password for the root user is changeme1122 (as defined on the Kickstart configuration file).

The Creation Script

In the Centos KVM Image Tools project that you cloned form GitHub in the previous step you will find a scripts directory. Here you will find one called centoskvm.sh. This is the script you need to run to create the Master Image automatically.

When you run the script a virtual machine will be created with the given settings, and output from the installation will be sent to your terminal rather than a VNC session. This VM will then be compressed and an image will be created from it.

Run the script on the command line.

sh centoskvm.sh centos_vm

Where centos_vm is the name of the virtual machine we want to create.

By default this script uses the centos6x-vm-gpt-selinux.cfg Kickstart configuration file. You can clone the project on GitHub and change the Kickstart file to change settings in the unattended creation.

What’s on the inside?

The following section illustrates the main operations performed by the centoskvm.sh script to better understand the process and provide some tips.

1. Creating the Virtual Machine

The firt step consist into creating the VM using the virt-install command with the following parameters:

virt-install \
--name centos_vm \
--ram 512 \
--cpu host \
--vcpus 1 \
--nographics \
--os-type=linux \
--os-variant=rhel6 \
--location=http://mirror.catn.com/pub/centos/6/os/x86_64 \
--initrd-inject=../Kickstarts/centos6x-vm-gpt-selinux.cfg \
--extra-args="ks=file:/centos6x-vm-gpt-selinux.cfg text console=tty0 utf8 console=ttyS0,115200" \
--disk path=/var/lib/libvirt/images/centos_vm.qcow2,size=10,bus=virtio,format=qcow2 \
--force \
--noreboot

On the script the Kickstart configuration is a local file injected via the “initrd-inject” parameter. Is it also possible to pass the Kickstart file as URL:

virt-install \
--name centos_vm \
--ram 512 \
--cpu host \
--vcpus 1 \
--nographics \
--os-type=linux \
--os-variant=rhel6 \
--location=http://mirror.catn.com/pub/centos/6/os/x86_64 \
--extra-args="ks=http://fubralimited.github.com/CentOS-KVM-Image-Tools/Kickstarts/centos6x-vm-gpt-selinux.cfg text console=tty0 utf8 console=ttyS0,115200" \
--disk path=/var/lib/libvirt/images/centos_vm.qcow2,size=10,bus=virtio,format=qcow2 \
--force \
--noreboot

The image created in this way has the default network settings (DHCP), it is fully updated and is not restarted. Please check the Kickstart configuration file source code for more information and options.

2. Reset the Virtual Machine

The virt-sysprep command is used to reset and unconfigure the virtual machine so clones can be made. The VM is modified in place, so the guest must be shut down.

cd /var/lib/libvirt/images/
virt-sysprep --format=qcow2 --no-selinux-relabel -a centos_vm.qcow2

The –no-selinux-relabel option is set to avoid automatic SELinux relabeling at boot. Instead we relabel the VM manually on the next step.

3. SElinux relabelling

Using the guestfish shell we can manually relabel the entire filesystem using the following options without the need to start the VM.

guestfish --selinux -i centos_vm.qcow2 <<EOF
sh load_policy
sh 'restorecon -Rv /'
EOF

or in one line:

guestfish --selinux -i centos_vm.qcow2 <<<'sh "load_policy && restorecon -R -v /"'

4. Make the virtual machine image sparse

Using the virt-sparsify tool we can make a virtual machine image sparse a.k.a. thin-provisioned. This means that free space within the disk image can be converted back to free space on the host.

virt-sparsify --compress --convert qcow2 --format qcow2 centos_vm.qcow2 centos_vm-sparsified.qcow2

5. Rename VM image file and set the correct ownership

On this last step we rename the VM image file and set the correct ownership.

rm -rf centos_vm.qcow2
mv centos_vm-sparsified.qcow2 centos_vm.qcow2
chown qemu:qemu centos_vm.qcow2

Please check the centoskvm.sh script for further details and configurations.

As you may be able to see from the –disk parameter the completed and sparsified disk image will be exported to the local filesystem in qcow2 format.

You can now access and deploy nodes using this newly created CentOS image by accessing the file in this location.

/var/lib/libvirt/images/centos_vm.qcow2

The virtual machine centos_vm created as above is shut down by default, so we can easily clone it and import to create new guests.

On my next articles I’ll show you how to use this VM image to create new guests and how to resize them.

Nicola Asuni Systems Engineer

Nicola focused on designing, building and integrating the backend for our application platforms, including automatic deployment, monitoring and backups.