Objective
Learn how to create and manage KVM virtual machines from command line
Operating System and Software Versions
- Operating System: – All Linux distributions
Requirements
- Root access
- Packages:
- qemu-kvm – The main package
- libvirt – Includes the libvirtd server exporting the virtualization support
- libvirt-client – This package contains
virsh
and other client-side utilities - virt-install – Utility to install virtual machines
- virt-viewer – Utility to display graphical console for a virtual machine
Difficulty
MEDIUM
Conventions
- # – requires given linux commands to be executed with root privileges either
directly as a root user or by use ofsudo
command - $ – requires given linux commands to be executed as a regular non-privileged user
Introduction
Knowing how to create and manage KVM virtual machines from command line can be really useful in certain scenarios: when working on headless servers, for example. Nonetheless, being able to script interactions with virtual machines can greatly improve our productivity. In this tutorial you will learn how to create, delete, clone and manage KVM machines with the help of few utilities.
Some terminology
Before we start working, it would be useful to define what KVM
and Qemu
are and how they interact. KVM
stands for Kernel Virtual Machine, and it is a module of the Linux kernel which allows a program to access and make use of the virtualization capabilities of modern processors, by exposing the /dev/kvm interface. Qemu
is, instead, the software which actually performs the OS emulation. It is and open source machine emulator and virtualizer which can use the acceleration feature provided by KVM
when running an emulated machine with the same architecture of the host.
Preliminary setup
First thing we have to do, is to check that the CPU we are using has support for virtualization. Unless you are running on a very old machine, this will surely be the case, but to verify it we simply run:
$ cat /proc/cpuinfo
Scroll down the output of the command above until you see the list of CPU ‘flags’: among them you should see svm
if you are using an Amd processor, or vmx
if the CPU vendor is Intel.
The second thing we have to do, is to make sure that the needed kernel modules have been loaded, to check this, we run:
# lsmod | grep kvm kvm_intel 200704 0 kvm 598016 1 kvm_intel irqbypass 16384 1 kvm
I’m running on an Intel CPU, therefore, in addition to the kvm
module, also the kvm_intel
one has been loaded. If you are using an Amd processor, the kvm_amd
module will be loaded instead. If the modules are not loaded automatically, you can try to load them manually by using the modprobe
command:
# modprobe kvm_intel
Finally, we have to start the libvirtd
daemon: the following command both enables it at boot time and starts it immediately:
# systemctl enable --now libvirtd
Create the new virtual machine
Now that we installed and started the libvirtd
service, we can use the virt-install
command to setup our virtual machine. The syntax of the program is really straightforward. The following linux command must be executed as root, or, if you want to launch it as a normal user, as a member of the kvm
group. The syntax of the program is the following:
# virt-install --name=linuxconfig-vm \ --vcpus=1 \ --memory=1024 \ --cdrom=/tmp/debian-9.0.0-amd64-netinst.iso \ --disk size=5 \ --os-variant=debian8
Let’s analyze the command above:
First of all we used the --name
option: this is mandatory and it is used to assign a name to the new virtual machine.
The next option is the --vcpus
one. We use it to specify the number of virtual cpus
to configure for the guest.
The --memory
option is used to select the amount of memory reserved for the guest machine in MiB
and --cdrom
lets us specify the path to a file or a device to be used as a virtual CD-ROM: it can be an ISO image, a CDROM device or a URL from which to access a boot ISO image.
The --disk
flag is used to configure the media storage for the guest. Various comma-separated options can be specified, for example: size
which is used to specify the size of the virtual disk in GB and path
which is used to specify a path to use for the disk (it will be created if doesn’t already exists). If this options is specified, you must make sure that the target path is accessible and has the right SELinux context (to know more about SELinux you can read this article).
If the path
option is not specified, the disk will be created in $HOME/.local/share/libvirt/images
if the command is executed as normal user (member of the kvm group) or in /var/lib/libvirt/images if running it as root.
Next we passed the --os-variant
option. While this is not mandatory, is highly recommended to use it, since it can improve performance of the virtual machine. The option will try to fine tune the guest to the specific OS version. If the option is not passed, the program will attempt to auto-detect the correct value from the installation media. To obtain a list of all supported systems you can run:
$ osinfo-query os
If everything went well and the virt-viewer
package is installed, a window will appear showing the guest OS installer.

The virsh utility
The virsh utility can be used to interact with virtual machines. For example, say you want to list all configured guests, using virsh you can simply run:
# virsh list --all
The output will show the id
, name
and state
of all the configured guests, whether they are running or not.
But what if you want to change some guest machine parameters? You can use virsh
to accomplish this task, for example:
# virsh edit linuxconfig-vm
Here is a screenshot of the command output:

As you can see the output is an xml representation of the virtual machine properties, or, using virsh terminology, a domain
. If you want to change, for example, the number of vcpus, you just have to find the relevant tag and change the value. In this case, we have:
<vcpu placement='static'>1</vcpu>
We want to add 1 vcpu, so we will change it to:
<vcpu placement='static'>2</vcpu>
All we have to do now, is just to reboot the virtual machine for the settings to be applied:
# virsh reboot linuxconfig-vm
If we now run lscpu
in the guest console, we should see the increased number of cpus:

The virsh
command can also be used to do other common operations: for example, virsh shutdown
can be used to shut down the guest, virsh destroy
is the equivalent of a brute force shutdown (therefore it can be dangerous) and virsh undefine
can be used to delete a guest machine (to undefine a domain).
Autostart a virtual machine on boot
You can take advantage of the virsh
command also if you want certain guests to be started automatically when the host system boots: the syntax it’s, again, very intuitive:
# virsh autostart linuxconfig-vm
To disable this option, we run:
# virsh autostart --disable linuxconfig-vm
Cloning a guest
Another utility, virt-clone
can be used to create a new virtual machine by cloning an existing one. To proceed, we must first ensure that the guest to be cloned is down, than we run:
virt-clone \ --original=linuxconfig-vm \ --name=linuxconfig-vm-clone \ --file=/var/lib/libvirt/images/linuxconfig-vm.qcow2
What we have here is very simple to understand: we specified the guest to be cloned using the --original
option and the name of the new guest using --name
as if we were installing it from scratch. With the --file
option, instead, we reference all the virtual hard disks associated with the original guest that we want to clone. The program will do its job, and, if successful, will create a new domain named linuxconfig-vm-clone
. We already know how to verify it:
# virsh list --all Id Name State ---------------------------------------------------- - linuxconfig-vm shut off - linuxconfig-vm-clone shut off
Final thoughts
In this tutorial we configured a new virtual machine, and we saw how to interact with it. The options we specified at creation time, are just the minimal needed for a working setup. A lot of other options can be used to adjust several aspects of the guest machine and they are really well described in the virt-install
manpage. As always, the best possible advice is: read the manual.