Vagrant with the libvirt plugin
Here is a post about how to create virtual machines with Vagrant and the libvirt plugin.
Why use libvirt as a vagrant provider
Because when on a modern Linux distro running Gnome, chances are it's already there!
I use Vagrant extensively to run quick, short lived virtual machines to test and try out things. I always used and use Virtualbox as a virtual machine provider for Vagrant. Maybe I am late to the party but I recently discovered Gnome Boxes and I was wondering about the underlying architecture. Then I went on vacation and finally took the time to investigate.
The answer is: KVM. Together with QEMU and libvirt. (I remember using Qemu back in the 2007 or so but thinking it was terribly slow and left it for what is was. But its 2020 now, so let's dive in again!)
KVM, QEMU, libvirt: lost in the limbo
To refresh the memory a bit, a hypervisor is software that creates and runs virtual machines. Type 1 hypervisors (like Xen, ESXi and Hyper-V) run directly on the hardware. Type 2 hypervisors (Parallels, Virtualbox, Vmware Fusion) run on top of an OS. KVM turns Linux into a type 1 hypervisor, but at the same time runs a fully functional OS. So it is a special case of a hypervisor.
KVM provides device abstraction but does not emulate a machine. It exposes the /dev/kvm interface, which a user mode host can then use to:
- Bootstrap an iso (set up theguest VM address space)
- Feed the guest simulated I/O
- Map the guest's video display back onto the system host
On Linux, QEMU is one such userspace host. QEMU uses KVM when available to virtualize guests at near-native speeds, but otherwise falls back to software-only emulation.
The last piece of the puzzle is libvirt Libvirt provides a convenient way to storage and network interface management for virtual machines. Libvirt includes an API library, a daemon (libvirtd), and a command line utility (virsh).
Gnome Boxes uses libvirt, as does Vagrant. Hence the blog title: using Vagrant with the libvirt plugin.
Let's run a VM already
If you run this on Fedora 32, you can see that lots of packages are already installed:
1dnf list --installed | grep libvirt
2dnf list --installed | grep qemu
We need Vagrant and the vagrant-libvirt plugin:
1sudo dnf install vagrant
2sudo vagrant plugin install vagrant-libvirt
Then make a folder and add a Vagrantfile in it
1
2mkdir ~/vagrant/centos && cd ~/vagrant/centos
3
4cat > Vagrantfile <<'EOF'
5$extra = <<-EXTRA
6dnf update -y && dnf install vim net-tools git lsof tar -y
7EXTRA
8
9Vagrant.configure("2") do |config|
10 config.vm.define "node01" do |node01_config|
11 node01_config.vm.box ="generic/centos8"
12 node01_config.vm.hostname = "centos01"
13 node01_config.vm.provider :libvirt do |domain|
14 domain.memory = 4096
15 domain.cpus = 2
16 domain.nested = true
17 domain.volume_cache = 'none'
18 end
19 end
20 config.vm.provision "shell", inline: $extra
21end
22EOF
And then do
1vagrant up
Hooray!
Afterthought: What about LXC and LXD?
You can also run LXD instead of KVM. I think that LXD is the Canonical way, while KVM has been adopted by RedHat (fact check probably needed). Traditionally, LXD is used to create system containers, light-weight virtual machines that use Linux Container features and not hardware virtualization. However with LXD you can create both system containers and virtual machines. Here is a nice blog post explaining that.