Tags Archives: libvirt

How to Install and Use KVM libvirt on Ubuntu

Virtualization Compatibility Check


Execute the below command to install the cpu-checker package.


apt install -y cpu-checker


check if your CPU supports virtualization by running this command.




If you get the following result, your CPU supports virtualization with KVM:


root@asus:~# kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used



Installing KVM on Ubuntu


Provided your CPU supports virtualization, you can install KVM on your machine.


To install KVM on Ubuntu, run the apt command below.


apt install qemu-kvm libvirt-clients libvirt-daemon-system bridge-utils virt-manager -y


These are the packages that will be installed:


qemu-kvm – This package provides accelerated KVM support. This is a userspace component for QEMU, responsible for accelerating KVM guest machines.


libvirt-daemon-system – This is the libvirt daemon and related management tools used for creating, managing, and destroying virtual machines on the host machine.


libvirt-clients – This provides the libvirt command-line interface for managing virtual machines.


bridge-utils – This package provides the userland tools used for configuring virtual network bridges. On a hosted virtualization system like KVM, the network bridge connects the virtual guest VM network with the real host machine network.


virt-manager – This provides a graphical user interface (GUI) for managing your virtual machines should you wish to use it.


If you want the libvirt daemon to start automatically at boot then enable libvirtd:


systemctl enable libvirtd


If libvirtd is not already running, do:


systemctl start libvirtd


Check if KVM is loaded in the kernel with:


lsmod | grep -i kvm




Overview of basic libvirt commands



To launch the libvirt KVM GUI Virtual Machine Manager run:





Alternatively you can use the virt-install commands to launch machines from the CLI.




virt-install –name fedora1 –vcpu 1 –memory 2048 –cdrom /root/Fedora-Workstation-Live-x86_64-36-1.5.iso –disk size=12 –check disk_size=off



This creates a Fedora machine with hostname fedora1 with 2GB RAM and a 12GB virtual hard drive.



To list all VMs:


virsh list –all


To shutdown the machine:



virsh shutdown fedora1



To start the machine:



virsh start fedora1



To display the storage allocated to the machine:



virsh domblklist fedora1


To destroy the machine:


virsh destroy fedora1


To delete the machine and its disk image use virsh undefine. This deletes the VM, and the –storage option takes the comma-separated list of storage you wish to remove. Example:


virsh undefine fedora1 -storage /var/lib/libvirt/images/fedora1-1.qcow2



Continue Reading

How To Get Started With Vagrant

What is Vagrant


Vagrant is a simple open-source virtual machine manager originally developed by HashiCorp which allows you to easily create and run a minimal pre-built virtual machine from a virtual machine image source and SSH immediately into it without any further configuration being necessary.

It’s ideal for developers who require a test machine for their application development.


Vagrant itself only manages your virtual machines and it can use VirtualBox or other VM platforms such as libvirt by means of plug-ins.

Vagrant acts as a wrapper on virtual machines, communicating with them via API providers or hypervisors. The default provider for Vagrant is VirtualBox.


Vagrant is available via the official Ubuntu repository and can be installed using other methods such as apt, apt-get, and aptitude.



How to setup your Vagrant environment


Create a directory called ~/Vagrant. This is where your Vagrantfiles will be stored.


mkdir ~/Vagrant


In this directory, create a subdirectory for the distribution you want to download.


For instance, for a CentOS test server, create a CentOS directory:


mkdir ~/Vagrant/centos


cd ~/Vagrant/centos


Next you need to create a Vagrantfile:


vagrant init


You should now see the following Vagrantfile in the Vagrant directory:

# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The “2” in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don’t change it unless you know what
# you’re doing.
Vagrant.configure(“2”) do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.
# Every Vagrant development environment requires a box. You can search for
# boxes at https://vagrantcloud.com/search.
config.vm.box = “base”
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing “localhost:8080” will access port 80 on the guest machine.
# NOTE: This will enable public access to the opened port
# config.vm.network “forwarded_port”, guest: 80, host: 8080
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via to disable public access
# config.vm.network “forwarded_port”, guest: 80, host: 8080, host_ip: “”
# Create a private network, which allows host-only access to the machine
# using a specific IP.
# config.vm.network “private_network”, ip: “”
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network “public_network”
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# config.vm.synced_folder “../data”, “/vagrant_data”
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
# config.vm.provider “virtualbox” do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
# # Customize the amount of memory on the VM:
# vb.memory = “1024”
# end
# View the documentation for the provider you are using for more
# information on available options.
# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
# config.vm.provision “shell”, inline: <<-SHELL
# apt-get update
# apt-get install -y apache2



