libvirt / virt-manager

libvirt is a toolkit to manage virtual machines and accompanying virtual storage, networking, and more. libvirt allows easy and comprehensive management of KVM/QEMU virtual machines through graphical (virt-manager) and command-line (virsh) interfaces.

Advantages of virtualization include:

  • Run many independent operating systems/environmnents on a single physical machine

  • Quickly create, clone and delete virtual machines for temporary/testing environments or horizontal scaling

  • VM operating systems are strongly isolated from each other and from the hypervisor

  • Easy, dynamic management of resources, virtual storage, RAM, CPU… (vertical scaling)

  • Easy rollback: snapshot the state of a VM, make changes, then restore the snapshot to return to the previous state

  • Create simple or complex virtual networks with routing, switching, firewalling…

  • Easy migration of VMs between hypervisors for emergencies or load balancing

  • QEMU/KVM virtual machine performance is very close to the performance on a real, physical host (Type 1 Hypervisor) - in contrast with Type 2 hypervisors (VirtualBox, VMWare Player…)

libvirt/virt-manager can be installed on a dedicated machine, or on any GNU/Linux desktop computer.

Installation

On Debian-based systems:

# base packages
sudo apt install virtinst dnsmasq-base libvirt-daemon-system qemu-kvm qemu-utils libguestfs-tools
# graphical tools (desktop machines only)
sudo apt install virt-manager virt-viewer

(Optional) add your normal/unprivileged user account to the libvirt group to allow it to manage virtual machines without using sudo/entering your password for common operations:

sudo usermod --appent --groups $USER libvirt,kvm,libvirt-qemu

Libvirt can also be installed and managed from xsrv, using the libvirt role.

VM creation

Manual

Run virt-manager from your applications menu and click New virtual machine

Select QEMU/KVM as the virtual machine type:

Select the installation media/ISO image for the operating system you want to install:

Set memory amount and virtual CPU number depending on your performance requirements:

Create a new virtual hard disk image for your VM depending on your storage requirements:

Set a unique name (such as a FQDN) for your VM, and attach it to the default NAT virtual network:

Click Finish and start the VM from virt-manager’s main window.

Automated

You can also create a VM from the command-line using the virt-install command. The xsrv init-vm and xsrv init-vm-template commands automate running virt-install with the correct options.

Cloning VMs

See Debian/Installation/From a VM template, xsrv init-vm --help, and the following manpages:

Migrating VMs between hypervisors

# dump the VM xml definition
srvadmin@hv1:~$ virsh dumpxml my.virtual.machine > my.virtual.machine.xml
# copy the VM XML definition to the destination host
srvadmin@hv1:~$ rsync -avP my.virtual.machine.xml srvadmin@hv2.example.org:my.virtual.machine.xml
# copy the VM disks to the destination host (same directory)
srvadmin@hv1:~$ rsync -avP /var/lib/libvirt/images/my.virtual.machine.qcow2 srvadmin@hv2.example.org:/var/lib/libvirt/images/my.virtual.machine.qcow2
# ssh to the destination host
srvadmin@hv1:~$ ssh srvadmin@hv2.example.org
# create a VM from the XML definition
srvadmin@hv2:~$ virsh define my.virtual.machine.xml
# start the VM
srvadmin@hv2:~$ virsh start my.virtual.machine.xml

If your VMs are managed by the libvirt role, instead of dumping/transferring the XML definition and loading it manually, you should just copy the relevant libvirt_vms entry to the target hypervisor host_vars, and set its state to absent on the original hypervisor. Don’t forget to migrate any port forwards related to it:

# host_vars/hv1/hv1.yml
 libvirt_vms:
-  - name: my.virtual.machine
-    xml_file: "{{ playbook_dir }}/data/libvirt/my.virtual.machine.xml"
+  - name: my.virtual.machine
+    state: absent
   - name: an.other.vm
     xml_file: "{{ playbook_dir }}/data/libvirt/an.other.vm.xml"
-libvirt_port_forwards:
-  - vm_name: my.virtual.machine
-    host_port: 443
-    vm_port: 443
-    protocol: tcp
-    host_ip: 192.168.1.20
-    vm_ip: 10.0.0.101
-    bridge: virbr1

# host_vars/hv2/hv2.yml
 libvirt_vms:
+  - name: my.virtual.machine
+    xml_file: "{{ playbook_dir }}/data/libvirt/my.virtual.machine.xml"
   - name: yet.another.vm
     xml_file: "{{ playbook_dir }}/data/libvirt/yet.another.vm.xml"
+libvirt_port_forwards:
+  - vm_name: my.virtual.machine
+    host_port: 443
+    vm_port: 443
+    protocol: tcp
+    host_ip: 192.168.1.21
+    vm_ip: 10.0.0.101
+    bridge: virbr1

Share a directory from the hypervisor/host to the VM/guest

  • Access VM settings in virt-manager

  • Click Add hardware > Filesystem

    • Mode: Mapped

    • Source path: /path/to/the/directory/to/share (on the hypervisor)

    • Target path: /dev/p9-name-of-share (in the VM)

  • Inside the VM run sudo apt install 9mount, mount -t 9p /dev/p9-name-of-share /mnt/example-share

  • The shared filesystem will be available in /mnt/example-share

Alternatives

Proxmox VE, a dedicated hypervisor manager based on Debian/KVM