Vagrant is an open-source software product for building and maintaining portable virtual software development environments; e.g., for VirtualBox, KVM, Hyper-V, Docker containers, VMware, and AWS. It is not a stand-alone virtualization provider. It relies on other virtualization providers such as Virtualbox, Libvirt/KVM, Docker, VMWare to create and run virtual machines.
By default, Vagrant uses Oracle VirtualBox as provider. If more than one providers are installed (E.g. Virtualbox and Libvirt) in your system, it will always start a VM with Virtualbox unless you explicitly provide a specific provider. One of the great features of Vagrant is that users are never tied to a specific virtualization platform. The users can create workflows that work with multiple virtualization providers.
In this guide, we will learn how to use Vagrant with Libvirt KVM provider on Linux.
Step 1 – Installing KVM
Before proceeding, you need to have KVM installed in your system. I already have KVM installed in my system, please checkout these guides on how to install KVM:
Step 2 – Installing vagrant
Next, we need to make sure that Vagrant is installed. Vagrant is available packaged for most of the distributions, please consult the downloads page here or use your package manager to install.
To confirm that vagrant is installed and working as expected, check it’s version using this command:
➜ vagrant version Installed Version: 2.2.19 Latest Version: 2.2.19 You're running an up-to-date version of Vagrant!
Step 3 – Install vagrant-libvirt plugin
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 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.6-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 vagrant-libvirt-0.8.2.gem Installed the plugin 'vagrant-libvirt (0.8.2)'!
Once installation is complete, confirm that it has been registered fine by listing plugins:
➜ vagrant plugin list vagrant-libvirt (0.8.2, global)
Step 4 – Use Vagrant With Libvirt KVM Provider
Make sure the Vagrant box that you want to use supports the libvirt provider. To discover vagrant boxes supported by libvirt, just select the “libvirt” option in Vagrant Cloud repository.
For the purpose of this guide, I am going to use a Rocky Linux 8 box.
To add a box, use this command:
vagrant box add generic/rocky8 --provider=libvirt
Check the list of boxes presents locally.
➜ vagrant box list generic/rocky8 (libvirt, 3.6.14)
Another alternative is to use a project. Create a vagrant project directory and switch to it:
mkdir rocky-vm cd rocky-vm
Then initialize with the box you want to use:
vagrant init generic/rocky8
Next, run the following command to start the virtual machine:
vagrant up --provider=libvirt
--provider=libvirt option explicitly tells Vagrant to use libvirt KVM to run the virtual machine. Meaning – KVM acts as default provider here.
➜ vagrant up --provider=libvirt Bringing machine 'default' up with 'libvirt' provider... ==> default: Checking if box 'generic/rocky8' version '3.6.14' 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: rocky-vm_default ==> default: -- Description: Source: /home/eutychus/rocky-vm/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: -- Management MAC: ==> default: -- Loader: ==> default: -- Nvram: ==> default: -- Base box: generic/rocky8 ==> default: -- Storage pool: default ==> default: -- Image(vda): /var/lib/libvirt/images/rocky-vm_default.img, virtio, 128G ==> default: -- Disk driver opts: cache='default' ==> default: -- Kernel: ==> default: -- Initrd: ==> default: -- Graphics Type: vnc ==> default: -- Graphics Port: -1 ==> default: -- Graphics IP: 127.0.0.1 ==> default: -- Graphics Password: Not defined ==> default: -- Video Type: cirrus ==> default: -- Video VRAM: 256 ==> default: -- Video 3D accel: false ==> default: -- Sound Type: ==> default: -- Keymap: en-us ==> default: -- TPM Backend: passthrough ==> default: -- TPM Path: ==> default: -- INPUT: type=mouse, bus=ps2 ==> default: Creating shared folders metadata... ==> default: Starting domain. ==> default: Waiting for domain to get an IP address... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 192.168.121.43:22 default: SSH username: vagrant default: SSH auth method: private key default: default: Vagrant insecure key detected. Vagrant will automatically replace default: this with a newly generated keypair for better security. default: 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!
Alternatively you can tell Vagrant to permanently use libvirt as default provider by adding the following environment variable.
Vagrant will create a Linux bridge on the host system.
➜ brctl show virbr1 bridge name bridge id STP enabled interfaces virbr1 8000.5254009d4555 yes vnet0
You can also check the ip
➜ ip addr show dev virbr1 9: virbr1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 52:54:00:9d:45:55 brd ff:ff:ff:ff:ff:ff inet 192.168.121.1/24 brd 192.168.121.255 scope global virbr1 valid_lft forever preferred_lft forever
Step 5 – Verify that the vm is running
You can verify if the CentOS 7 VM is really running in Libvirt KVM provider from Virsh command line interface.
Id Name State ---------------------------------- 1 rocky-vm_default running
vagrant status command:
➜ vagrant status Current machine states: default running (libvirt) The Libvirt domain is running. To stop this machine, you can run `vagrant halt`. To destroy the machine, you can run `vagrant destroy`.
You can also verify it from a KVM management GUI applications like Virt-manager.
To ssh to the VM, use vagrant ssh command.
➜ vagrant ssh [[email protected] ~]$
To output .ssh/config valid syntax for connecting to this environment via ssh, run ssh-config command. You’ll need to place provided output under ~/.ssh/config directory to ssh.
➜ vagrant ssh-config Host default HostName 192.168.121.43 User vagrant Port 22 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /home/eutychus/rocky-vm/.vagrant/machines/default/libvirt/private_key IdentitiesOnly yes LogLevel FATAL
To shut down the VM, run:
➜ vagrant halt ==> default: Attempting graceful shutdown of VM...
To set VM to its initial state by cleaning all data, use vagrant destroy:
➜ vagrant destroy default: Are you sure you want to destroy the 'default' VM? [y/N] y ==> default: Removing domain... ==> default: Deleting the machine folder
In this guide, we learned how to use Vagrant with libvirt KVM provider in Linux. We also looked at how to verify if the virtual machine is running in Libvirt KVM.