To define the virtual machine (known in Vagrant as a “box”) in Vagrantfile edit the following line:


config.vm.box = “[box_name]”


To validate the Vagrantfile use:


vagrant validate



After adding new changes to the Vagrantfile, to apply the changes use


vagrant reload



To list the status of the current running VM:


vagrant status



To get debug info on deployment:


vagrant –debug up


To display full list of guest ports mapped to the host machine ports:


vagrant port [vm_name]





Selecting a Vagrant virtual machine to run


Vagrant boxes are sourced from three different places: Hashicorp (the maintainers of Vagrant), distribution maintainers, and other third-parties.


You can browse through the images at app.vagrantup.com/boxes/search.


vagrant init generic/centos8


The init subcommand will create the Vagrantfile configuration file, in your current directory, and then transform that directory into a Vagrant environment.


You can view a list of current known Vagrant environments by means of the global-status subcommand:


vagrant global-status
id name provider state directory
49c797f default libvirt running /home/tux/Vagrant/centos8
Starting a virtual machine with Vagrant


You can then start your virtual machine by entering:


vagrant up


This causes Vagrant to download the virtual machine image if it doesn’t already exist locally, set up a virtual network, and configure your box.


Entering a Vagrant virtual machine


Once your virtual machine is up and running, you can log in to it with vagrant ssh:


vagrant ssh


You connect to the box by means of ssh. You can run all the commands native to that host OS. It’s a virtual machine with its own kernel, emulated hardware and all common Linux software.


Leaving a Vagrant virtual machine


To leave your Vagrant virtual machine, log out of the host as you normally exit a Linux computer:


box$ exit


Alternatively, you can power the virtual machine down:


box$ sudo poweroff


You can also stop the machine from running using the vagrant command:


box$ vagrant halt



Destroying a Vagrant virtual machine


When finished with a Vagrant virtual machine, you can destroy it:


vagrant destroy


Alternatively, you can remove a virtual machine by running the global box subcommand:

vagrant box remove generic/centos8


What is libvirt


The libvirt project is a toolkit for managing virtualization, with support for KVM, QEMU, LXC, and more. Its rather like a virtual machine API, allowing developers to test and run applications on virtual machines with minimal overhead.


On some distributions you may need to first start the libvirt daemon:


systemctl start libvirtd


Install vagrant-libvirt plugin in Linux


In order to run Vagrant virtual machines on KVM, you need to install the vagrant-libvirt plugin. This plugin adds the Libvirt provider to Vagrant and allows Vagrant to control and provision machines via Libvirt.


Install the necessary dependencies for vagrant-libvirt plugin.


On Ubuntu:


$ sudo apt install qemu libvirt-daemon-system libvirt-clients libxslt-dev libxml2-dev libvirt-dev zlib1g-dev ruby-dev ruby-libvirt ebtables dnsmasq-base


root@asus:/home/kevin# vagrant –version
Vagrant 2.3.4


Now we can install the plug-in:


root@asus:/home/kevin# vagrant plugin install vagrant-libvirt
==> vagrant: A new version of Vagrant is available: 2.3.5 (installed version: 2.3.4)!
==> vagrant: To upgrade visit: https://www.vagrantup.com/downloads.html


Installing the ‘vagrant-libvirt’ plugin. This can take a few minutes…


Fetching formatador-1.1.0.gem
Fetching fog-core-2.3.0.gem
Fetching fog-json-1.2.0.gem
Fetching nokogiri-1.15.0-x86_64-linux.gem
Fetching fog-xml-0.1.4.gem
Fetching ruby-libvirt-0.8.0.gem
Building native extensions. This could take a while…
Fetching fog-libvirt-0.11.0.gem
Fetching xml-simple-1.1.9.gem
Fetching diffy-3.4.2.gem
Fetching vagrant-libvirt-0.12.0.gem
Installed the plugin ‘vagrant-libvirt (0.12.0)’!



Testing Vagrant Box

First let’s download a Vagrant box that supports libvirt.



see https://vagrantcloud.com/generic/ubuntu2004


