Skip to Content
DocsServerVirtualization

Virtualization and Containers

Ubuntu 26.04 provides a complete virtualization and container technology stack. This article covers KVM/QEMU hardware virtualization, libvirt management tools, LXD system containers, and the MicroCloud cluster solution.

KVM / QEMU

KVM (Kernel-based Virtual Machine) is a virtualization module built into the Linux kernel. Combined with QEMU, it provides full hardware virtualization capabilities.

Check Hardware Support

# Check CPU virtualization support grep -Ec '(vmx|svm)' /proc/cpuinfo # Output greater than 0 means supported # Or use the kvm-ok tool sudo apt install cpu-checker -y kvm-ok

Install KVM

sudo apt update sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager -y # Add current user to the libvirt group sudo usermod -aG libvirt $USER sudo usermod -aG kvm $USER newgrp libvirt # Verify service is running sudo systemctl status libvirtd # Verify installation virsh list --all

Create a VM with virt-install

# Download ISO wget https://releases.ubuntu.com/26.04/ubuntu-26.04-live-server-amd64.iso -O /var/lib/libvirt/images/ubuntu-26.04.iso # Create a virtual machine # Note: --os-variant should match the ISO. If your local osinfo-db does not # list it yet, confirm with osinfo-query os | grep ubuntu. If it is not listed, # you can temporarily fall back to ubuntu24.04, or use # --os-variant detect=on,name=ubuntu26.04 virt-install \ --name ubuntu-vm \ --ram 2048 \ --vcpus 2 \ --disk path=/var/lib/libvirt/images/ubuntu-vm.qcow2,size=20,format=qcow2 \ --cdrom /var/lib/libvirt/images/ubuntu-26.04.iso \ --os-variant ubuntu26.04 \ --network bridge=virbr0 \ --graphics vnc,listen=0.0.0.0,port=5901 \ --console pty,target_type=serial \ --noautoconsole # Use a cloud image for quick creation (no installation process needed) wget https://cloud-images.ubuntu.com/releases/26.04/release/ubuntu-26.04-server-cloudimg-amd64.img # Create a disk copy and resize cp ubuntu-26.04-server-cloudimg-amd64.img /var/lib/libvirt/images/vm-disk.qcow2 qemu-img resize /var/lib/libvirt/images/vm-disk.qcow2 20G # Use with cloud-init # If osinfo-db does not list ubuntu26.04, you can temporarily fall back to ubuntu24.04 virt-install \ --name cloud-vm \ --ram 2048 \ --vcpus 2 \ --disk /var/lib/libvirt/images/vm-disk.qcow2 \ --import \ --os-variant ubuntu26.04 \ --network bridge=virbr0 \ --cloud-init user-data=cloud-config.yaml \ --noautoconsole

Common virsh Commands

# VM management virsh list --all # List all VMs virsh start ubuntu-vm # Start virsh shutdown ubuntu-vm # Graceful shutdown virsh destroy ubuntu-vm # Force shutdown virsh reboot ubuntu-vm # Reboot virsh suspend ubuntu-vm # Suspend virsh resume ubuntu-vm # Resume virsh undefine ubuntu-vm --remove-all-storage # Delete VM and its disks virsh autostart ubuntu-vm # Enable autostart at boot # Resource adjustment virsh setvcpus ubuntu-vm 4 --config # Change CPU count (requires shutdown) virsh setmaxmem ubuntu-vm 4G --config # Change max memory virsh setmem ubuntu-vm 4G --config # Change current memory # Snapshot management virsh snapshot-create-as ubuntu-vm snap1 "Post-install snapshot" virsh snapshot-list ubuntu-vm virsh snapshot-revert ubuntu-vm snap1 virsh snapshot-delete ubuntu-vm snap1 # Console access virsh console ubuntu-vm # Serial console virsh vncdisplay ubuntu-vm # Show VNC port # Disk management qemu-img info /var/lib/libvirt/images/ubuntu-vm.qcow2 qemu-img resize /var/lib/libvirt/images/ubuntu-vm.qcow2 +10G

Network Bridge Configuration

# Create a bridge (Netplan configuration) sudo tee /etc/netplan/01-bridge.yaml << 'EOF' network: version: 2 renderer: networkd ethernets: ens33: dhcp4: false bridges: br0: interfaces: - ens33 dhcp4: true parameters: stp: false forward-delay: 0 EOF sudo netplan apply # Use the bridge network in libvirt virsh net-define bridge-net.xml virsh net-start bridge-net virsh net-autostart bridge-net

libvirt Management

Define a VM with XML

<!-- /etc/libvirt/qemu/example-vm.xml --> <domain type='kvm'> <name>example-vm</name> <memory unit='GiB'>4</memory> <vcpu placement='static'>2</vcpu> <os> <type arch='x86_64' machine='q35'>hvm</type> <boot dev='hd'/> </os> <features> <acpi/> <apic/> </features> <cpu mode='host-passthrough'/> <devices> <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/var/lib/libvirt/images/example-vm.qcow2'/> <target dev='vda' bus='virtio'/> </disk> <interface type='bridge'> <source bridge='br0'/> <model type='virtio'/> </interface> <console type='pty'> <target type='serial' port='0'/> </console> <graphics type='vnc' port='-1' autoport='yes'/> </devices> </domain>
# Create a VM from XML virsh define example-vm.xml virsh start example-vm

