Start libvirt VM as unprivileged user
Tagged
admin
, bash
Quick post for starting a VM inside libvirt as a non-root user. Also contains
some useful snippets.
I want to start an alpine virt iso (from here)
inside kvm through libvirt
. But I am sick to run all my virsh commands prefixed with sudo.
DISCLAIMER: This will contain some of my conclusions with my partial understanding
of those tools. I am quite sure that all of this can be improved, but I don’t
have time to invest on this for the moment.
Packages and doc
To do this I have to install all the libvirt stuff and dependencies. I recently
changed my distrib for an Archlinux, relevant articles can be found here:
Installed packages are:
libvirt
qemu
virt-install
Libvirt is a wrapper around virtualization solutions, you can use it to
start containers and VMs through different tools and hypervisors. The virt-install
package is just a plugin of libvirt
to manage VMs installations. You can
perform all those operations directly through QEMU
if you want.
Setup
Note: libvirt command line interface is virsh
, because fuck logic, so
you don’t get lost in the following.
To make all this work I had to add myself to those groups: kvm
, libvirt
.
Libvirt comes with a definition of a default network, you can see it by typing:
sudo virsh net-dumpxml default
. This will create and start a virtual bridge
named virbr0
, for my case (check the name it will be important later on), when
the network is started.
What we will do is reuse this bridge for the VMs we will start in our user space.
To perform that we have to ensure that this network is started by libvirt at
startup:
# start libvirt at computer startup
sudo systemctl enable libvirtd
# ensure network is started by default
sudo virsh net-autostart default
Now, just one last config, QEMU provides some ACL which will allow users to
interact with parts of it, we will modificate it to add access to the virtual
bridge. We also have to set suid on the qemu bridge command so a simple user
can get permissions for setting up bridge configuration.
# create ACL directory and set the value
sudo mkdir -p /etc/qemu && echo "allow virbr0" | sudo tee /etc/qemu/bridge.conf
# enable suid on qemu bridge tool
locate qemu-bridge-helper | sudo xargs chmod +s
BEWARE: The default network bridge name has been used here (virbr0
),
check if it is the one from your default network.
Shoot!
We just have to start our new VM now, be sure to have correctly logged out and
in again before running the following commands (it makes the group changes effective).
# download the ISO
wget https://nl.alpinelinux.org/alpine/v3.5/releases/x86_64/alpine-virt-3.5.2-x86_64.iso
# start it
virt-install # create a new VM through libvirt \
--virt-type kvm # use the kvm hypervisor \
--name alpine # VM name \
--memory 1024 # allocate 1024MB of RAM \
--disk size=10 # allocate a volume of 10G for disk storage of the VM \
--noautoconsole # I don't want to start a gui on top of my VM (this part has to be investigated) \
--cdrom alpine-virt-3.5.2-x86_64.iso # the disk iso for the installation \
--network bridge=virbr0,model=virtio # the tricky part now, I define the bridge to attach my VM to \
# the model=virtio is something which makes it work properly, \
# also have to investigate it
virsh console --domain alpine # attach our console to the VM console
You should have a running VM and be able to control it without any sudo
command.
Yay \o/
Some snippets
I use some shell snippets to control the destruction of my VM.
vm=alpine
# stop a dedicated vm
virsh list | awk '$2 ~ /'"${vm}"'/ {system("virsh destroy " $2)}'
# delete it
virsh list --all | awk '$2 ~ /'"${vm}"'/ {system("virsh undefine " $2)}'
# delete all the volumes
virsh vol-list default | awk 'NR > 2 && NF > 0 {system("xargs virsh vol-delete --pool default " $1)}'