vagrant box add generic/ubuntu2204 –provider libvirt


Create a small configuration file to use use this new Vagrant box:


cat <<-VAGRANTFILE > Vagrantfile


Vagrant.configure(“2”) do |config|
config.vm.box = “generic/ubuntu2204”



root@asus:/home/kevin# cat <<-VAGRANTFILE > Vagrantfile
> Vagrant.configure(“2”) do |config|
config.vm.box = “generic/ubuntu2204”



And now bring up the system (< 20 seconds):


vagrant up –provider libvirt


You can now log onto the virtual machine guest with:


vagrant ssh


Check the list of boxes present locally.


$ vagrant box list


root@asus:/home/kevin# vagrant box list
generic/ubuntu2204 (libvirt, 4.2.16)




Vagrant will create a Linux bridge on the host system.


$ brctl show virbr1


root@asus:/home/kevin# brctl show virbr1
bridge name bridge id STP enabled interfaces
virbr1 8000.525400075114 yes


root@asus:/home/kevin# vagrant ssh


vagrant@ubuntu2204:~$ df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 198M 956K 197M 1% /run
/dev/mapper/ubuntu–vg-ubuntu–lv 62G 4.9G 54G 9% /
tmpfs 988M 0 988M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/vda2 2.0G 130M 1.7G 8% /boot
tmpfs 198M 4.0K 198M 1% /run/user/1000




Run virsh list to see if you’ll get a list of VMs.


virsh list


To ssh to the VM, use vagrant ssh command.


vagrant ssh



To output .ssh/config valid syntax for connecting to this environment via ssh, run ssh-config command.


You need to place provided output under ~/.ssh/config directory to ssh.


$ vagrant ssh-config



root@asus:/home/kevin# vagrant up
Bringing machine ‘default’ up with ‘libvirt’ provider…
==> default: Checking if box ‘generic/ubuntu2204’ version ‘4.2.16’ is up to date…
==> default: Uploading base box image as volume into Libvirt storage…
==> default: Creating image (snapshot of base box volume).
==> default: Creating domain with the following settings…
==> default: — Name: kevin_default
==> default: — Description: Source: /home/kevin/Vagrantfile
==> default: — Domain type: kvm
==> default: — Cpus: 2
==> default: — Feature: acpi
==> default: — Feature: apic
==> default: — Feature: pae
==> default: — Clock offset: utc
==> default: — Memory: 2048M
==> default: — Base box: generic/ubuntu2204
==> default: — Storage pool: default
==> default: — Image(vda): /var/lib/libvirt/images/kevin_default.img, virtio, 128G
==> default: — Disk driver opts: cache=’default’
==> default: — Graphics Type: vnc
==> default: — Video Type: cirrus
==> default: — Video VRAM: 256
==> default: — Video 3D accel: false
==> default: — Keymap: en-us
==> default: — TPM Backend: passthrough
==> default: — INPUT: type=mouse, bus=ps2
==> default: Creating shared folders metadata…
==> default: Starting domain.
==> default: Domain launching with graphics connection settings…
==> default: — Graphics Port: 5900
==> default: — Graphics IP:
==> default: — Graphics Password: Not defined
==> default: — Graphics Websocket: 5700
==> default: Waiting for domain to get an IP address…
==> default: Waiting for machine to boot. This may take a few minutes…
default: SSH address:
default: SSH username: vagrant
default: SSH auth method: private key
default: Warning: Connection refused. Retrying…
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default: Inserting generated public key within guest…
default: Removing insecure key from the guest if it’s present…
default: Key inserted! Disconnecting and reconnecting using new SSH key…
==> default: Machine booted and ready!



root@asus:/home/kevin# vagrant ssh


vagrant@ubuntu2204:~$ df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 198M 956K 197M 1% /run
/dev/mapper/ubuntu–vg-ubuntu–lv 62G 4.9G 54G 9% /
tmpfs 988M 0 988M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/vda2 2.0G 130M 1.7G 8% /boot
tmpfs 198M 4.0K 198M 1% /run/user/1000



To shut down the VM, run:


$ vagrant halt



To set VM to its initial state by cleaning all data, use vagrant destroy:


$ vagrant destroy



At any time, you can view a list of known Vagrant environments using the global-status subcommand:


$ vagrant global-status


