How To Use Vagrant with Libvirt KVM on CentOS Stream 8

Posted on 262 views

Kernel-based Virtual Machine (KVM) is an open source virtualization technology that has been adopted by big Virtualization and Cloud projects such as OpenStack, CloudStack, oVirt and many others. It is built into Linux to help you turn your Linux Server into a hypervisor that runs multiple virtual machines (VMs). This guide is created to help new users use Vagrant on CentOS Stream 8 and KVM hypervisor to spin up and manage virtual machines lifecycle.

If it is your first time using vagrant, it is an open-source tool created by HashiCorp to enable Developers build and maintain portable software development environments in any Virtualization platform – KVM, Virtualbox, VMware, Parallels and even Docker containers. The main requirement for this guide is a running CentOS Stream 8 Server or Workstation. If you have a Fedora Workstation this guide will also work for you.

We had earlier done a separate article on using Libivirt with KVM on other Linux distributions which should also apply to CentOS Stream 8. The only differences that I noted were on the installation of Vagrant plugin for KVM. When doing the installation on CentOS Stream 8, some extra dependencies are required which this guide will cover.

Step 1: Install KVM on CentOS Stream 8

We need KVM virtualization software stack before we can install and use Vagrant plugin with the installation. Before you begin the installation ensure all your system packages including kernel are updated to the latest release.

sudo dnf -y update

Once the update has been done, reboot your system.

sudo systemctl reboot

Wait for the system to be rebooted then install KVM virtualization tools on CentOS Stream 8 Linux machine.

sudo dnf install -y @virt virt-install libvirt-devel vim bash-completion

Start and enable libvirtd service.

sudo systemctl enable --now libvirtd

Add your user to libvirt group

sudo usermod -aG libvirt $USER
newgrp libvirt

Step 2: Install Vagrant on CentOS Stream 8

The next software component is Vagrant. Some dependencies that we’ll use are build tools which you can easily install with the following dnf commands.

sudo dnf groupinstall "Development Tools" -y 
sudo dnf -y install rsync gcc zlib-devel libvirt-devel cmake libxslt-devel libxml2-devel libvirt-devel libguestfs-tools-c ruby-devel gcc make

Install Ruby and Ruby Development packages that are required to use Vagrant.

sudo dnf install -y ruby ruby-devel

Download and install latest release of Vagrant.

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo
sudo yum install vagrant -y

Hit the key to begin installation:

Transaction Summary
Install  1 Package

Total size: 42 M
Installed size: 122 M
Is this ok [y/N]: y

Step 3: Install Vagrant plugin for Libvirt

After installing KVM, Vagrant and tools required you can proceed to install vagrant plugin for KVM. This will enable you to spin virtual machines from images specific to Libvirt provider in your CentOS Stream 8 Desktop or Server.

Switch to root user account:

sudo su -

Update the Vagrant libraries:

At the time of this writing there is a compatibility issue between system libraries and the ones embedded with Vagrant. Run the following script as root to update the Vagrant libraries (Credits Oracle blog):

#!/usr/bin/env bash
# Description: override krb5/libssh libraries in Vagrant embedded libraries
set -e

# Get pre-requisites
dnf -y install libxslt-devel libxml2-devel libvirt-devel libguestfs-tools-c ruby-devel gcc byacc make cmake gcc-c++