Storage Pool Management

# List storage pools virsh pool-list --all # Create a directory storage pool virsh pool-define-as mypool dir --target /data/libvirt/images virsh pool-build mypool virsh pool-start mypool virsh pool-autostart mypool # Create a volume virsh vol-create-as mypool vm-disk.qcow2 20G --format qcow2 # List volumes virsh vol-list mypool

LXD System Containers

LXD provides lightweight system containers with a full Linux system environment, fast startup times, and low resource overhead.

Install LXD

# Install via Snap sudo snap install lxd # Initialize LXD sudo lxd init # Interactive configuration: # - Clustering: no (standalone) # - Storage pool: dir or zfs # - Network: create a new bridge network # - Auto-update images: yes # Minimal initialization sudo lxd init --minimal # Add user to the lxd group sudo usermod -aG lxd $USER newgrp lxd

LXD Container Management

# View available images lxc image list ubuntu: # Ubuntu official images lxc image list images: # Community images # Launch a container lxc launch ubuntu:26.04 my-container lxc launch ubuntu:26.04 web-server # Launch a virtual machine (LXD also supports VMs) lxc launch ubuntu:26.04 my-vm --vm # Container operations lxc list # List all lxc start my-container # Start lxc stop my-container # Stop lxc restart my-container # Restart lxc delete my-container --force # Delete lxc info my-container # Detailed info # Enter a container lxc exec my-container -- bash lxc exec my-container -- cat /etc/os-release # File transfer lxc file push local-file.txt my-container/root/ lxc file pull my-container/etc/hostname . # Snapshots lxc snapshot my-container snap0 lxc restore my-container snap0 lxc info my-container # View snapshot list

LXD Resource Limits

# CPU limit lxc config set my-container limits.cpu 2 # Memory limit lxc config set my-container limits.memory 1GB # Disk limit lxc config device set my-container root size=10GB # Network bandwidth limit lxc config device set my-container eth0 limits.ingress=100Mbit lxc config device set my-container eth0 limits.egress=100Mbit

LXD Profiles

# Create a custom profile lxc profile create web-server lxc profile set web-server limits.cpu 2 lxc profile set web-server limits.memory 2GB # Launch a container using a profile lxc launch ubuntu:26.04 web1 --profile default --profile web-server # View the profile lxc profile show web-server # cloud-init integration lxc profile set web-server user.user-data - << 'EOF' #cloud-config packages: - nginx runcmd: - systemctl enable --now nginx EOF

MicroCloud

MicroCloud is a lightweight cluster solution from Canonical that integrates LXD, MicroCeph (distributed storage), and MicroOVN (SDN networking).

Install MicroCloud

# Install on all nodes sudo snap install lxd sudo snap install microceph sudo snap install microovn sudo snap install microcloud # Initialize the cluster on the first node sudo microcloud init

Initialize the Cluster

# microcloud init will guide you through: # 1. Discovering other nodes on the LAN # 2. Selecting nodes to join the cluster # 3. Configuring MicroCeph distributed storage # 4. Configuring MicroOVN networking # 5. Configuring the LXD cluster # Verify after initialization lxc cluster list sudo microceph status sudo microovn status

Using the MicroCloud Cluster

# Launch containers (automatically distributed across cluster nodes) lxc launch ubuntu:26.04 app1 lxc launch ubuntu:26.04 app2 lxc launch ubuntu:26.04 app3 # Launch on a specific node lxc launch ubuntu:26.04 db1 --target node2 # View container distribution lxc list -c nNtSl # Live-migrate a container lxc move app1 --target node3

Technology Comparison

FeatureKVM/QEMULXD ContainersDocker
Virtualization typeHardware virtualizationSystem containersApplication containers
Isolation levelFull isolationShared kernelShared kernel
Startup timeTens of seconds1-2 secondsSub-second
Resource overheadHigherLowVery low
KernelIndependent kernelShared host kernelShared host kernel
Use caseHeterogeneous OSFull Linux environmentsMicroservices
DensityLowHighVery high
Live migrationSupportedSupportedRequires orchestration tools

Recommendations

  • KVM/QEMU: Running different operating systems, strongest isolation required, traditional virtualization scenarios
  • LXD: Full Linux system environments, development and testing, lightweight service isolation
  • Docker: Microservice deployment, CI/CD, application packaging and distribution
  • MicroCloud: Small clusters, edge computing, simple distributed solutions

Management Tools

Cockpit Web Console

# Install Cockpit sudo apt install cockpit cockpit-machines -y # Start the service sudo systemctl enable --now cockpit.socket # Access at https://server-ip:9090 # Manage virtual machines through the web interface # Firewall sudo ufw allow 9090/tcp

virt-manager (Graphical Management)

# Install (requires a desktop environment or X11 forwarding) sudo apt install virt-manager -y # Remote connection (via SSH X11 forwarding) ssh -X user@server virt-manager
Last updated on