root@asus:/home/kevin# vagrant global-status
id name provider state directory
0466da3 default libvirt running /home/kevin

The above shows information about all known Vagrant environments
on this machine. This data is cached and may not be completely
up-to-date (use “vagrant global-status –prune” to prune invalid
entries). To interact with any of the machines, you can go to that
directory and run Vagrant, or you can use the ID directly with
Vagrant commands from any directory. For example:
“vagrant destroy 1a2b3c4d”


vagrant@ubuntu2204:~$ sudo poweroff
Connection to closed by remote host.


root@asus:/home/kevin# vagrant box list
generic/ubuntu2204 (libvirt, 4.2.16)




Typing vagrant from the command line will display a list of all available commands.


Be sure that you are in the same directory as the Vagrantfile when running these commands!


Creating a VM

vagrant init — Initialize Vagrant with a Vagrantfile and ./.vagrant directory, using no specified base image. Before you can do vagrant up, you’ll need to specify a base image in the Vagrantfile.

vagrant init <boxpath> — Initialize Vagrant with a specific box. To find a box, go to the public Vagrant box catalog. When you find one you like, just replace it’s name with boxpath. For example, vagrant init ubuntu/trusty64.

Starting a VM
vagrant up — starts vagrant environment (also provisions only on the FIRST vagrant up)
vagrant resume — resume a suspended machine (vagrant up works just fine for this as well)
vagrant provision — forces reprovisioning of the vagrant machine
vagrant reload — restarts vagrant machine, loads new Vagrantfile configuration
vagrant reload –provision — restart the virtual machine and force provisioning

Getting into a VM
vagrant ssh — connects to machine via SSH
vagrant ssh <boxname> — If you give your box a name in your Vagrantfile, you can ssh into it with boxname. Works from any directory.

Stopping a VM
vagrant halt — stops the vagrant machine
vagrant suspend — suspends a virtual machine (remembers state)


Cleaning Up a VM
vagrant destroy — stops and deletes all traces of the vagrant machine
vagrant destroy -f — same as above, without confirmation

vagrant box list — see a list of all installed boxes on your computer
vagrant box add <name> <url> — download a box image to your computer
vagrant box outdated — check for updates vagrant box update
vagrant box remove <name> — deletes a box from the machine
vagrant package — packages a running virtualbox env in a reusable box

Saving Progress
-vagrant snapshot save [options] [vm-name] <name> — vm-name is often default. Allows us to save so that we can rollback at a later time


vagrant -v — get the vagrant version
vagrant status — outputs status of the vagrant machine
vagrant global-status — outputs status of all vagrant machines
vagrant global-status –prune — same as above, but prunes invalid entries
vagrant provision –debug — use the debug flag to increase the verbosity of the output
vagrant push — yes, vagrant can be configured to deploy code!
vagrant up –provision | tee provision.log — Runs vagrant up, forces provisioning and logs all output to a file

vagrant-hostsupdater : $ vagrant plugin install vagrant-hostsupdater to update your /etc/hosts file automatically each time you start/stop your vagrant box.



Vagrant can be used to run and control multiple guest machines via a Vagrantfile. This is called a “multi-machine” environment.



Defining Multiple Machines


Multiple machines are defined in the Vagrantfile using the config.vm.define statement.


This configuration directive effectively creates a Vagrant configuration within a configuration, for example:



Vagrant.configure(“2”) do |config|
config.vm.provision “shell”, inline: “echo Hello”


config.vm.define “web” do |web|
web.vm.box = “apache”


config.vm.define “db” do |db|
db.vm.box = “mysql”



Controlling Multiple Machines


Commands that target a specific virtual machine, such as vagrant ssh, require the name of the machine to be specified.


For example, here you would specify vagrant ssh web or vagrant ssh db.


Other commands, such as vagrant up, apply to all VMs by default.


Alternatively, you can specify only specific machines, such as


vagrant up web




vagrant up db.


Autostart Machines


By default in a multi-machine environment, vagrant up will start all the defined VMs.


The autostart setting enables you to instruct Vagrant NOT to start specific machines.


For example:


config.vm.define “web”
config.vm.define “db”
config.vm.define “db_follower”, autostart: false


If you then run vagrant up with the above settings, Vagrant will automatically start the “web” and “db” machines, but does not launch the “db_follower” VM.





Continue Reading