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-okInstall 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 --allCreate 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 \
--noautoconsoleCommon 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 +10GNetwork 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-netlibvirt 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-vmStorage 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 mypoolLXD 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 lxdLXD 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 listLXD 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=100MbitLXD 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
EOFMicroCloud
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 initInitialize 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 statusUsing 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 node3Technology Comparison
| Feature | KVM/QEMU | LXD Containers | Docker |
|---|---|---|---|
| Virtualization type | Hardware virtualization | System containers | Application containers |
| Isolation level | Full isolation | Shared kernel | Shared kernel |
| Startup time | Tens of seconds | 1-2 seconds | Sub-second |
| Resource overhead | Higher | Low | Very low |
| Kernel | Independent kernel | Shared host kernel | Shared host kernel |
| Use case | Heterogeneous OS | Full Linux environments | Microservices |
| Density | Low | High | Very high |
| Live migration | Supported | Supported | Requires 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/tcpvirt-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-managerLast updated on