mkdir -p vagrant-build
cd vagrant-build
dnf download --source krb5-libs libssh
# krb5
rpm2cpio krb5-*.src.rpm | cpio -idmv krb5-*.tar.gz
tar xzf krb5-*.tar.gz
pushd krb5-*/src
cp -a lib/crypto/* /opt/vagrant/embedded/lib64/

# libssh
rpm2cpio libssh-*.src.rpm | cpio -imdv  libssh-*.tar.xz
tar xJf libssh-*.tar.xz
mkdir build
pushd build
cmake ../libssh-*  -DOPENSSL_ROOT_DIR=/opt/vagrant/embedded
cp lib/libssh* /opt/vagrant/embedded/lib64/

Install Libvirt plugin for Vagrant:

# vagrant plugin install vagrant-libvirt
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.13.8-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.9.0.gem
Fetching xml-simple-1.1.9.gem
Fetching diffy-3.4.2.gem
Fetching vagrant-libvirt-0.10.8.gem
Installed the plugin 'vagrant-libvirt (0.10.8)'!

Make sure the installation was successful. For any errors encountered you can share in the comments section then we see how we can help you.

Step 4: Adding Libvirt Vagrant Boxes

Boxes are the package format for Vagrant environments. A box can be used by anyone on any platform that Vagrant supports to bring up an identical working environment.

To use the provider we just installed, we need Vagrant boxes that were built for Libvirt provider. You can explore all the boxes available in Vagrant Cloud to find your match.

In my use case I need few boxes which I can pull with the vagrant box utility created to provide all the functionality for managing boxes.

### Add CentOS Stream 8 box ###
vagrant box add centos/stream8 --provider=libvirt

### Add CentOS 7 box ###
vagrant box add centos/7 --provider=libvirt

### Add Ubuntu 22.04 box ###
vagrant box add generic/ubuntu2204 --provider=libvirt

### Add Ubuntu 20.04 box ###
vagrant box add generic/ubuntu2004 --provider=libvirt

### Add Fedora 36 box ###
vagrant box add generic/fedora36 --provider=libvirt

You can get a list of all available Vagrant boxes using the following command:

$ vagrant box list
centos/7           (libvirt, 2004.01)
centos/8           (libvirt, 1905.1)
generic/ubuntu2004 (libvirt, 3.0.20)

Running Virtual Machines with Vagrant and Libvirt on CentOS Stream 8

Vagrantfile describes the type of machine required for a project, and how to configure and provision these machines.

We’ll create a simple Vagrantfile that you can use to run:

vim Vagrantfile

Mine has the following contents:

# -*- mode: ruby -*-
# vi: set ft=ruby :


Vagrant.configure("2") do |config|

  ##### DEFINE VM #####
  config.vm.define "cent-01" do |config|
  config.vm.hostname = "cent-01" = "centos/7"
  config.vm.box_check_update = false
  config.vm.provider :libvirt do |v|
    v.memory = 1024

To start the virtual machine run:

$ vagrant up

Expected output:

Bringing machine 'default' up with 'libvirt' provider...
==> default: Registering VM image from the base box 'centos/8'...
==> default: Creating new virtual machine as a linked clone of the box image...
==> default: Unregistering the box VM image...
==> default: Setting the default configuration for VM...
==> default: Setting the name of the VM: cent8
==> default: Preparing network interfaces based on configuration...
    default: Adapter 0: shared
==> default: Clearing any previously set network interfaces...
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
==> 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: 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!
==> default: Mounting shared folders...
    default: /vagrant => /Users/jmutai/vagrant/cent8

To start SSH shell, run:

$ vagrant ssh
This system is built by the Bento project by Chef Software
More information can be found at
Last login: Fri Aug  7 00:29:28 2020

[[email protected] ~]$ cat /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)
[[email protected] ~]$ exit

To stop server once it is running, use vagrant halt command.

$ vagrant halt
==> default: Attempting graceful shutdown of VM...

To destroy the virtual machine, run:

$ vagrant destroy
    default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Destroying VM and associated drives...
==> default: Destroying unused networking interface...

All vagrant command options available are:

--version      -- Prints the Vagrant version information
box            -- Box commands
connect        -- Connects to a shared, remote Vagrant environment
destroy        -- Destroys the vagrant environment
docker-logs    -- Shows Docker logs
docker-run     -- Run one-off commands against a Docker container
global-status  -- Reports the status of all active Vagrant environments on the system
halt           -- Halts the currently running vagrant environment
help           -- [TASK] Describe available tasks or one specific task
init           -- [box_name] [box_url] Initializes current folder for Vagrant usage
list-commands  -- Outputs all available Vagrant subcommands
login          -- Authenticates against a Vagrant Cloud server to access protected boxes
package        -- Packages a vagrant environment for distribution
plugin         -- Manage plugins
provision      -- Run the provisioner
push           -- Deploys code in this environment to a configured destination
rdp            -- Connects to machine via RDP
reload         -- Reload the vagrant environment
resume         -- Resumes a suspend vagrant environment
rsync          -- Syncs rsync synced folders to remote machine
rsync-auto     -- Syncs rsync synced folders automatically when files change
share          -- Shares the Vagrant environment and allows remote access
ssh            -- SSH into the currently running environment
ssh-config     -- Outputs .ssh/config valid syntax for connecting to this environment via ssh
status         -- Shows the status of the current Vagrant environment
suspend        -- Suspends the currently running vagrant environment
up             -- Creates the vagrant environment
version        -- Prints the currently installed Vagrant version and checks for new updates

You can learn more by reading through the official Vagrant documentation.


Gravatar Image
A systems engineer with excellent skills in systems administration, cloud computing, systems deployment, virtualization, containers, and a certified ethical hacker.