Libvirt and virsh Management
Overview
- What you’ll learn: How to manage virtual machines using the libvirt API and its command-line tool virsh, including XML domain definitions, storage pool management, virtual networking configuration, and lifecycle operations.
- Prerequisites: QEMU/KVM Virtual Machines (Lesson 55), basic XML familiarity
- Estimated reading time: 20 minutes
Introduction
While QEMU provides powerful command-line options for running virtual machines, managing multiple VMs with complex configurations through raw QEMU commands quickly becomes unwieldy. Libvirt solves this problem by providing a unified management layer that abstracts the underlying hypervisor technology. It offers a stable API, persistent configuration through XML definitions, and a rich set of management tools.
The libvirt project consists of several components: the libvirtd daemon that manages the hypervisor and VMs, the virsh command-line interface for administration, and client libraries for building custom management applications. Libvirt supports multiple hypervisor backends including QEMU/KVM, Xen, LXC, and VMware ESXi, making it a versatile foundation for virtualization management.
In this lesson, you will install and configure libvirt on Ubuntu, learn to define virtual machines using XML domain descriptions, manage storage pools and volumes, configure virtual networks, and perform common VM lifecycle operations using virsh.
Installing and Configuring Libvirt
Libvirt is distributed as part of the standard Ubuntu package repositories. The installation includes the daemon, client tools, and default network/storage configurations that get you started immediately.
# Install libvirt and related tools
$ sudo apt update
$ sudo apt install -y libvirt-daemon-system libvirt-clients virtinst virt-viewer
# Verify libvirtd is running
$ sudo systemctl status libvirtd
● libvirtd.service - Virtualization daemon
Active: active (running) since Mon 2025-12-01 10:00:00 UTC
# Add your user to the libvirt group
$ sudo usermod -aG libvirt $USER
$ newgrp libvirt
# Verify connection to the hypervisor
$ virsh uri
qemu:///system
# List capabilities of the hypervisor
$ virsh capabilities | head -20
<capabilities>
<host>
<cpu>
<arch>x86_64</arch>
<model>Skylake-Client-IBRS</model>
</cpu>
</host>
...
# Check the default storage pool and network
$ virsh pool-list --all
Name State Autostart
-------------------------------
default active yes
$ virsh net-list --all
Name State Autostart Persistent
--------------------------------------------
default active yes yes
The libvirt-daemon-system package installs the libvirtd daemon and its systemd integration. The virtinst package provides virt-install, a convenient tool for creating new VMs. After installation, libvirt automatically creates a default NAT network (virbr0) and a default storage pool pointing to /var/lib/libvirt/images/.
XML Domain Definitions
In libvirt, a virtual machine is called a domain. Each domain is described by an XML document that specifies its hardware configuration, including CPU, memory, disks, network interfaces, and other devices. This declarative approach makes VM configurations portable, version-controllable, and reproducible.
# Example domain XML (ubuntu-vm.xml)
<domain type='kvm'>
<name>ubuntu-vm</name>
<memory unit='GiB'>4</memory>
<vcpu placement='static'>2</vcpu>
<os>
<type arch='x86_64' machine='pc-q35-6.2'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
</features>
<cpu mode='host-passthrough' check='none'/>
<devices>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' discard='unmap'/>
<source file='/var/lib/libvirt/images/ubuntu-vm.qcow2'/>
<target dev='vda' bus='virtio'/>
</disk>
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
</interface>
<graphics type='vnc' port='-1' autoport='yes'/>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
</devices>
</domain>
# Define the domain from XML
$ virsh define ubuntu-vm.xml
Domain 'ubuntu-vm' defined from ubuntu-vm.xml
# Dump the current XML of a running domain
$ virsh dumpxml ubuntu-vm
# Edit a domain's XML interactively
$ virsh edit ubuntu-vm
The type='kvm' attribute on the root element tells libvirt to use KVM hardware acceleration. The cpu mode='host-passthrough' exposes the host CPU model directly to the guest for maximum performance. All disk and network devices use virtio drivers (bus='virtio' and model type='virtio') for optimal I/O performance. The virsh define command registers the domain persistently, while virsh create would start a transient domain.
Storage Pools and Volumes
Libvirt manages disk storage through storage pools and volumes. A storage pool is a source of storage (a directory, an LVM volume group, an NFS share, etc.), and volumes are individual disk images within that pool. This abstraction simplifies storage management across different backends.
# List storage pools
$ virsh pool-list --all
Name State Autostart
-------------------------------
default active yes
# View pool details
$ virsh pool-info default
Name: default
UUID: a1b2c3d4-e5f6-...
State: running
Persistent: yes
Autostart: yes
Capacity: 100.00 GiB
Allocation: 25.30 GiB
Available: 74.70 GiB
# Create a new directory-based storage pool
$ virsh pool-define-as mypool dir --target /srv/libvirt/images
Pool mypool defined
$ virsh pool-build mypool
Pool mypool built
$ virsh pool-start mypool
Pool mypool started
$ virsh pool-autostart mypool
Pool mypool marked as autostarted
# Create a volume in the pool
$ virsh vol-create-as default ubuntu-vm.qcow2 20G --format qcow2
Vol ubuntu-vm.qcow2 created
# List volumes in a pool
$ virsh vol-list default
Name Path
-----------------------------------------------------------
ubuntu-vm.qcow2 /var/lib/libvirt/images/ubuntu-vm.qcow2
# Clone a volume
$ virsh vol-clone ubuntu-vm.qcow2 ubuntu-vm-clone.qcow2 --pool default
# Delete a volume
$ virsh vol-delete ubuntu-vm-clone.qcow2 --pool default
Storage pools decouple VM definitions from specific file paths. When you move VMs between hosts, you only need to ensure the destination has a pool with the same name. Libvirt supports directory pools, LVM pools, iSCSI pools, NFS pools, and more.
Virtual Networking
Libvirt provides virtual network management through its network XML definitions. The default network uses NAT to give VMs internet access while isolating them from the physical network. You can also create isolated networks, routed networks, or bridge directly to physical interfaces.
# View the default network configuration
$ virsh net-dumpxml default
<network>
<name>default</name>
<forward mode='nat'/>
<bridge name='virbr0' stp='on' delay='0'/>
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
</dhcp>
</ip>
</network>
# Create an isolated network (no external access)
$ cat isolated-net.xml
<network>
<name>isolated</name>
<bridge name='virbr1'/>
<ip address='10.10.10.1' netmask='255.255.255.0'>
<dhcp>
<range start='10.10.10.2' end='10.10.10.254'/>
</dhcp>
</ip>
</network>
$ virsh net-define isolated-net.xml
$ virsh net-start isolated
$ virsh net-autostart isolated
# List DHCP leases on the default network
$ virsh net-dhcp-leases default
Expiry Time MAC address IP address Hostname
-------------------------------------------------------------------------
2025-12-01 11:00:00 52:54:00:ab:cd:ef 192.168.122.100/24 ubuntu-vm
The default NAT network provides a simple way for VMs to access the internet through the host. The virbr0 bridge acts as the gateway for VMs, and libvirt runs a dnsmasq instance to provide DHCP and DNS services. For production environments, you may want to configure bridged networking that connects VMs directly to the physical network.
VM Lifecycle Operations with virsh
Virsh provides commands for every stage of a virtual machine’s lifecycle, from creation and startup to migration and deletion. Mastering these commands is essential for day-to-day VM administration.
# Create a new VM using virt-install
$ virt-install
--name ubuntu-vm
--ram 4096
--vcpus 2
--cpu host-passthrough
--disk path=/var/lib/libvirt/images/ubuntu-vm.qcow2,size=20,format=qcow2,bus=virtio
--network network=default,model=virtio
--os-variant ubuntu22.04
--cdrom /var/lib/libvirt/isos/ubuntu-22.04-live-server-amd64.iso
--graphics vnc,listen=0.0.0.0
--noautoconsole
# List all domains
$ virsh list --all
Id Name State
---------------------------
1 ubuntu-vm running
- test-vm shut off
# Start, pause, resume, shutdown, and destroy
$ virsh start ubuntu-vm
$ virsh suspend ubuntu-vm
$ virsh resume ubuntu-vm
$ virsh shutdown ubuntu-vm # graceful ACPI shutdown
$ virsh destroy ubuntu-vm # force power off (like pulling the plug)
# Reboot a domain
$ virsh reboot ubuntu-vm
# Access the console
$ virsh console ubuntu-vm
Connected to domain 'ubuntu-vm'
Escape character is ^]
# Take and manage snapshots
$ virsh snapshot-create-as ubuntu-vm --name "before-upgrade" --description "Clean state"
Domain snapshot before-upgrade created
$ virsh snapshot-list ubuntu-vm
Name Creation Time State
------------------------------------------------------
before-upgrade 2025-12-01 10:30:00 +0000 running
$ virsh snapshot-revert ubuntu-vm before-upgrade
$ virsh snapshot-delete ubuntu-vm before-upgrade
# View domain resource usage
$ virsh dominfo ubuntu-vm
Id: 1
Name: ubuntu-vm
State: running
CPU(s): 2
Max memory: 4194304 KiB
Used memory: 4194304 KiB
# Undefine (delete) a domain
$ virsh undefine ubuntu-vm --remove-all-storage
The virt-install command simplifies new VM creation by generating the XML definition and starting the installation in one step. The --os-variant option optimizes the VM configuration for the specified operating system. For ongoing management, virsh start, virsh shutdown, and virsh destroy control the power state. Snapshots allow you to save and restore VM states, which is invaluable for testing and development workflows.
Key Takeaways
- Libvirt provides a unified management layer over QEMU/KVM with the libvirtd daemon handling VM lifecycle, storage, and networking through a stable API.
- Virtual machines (domains) are defined declaratively in XML, making configurations portable, reproducible, and suitable for version control.
- Storage pools abstract the underlying storage backend (directory, LVM, NFS), while volumes represent individual disk images that can be created, cloned, and managed independently.
- Virtual networks support NAT, isolated, routed, and bridged modes with built-in DHCP and DNS provided by dnsmasq.
- The virsh command-line tool provides comprehensive lifecycle management including start, stop, snapshot, console access, and domain configuration editing.
What’s Next
In Lesson 57, you will learn about LXD System Containers, which provide a lightweight alternative to full virtual machines by running complete Linux system images in containers managed through the lxc command-line tool.
繁體中文
概述
- 學習目標:了解如何使用 libvirt API 及其命令列工具 virsh 來管理虛擬機器,包括 XML 網域定義、儲存池管理、虛擬網路配置和生命週期操作。
- 先決條件:QEMU/KVM 虛擬機器(第 55 課),基本的 XML 知識
- 預計閱讀時間:20 分鐘
簡介
雖然 QEMU 提供了強大的命令列選項來執行虛擬機器,但透過原始 QEMU 命令管理具有複雜配置的多個 VM 很快就變得難以管理。Libvirt 透過提供統一的管理層來解決這個問題,該管理層抽象化了底層的 Hypervisor 技術。它提供穩定的 API、透過 XML 定義的持久性配置以及豐富的管理工具集。
Libvirt 專案由幾個元件組成:管理 Hypervisor 和 VM 的 libvirtd 守護程式、用於管理的 virsh 命令列介面,以及用於建構自訂管理應用程式的用戶端程式庫。Libvirt 支援多種 Hypervisor 後端,包括 QEMU/KVM、Xen、LXC 和 VMware ESXi。
在本課程中,您將在 Ubuntu 上安裝和配置 libvirt、學習使用 XML 網域描述定義虛擬機器、管理儲存池和磁碟區、配置虛擬網路,以及使用 virsh 執行常見的 VM 生命週期操作。
安裝和配置 Libvirt
Libvirt 作為標準 Ubuntu 套件庫的一部分發布。安裝包括守護程式、用戶端工具以及預設的網路和儲存配置。
# 安裝 libvirt 和相關工具
$ sudo apt update
$ sudo apt install -y libvirt-daemon-system libvirt-clients virtinst virt-viewer
# 驗證 libvirtd 正在執行
$ sudo systemctl status libvirtd
# 將使用者加入 libvirt 群組
$ sudo usermod -aG libvirt $USER
# 驗證與 Hypervisor 的連線
$ virsh uri
qemu:///system
# 檢查預設儲存池和網路
$ virsh pool-list --all
$ virsh net-list --all
XML 網域定義
在 libvirt 中,虛擬機器稱為網域。每個網域由一個 XML 文件描述,該文件指定其硬體配置,包括 CPU、記憶體、磁碟、網路介面和其他裝置。這種宣告式方法使 VM 配置具有可移植性、可版本控制性和可重現性。
# 範例網域 XML
<domain type='kvm'>
<name>ubuntu-vm</name>
<memory unit='GiB'>4</memory>
<vcpu placement='static'>2</vcpu>
<os>
<type arch='x86_64'>hvm</type>
<boot dev='hd'/>
</os>
<cpu mode='host-passthrough'/>
<devices>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/libvirt/images/ubuntu-vm.qcow2'/>
<target dev='vda' bus='virtio'/>
</disk>
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
</interface>
</devices>
</domain>
# 從 XML 定義網域
$ virsh define ubuntu-vm.xml
# 匯出執行中網域的 XML
$ virsh dumpxml ubuntu-vm
# 互動式編輯網域 XML
$ virsh edit ubuntu-vm
儲存池和磁碟區
Libvirt 透過儲存池和磁碟區來管理磁碟儲存。儲存池是儲存來源(目錄、LVM 磁碟區群組、NFS 共享等),磁碟區是該池中的個別磁碟映像。
# 列出儲存池
$ virsh pool-list --all
# 查看池詳細資訊
$ virsh pool-info default
# 建立新的目錄型儲存池
$ virsh pool-define-as mypool dir --target /srv/libvirt/images
$ virsh pool-build mypool
$ virsh pool-start mypool
$ virsh pool-autostart mypool
# 在池中建立磁碟區
$ virsh vol-create-as default ubuntu-vm.qcow2 20G --format qcow2
# 列出池中的磁碟區
$ virsh vol-list default
# 複製磁碟區
$ virsh vol-clone ubuntu-vm.qcow2 ubuntu-vm-clone.qcow2 --pool default
虛擬網路
Libvirt 透過其網路 XML 定義提供虛擬網路管理。預設網路使用 NAT 為 VM 提供網際網路存取,同時將它們與實體網路隔離。您還可以建立隔離網路、路由網路,或直接橋接到實體介面。
# 查看預設網路配置
$ virsh net-dumpxml default
# 建立隔離網路
$ virsh net-define isolated-net.xml
$ virsh net-start isolated
$ virsh net-autostart isolated
# 列出預設網路的 DHCP 租約
$ virsh net-dhcp-leases default
使用 virsh 進行 VM 生命週期操作
Virsh 為虛擬機器生命週期的每個階段提供命令,從建立和啟動到遷移和刪除。
# 使用 virt-install 建立新 VM
$ virt-install
--name ubuntu-vm
--ram 4096
--vcpus 2
--disk path=/var/lib/libvirt/images/ubuntu-vm.qcow2,size=20
--network network=default,model=virtio
--os-variant ubuntu22.04
--cdrom /path/to/ubuntu.iso
--noautoconsole
# 列出所有網域
$ virsh list --all
# 啟動、暫停、恢復、關閉和強制關閉
$ virsh start ubuntu-vm
$ virsh suspend ubuntu-vm
$ virsh resume ubuntu-vm
$ virsh shutdown ubuntu-vm
$ virsh destroy ubuntu-vm
# 建立和管理快照
$ virsh snapshot-create-as ubuntu-vm --name "before-upgrade"
$ virsh snapshot-list ubuntu-vm
$ virsh snapshot-revert ubuntu-vm before-upgrade
$ virsh snapshot-delete ubuntu-vm before-upgrade
# 取消定義(刪除)網域
$ virsh undefine ubuntu-vm --remove-all-storage
重點摘要
- Libvirt 在 QEMU/KVM 之上提供統一的管理層,libvirtd 守護程式透過穩定的 API 處理 VM 生命週期、儲存和網路。
- 虛擬機器(網域)以宣告式 XML 定義,使配置具有可移植性、可重現性,並適合版本控制。
- 儲存池抽象化了底層儲存後端(目錄、LVM、NFS),而磁碟區代表可以獨立建立、複製和管理的個別磁碟映像。
- 虛擬網路支援 NAT、隔離、路由和橋接模式,內建由 dnsmasq 提供的 DHCP 和 DNS。
- virsh 命令列工具提供全面的生命週期管理,包括啟動、停止、快照、主控台存取和網域配置編輯。
下一步
在第 57 課中,您將學習 LXD 系統容器,它透過在由 lxc 命令列工具管理的容器中執行完整的 Linux 系統映像,提供了完整虛擬機器的輕量級替代方案。
日本語
概要
- 学習内容:libvirt API とそのコマンドラインツール virsh を使用した仮想マシンの管理方法。XML ドメイン定義、ストレージプール管理、仮想ネットワーク構成、ライフサイクル操作を含みます。
- 前提条件:QEMU/KVM 仮想マシン(レッスン55)、基本的な XML の知識
- 推定読了時間:20分
はじめに
QEMU は仮想マシンを実行するための強力なコマンドラインオプションを提供しますが、生の QEMU コマンドで複雑な構成を持つ複数の VM を管理することはすぐに手に負えなくなります。Libvirt は、基盤となるハイパーバイザー技術を抽象化する統一管理レイヤーを提供することで、この問題を解決します。安定した API、XML 定義による永続的な構成、豊富な管理ツールセットを提供します。
Libvirt プロジェクトはいくつかのコンポーネントで構成されています:ハイパーバイザーと VM を管理する libvirtd デーモン、管理用の virsh コマンドラインインターフェース、カスタム管理アプリケーション構築用のクライアントライブラリです。Libvirt は QEMU/KVM、Xen、LXC、VMware ESXi を含む複数のハイパーバイザーバックエンドをサポートします。
このレッスンでは、Ubuntu に libvirt をインストール・構成し、XML ドメイン記述を使用した仮想マシンの定義、ストレージプールとボリュームの管理、仮想ネットワークの構成、virsh を使用した一般的な VM ライフサイクル操作を学びます。
Libvirt のインストールと構成
Libvirt は標準の Ubuntu パッケージリポジトリの一部として配布されています。インストールにはデーモン、クライアントツール、デフォルトのネットワーク/ストレージ構成が含まれます。
# libvirt と関連ツールをインストール
$ sudo apt update
$ sudo apt install -y libvirt-daemon-system libvirt-clients virtinst virt-viewer
# libvirtd の稼働を確認
$ sudo systemctl status libvirtd
# ユーザーを libvirt グループに追加
$ sudo usermod -aG libvirt $USER
# ハイパーバイザーへの接続を確認
$ virsh uri
qemu:///system
# デフォルトのストレージプールとネットワークを確認
$ virsh pool-list --all
$ virsh net-list --all
XML ドメイン定義
libvirt では、仮想マシンはドメインと呼ばれます。各ドメインは、CPU、メモリ、ディスク、ネットワークインターフェース、その他のデバイスを含むハードウェア構成を指定する XML ドキュメントで記述されます。この宣言的アプローチにより、VM 構成はポータブルで、バージョン管理可能で、再現可能になります。
# ドメイン XML の例
<domain type='kvm'>
<name>ubuntu-vm</name>
<memory unit='GiB'>4</memory>
<vcpu placement='static'>2</vcpu>
<os>
<type arch='x86_64'>hvm</type>
<boot dev='hd'/>
</os>
<cpu mode='host-passthrough'/>
<devices>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/libvirt/images/ubuntu-vm.qcow2'/>
<target dev='vda' bus='virtio'/>
</disk>
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
</interface>
</devices>
</domain>
# XML からドメインを定義
$ virsh define ubuntu-vm.xml
# 実行中のドメインの XML をダンプ
$ virsh dumpxml ubuntu-vm
# ドメインの XML をインタラクティブに編集
$ virsh edit ubuntu-vm
ストレージプールとボリューム
Libvirt はストレージプールとボリュームを通じてディスクストレージを管理します。ストレージプールはストレージソース(ディレクトリ、LVM ボリュームグループ、NFS 共有など)であり、ボリュームはそのプール内の個々のディスクイメージです。
# ストレージプールを一覧表示
$ virsh pool-list --all
# プール詳細を表示
$ virsh pool-info default
# 新しいディレクトリベースのストレージプールを作成
$ virsh pool-define-as mypool dir --target /srv/libvirt/images
$ virsh pool-build mypool
$ virsh pool-start mypool
$ virsh pool-autostart mypool
# プール内にボリュームを作成
$ virsh vol-create-as default ubuntu-vm.qcow2 20G --format qcow2
# プール内のボリュームを一覧表示
$ virsh vol-list default
# ボリュームをクローン
$ virsh vol-clone ubuntu-vm.qcow2 ubuntu-vm-clone.qcow2 --pool default
仮想ネットワーク
Libvirt はネットワーク XML 定義を通じて仮想ネットワーク管理を提供します。デフォルトネットワークは NAT を使用して VM にインターネットアクセスを提供しながら、物理ネットワークから分離します。分離ネットワーク、ルーテッドネットワーク、物理インターフェースへの直接ブリッジも作成できます。
# デフォルトネットワーク構成を表示
$ virsh net-dumpxml default
# 分離ネットワークを作成
$ virsh net-define isolated-net.xml
$ virsh net-start isolated
$ virsh net-autostart isolated
# デフォルトネットワークの DHCP リースを一覧表示
$ virsh net-dhcp-leases default
virsh による VM ライフサイクル操作
Virsh は、作成と起動からマイグレーションと削除まで、仮想マシンのライフサイクルのあらゆる段階にコマンドを提供します。
# virt-install で新しい VM を作成
$ virt-install
--name ubuntu-vm
--ram 4096
--vcpus 2
--disk path=/var/lib/libvirt/images/ubuntu-vm.qcow2,size=20
--network network=default,model=virtio
--os-variant ubuntu22.04
--cdrom /path/to/ubuntu.iso
--noautoconsole
# すべてのドメインを一覧表示
$ virsh list --all
# 起動、一時停止、再開、シャットダウン、強制停止
$ virsh start ubuntu-vm
$ virsh suspend ubuntu-vm
$ virsh resume ubuntu-vm
$ virsh shutdown ubuntu-vm
$ virsh destroy ubuntu-vm
# スナップショットの作成と管理
$ virsh snapshot-create-as ubuntu-vm --name "before-upgrade"
$ virsh snapshot-list ubuntu-vm
$ virsh snapshot-revert ubuntu-vm before-upgrade
$ virsh snapshot-delete ubuntu-vm before-upgrade
# ドメインの定義解除(削除)
$ virsh undefine ubuntu-vm --remove-all-storage
重要ポイント
- Libvirt は QEMU/KVM 上に統一管理レイヤーを提供し、libvirtd デーモンが安定した API を通じて VM ライフサイクル、ストレージ、ネットワーキングを処理します。
- 仮想マシン(ドメイン)は宣言的に XML で定義され、構成はポータブルで再現可能で、バージョン管理に適しています。
- ストレージプールは基盤となるストレージバックエンド(ディレクトリ、LVM、NFS)を抽象化し、ボリュームは独立して作成、クローン、管理できる個々のディスクイメージを表します。
- 仮想ネットワークは NAT、分離、ルーテッド、ブリッジモードをサポートし、dnsmasq による組み込みの DHCP と DNS を提供します。
- virsh コマンドラインツールは、起動、停止、スナップショット、コンソールアクセス、ドメイン構成編集を含む包括的なライフサイクル管理を提供します。
次のステップ
レッスン57では、LXD システムコンテナについて学びます。lxc コマンドラインツールで管理されるコンテナ内で完全な Linux システムイメージを実行することで、完全な仮想マシンの軽量な代替手段を提供します。