libvirt
Libvirt 是一组软件的汇集,提供了管理虚拟机和其它虚拟化功能(如:存储和网络接口等)的便利途径。这些软件包括:一个长期稳定的 C 语言 API、一个守护进程(libvirtd)和一个命令行工具(virsh)。Libvirt 的主要目标是提供一个单一途径以管理多种不同虚拟化方案以及虚拟化主机,包括:KVM/QEMU,Xen,LXC,OpenVZ 或 VirtualBox hypervisors (详见这里)。
Libvirt 的一些主要功能如下:
- VM management(虚拟机管理):各种虚拟机生命周期的操作,如:启动、停止、暂停、保存、恢复和迁移等;多种不同类型设备的热插拔操作,包括磁盘、网络接口、内存、CPU等。
- Remote machine support(支持远程连接):Libvirt 的所有功能都可以在运行着 libvirt 守护进程的机器上执行,包括远程机器。可以使用最简便且无需额外配置的 SSH 协议,也可以使用受支持的多种网络连接方式。
- Storage management(存储管理):任何运行 libvirt 守护进程的主机都可以用于管理多种类型的存储:创建多种类型的文件镜像(qcow2,vmdk,raw,...),挂载 NFS 共享,枚举现有 LVM 卷组,创建新的 LVM 卷组和逻辑卷,对裸磁盘设备分区,挂载 iSCSI 共享,以及更多......
- Network interface management(网络接口管理):任何运行 libvirt 守护进程的主机都可以用于管理物理的和逻辑的网络接口,枚举现有接口,配置(和创建)接口、桥接、VLAN、端口绑定。
- Virtual NAT and Route based networking(虚拟 NAT 和基于路由的网络):任何运行 libvirt 守护进程的主机都可以管理和创建虚拟网络。Libvirt 虚拟网络使用防火墙规则实现一个路由器,为虚拟机提供到主机网络的透明访问。
安装[编辑 | 编辑源代码]
基于守护进程/客户端的架构的 libvirt 只需要安装在需要要实现虚拟化的机器上。注意,服务器和客户端可以是相同的物理机器。
服务端[编辑 | 编辑源代码]
安装 libvirt包 以及至少一个虚拟运行环境(hypervisor):
- libvirt 的 KVM/QEMU 驱动 是 libvirt 的首选驱动,如果 KVM 功能已 启用,则支持全虚拟化和硬件加速的客户机。详见 QEMU。
- 其他受支持的虚拟运行环境包括 LXC、VirtualBox 和 Xen。请参见它们各自的安装说明。有关
libvirtd
的安装备注:
对于网络连接,需要安装这些包:
- iptables-nft包 和 dnsmasq包 用于 默认的 NAT/DHCP 网络
- openbsd-netcat包 用于 SSH 远程管理
Other optional dependencies may provide desired or extended features, such as dmidecode包 for DMI system info support. Install the ones you may need as dependencies after reading pacman's output for libvirt包.
libvirt
5.1.0 and firewalld 0.7.0 you no longer need to change the firewall backend to iptables. libvirt
now installs a zone called 'libvirt' in firewalld and manages its required network rules there. See Firewall and network filtering in libvirt.客户端[编辑 | 编辑源代码]
客户端是用于管理和访问虚拟机的用户界面。
- virsh — 用于管理和配置域(虚拟机)的命令行程序。
- GNOME Boxes — 简单的 GNOME 3 程序,可以访问远程虚拟系统。是 gnome-extra包组的一部分。
- Libvirt Sandbox — 应用程序沙箱工具包。
- Virt Viewer — 简单的远程显示客户端。
- Qt VirtManager — 管理虚拟机的Qt程序。
- Virt-manager — 用于图形化使用 libvirt 管理 KVM,Xen 或是 LXC。
- Cockpit — 基于网页的系统管理工具,可通过插件管理虚拟机。
兼容 libvirt 的软件列表见 这里.
配置[编辑 | 编辑源代码]
对于系统 级别的管理任务(如:全局配置和镜像卷 位置),libvirt 要求至少要设置授权和启动守护进程。
设置授权[编辑 | 编辑源代码]
来自 libvirt:连接授权:
- Libvirt 守护进程允许管理员分别为客户端连接的每个网络 socket 选择不同授权机制。这主要是通过 libvirt 守护进程的主配置文件
/etc/libvirt/libvirtd.conf
来实现的。每个 libvirt socket 可以有独立的授权机制配置。目前的可选项有none
、polkit
和sasl
。
Using libvirt group[编辑 | 编辑源代码]
The easiest way to ensure your user has access to libvirt daemon is to add member to libvirt
user group.
Members of the libvirt
group have passwordless access to the RW daemon socket by default.
使用 polkit[编辑 | 编辑源代码]
Because libvirt包 pulls polkit包 as a dependency during installation, polkit is used as the default value for the unix_sock_auth
parameter (source). File-based permissions remain nevertheless available.
polkit
认证工作正常,应该重启一次系统。libvirt 守护进程在 polkit 策略配置文件(/usr/share/polkit-1/actions/org.libvirt.unix.policy
)中提供了两种 polkit 操作:
org.libvirt.unix.manage
面向完全的管理访问(读写模式后台 socket),以及org.libvirt.unix.monitor
面向仅监视察看访问(只读 socket)。
默认的面向读写模式后台 socket 的策略需要认证为管理员。这点类似于 sudo 认证,但它并不要求客户应用最终以 root 身份运行。默认策略下也仍然允许任何应用连接到只读 socket。
Arch Linux 默认 wheel
组的所有用户都是管理员身份:定义于 /etc/polkit-1/rules.d/50-default.rules
(参阅:Polkit#管理员身份认证)。所以如果用户是 wheel
组的成员,就不必新建组和规则文件:只要连接到了读写模式 socket(例如通过 virt-manager包)就会被提示输入该用户的口令。
pkttyagent
,它可能因工作不正常而导致各种问题。你可能想要修改授权以读写模式访问 socket 的组。例如,你想授权 mykvm
组,可创建下面的文件:
/etc/polkit-1/rules.d/50-libvirt.rules
/* Allow users in mykvm group to manage the libvirt daemon without authentication */ polkit.addRule(function(action, subject) { if (action.id == "org.libvirt.unix.manage" && subject.isInGroup("mykvm")) { return polkit.Result.YES; } });
然后添加自己到 mykvm
组并重新登录。可以将 mykvm 替换为你想要的任意组,只需确保该组存在,且用户是该组的成员(详情可参考用户和用户组)。
修改组之后不要忘记重新登录才能生效。
基于文件的权限授权[编辑 | 编辑源代码]
为了给 libvirt 组用户定义基于文件的权限以管理虚拟机,取消下列行的注释:
/etc/libvirt/libvirtd.conf
#unix_sock_group = "libvirt" #unix_sock_ro_perms = "0777" # set to 0770 to deny non-group libvirt users #unix_sock_rw_perms = "0770" #auth_unix_ro = "none" #auth_unix_rw = "none"
有些资料提到可以通过改变某些特定 libvirt 目录的权限以简化管理。需要记住的是:包更新时,这些变更会丢失。如要修改这些系统目录的权限,需要 root 用户权限。
守护进程[编辑 | 编辑源代码]
libvirtd.service
和 virtlogd.service
这两个服务单元都要启动。可以把 libvirtd.service
设置为启用,这时系统将同时启用 virtlogd.service
和 virtlockd.socket
两个服务单元,因此后二者不必再设置为启用。
非加密的 TCP/IP sockets[编辑 | 编辑源代码]
编辑 /etc/libvirt/libvirtd.conf
:
/etc/libvirt/libvirtd.conf
listen_tls = 0 listen_tcp = 1 auth_tcp="none"
同时需要编辑 /etc/conf.d/libvirtd
以在监听模式下启动服务:
/etc/conf.d/libvirtd
LIBVIRTD_ARGS="--listen"
用主机名访问虚拟机[编辑 | 编辑源代码]
在非隔离的、桥接的网络中从宿主机访问客户机,可以通过启用 libvirt包 提供的 libvirt
和/或 libvirt_guest
NSS 模块来实现。For the comparison of the two modules and technical details, see libvirt documentation.
在 nsswitch.conf(5) 中添加需要的模块:
/etc/nsswitch.conf
hosts: files libvirt libvirt_guest dns myhostname
ping
和 ssh
这类命令使用虚拟机主机名可以正常工作,但 host
和 nslookup
这类命令可能会失败或产生非预期结果,因后者依赖 DNS 。应改用 getent hosts <vm-hostname>
命令。测试[编辑 | 编辑源代码]
测试 libvirt 在系统级工作是否正常:
$ virsh -c qemu:///system
测试 libvirt 在用户会话级工作是否正常:
$ virsh -c qemu:///session
管理[编辑 | 编辑源代码]
绝大部分的 libvirt 管理可以通过三个工具实现:virt-manager包(图形界面)、virsh
和 guestfish
(它是 libguestfs包 的一部分)。
virsh[编辑 | 编辑源代码]
Visrsh 用于管理客户域(虚拟机),适用于脚本及虚拟环境管理工作。受限于与虚拟化环境通信的通道,绝大部分 virsh 命令需要管理员权限。尽管如此,一些典型的管理操作如域的创建、运行等也可以像 VirtualBox 那样以普通用户身份执行。
Virsh 允许带命令行选项执行。如果不带则进入其内置的交互式终端:virsh
。交互式终端支持 tab 键命令补全。
从命令行执行:
$ virsh [可选项] <命令> [参数]...
在交互式终端里运行:
virsh # <命令> [参数]...
帮助也是可用的:
$ virsh help [option*] or [group-keyword*]
存储池[编辑 | 编辑源代码]
存储池是指保存卷的位置。Libvirt 中卷的定义相当于其他系统中虚拟磁盘或虚拟机镜像的概念。存储池应该是一个目录、一个网络文件系统或一个分区(这也包括 LVM)。存储池可以在活动与不活动之间切换,可以为其分配存储空间。
在系统级别,默认被激活的存储池是 /var/lib/libvirt/images/
;在用户会话级别,virt-manager
将存储池创建在 $XDG_DATA_HOME/images
目录。
列出活动和不活动的存储池的命令:
$ virsh pool-list --all
用 virsh 新建存储池[编辑 | 编辑源代码]
以下示例为添加存储池、目录和 LVM 卷的方法:
$ virsh pool-define-as name type [source-host] [source-path] [source-dev] [source-name] [<target>] [--source-format format] $ virsh pool-define-as poolname dir - - - - /home/username/.local/libvirt/images $ virsh pool-define-as poolname fs - - /dev/vg0/images - mntpoint
上述示例仅仅定义了存储池的信息,下面创建它:
$ virsh pool-build poolname $ virsh pool-start poolname $ virsh pool-autostart poolname
删除它的命令:
$ virsh pool-undefine poolname
- 最佳实践是仅把一个卷组分配给一个存储池。
- 请为存储池选择一个与 LVM 卷组不同的名字。否则当存储池被删除时,该卷组也将被删除。
用 virt-manager 新建存储池[编辑 | 编辑源代码]
首先,连接到虚拟运行环境(例如 QEMU/KVM 的系统/用户会话)。然后,右键点击一个连接,选择详情;切换到存储选项卡,点击左下角的+,按照向导操作。
存储卷[编辑 | 编辑源代码]
存储池被创建之后,就可以在存储池中创建存储卷。如果你想新建一个域(虚拟机),那么这一步可以跳过,因为这一步可以在创建域的过程中完成。
用 virsh 新建卷[编辑 | 编辑源代码]
新建卷,列出卷,变更卷大小,删除卷:
$ virsh vol-create-as poolname volumename 10GiB --format aw|bochs|raw|qcow|qcow2|vmdk $ virsh vol-upload --pool poolname volumename volumepath $ virsh vol-list poolname $ virsh vol-resize --pool poolname volumename 12GiB $ virsh vol-delete --pool poolname volumename $ virsh vol-dumpxml --pool poolname volumename # for details.
域[编辑 | 编辑源代码]
虚拟机被称作“域”。如果你想在命令行下操作,使用 virsh
列出,创建,暂停,关闭……域。virt-viewer
可以用来查看使用 virsh
启动的域。域的创建通常以图形化的 virt-manager
或者命令行下的 virt-install
(一个命令行工具,是 virt-install包 包的一部分)完成。
创建新域通常需要安装媒介,例如存储池中的 .iso
文件或是直接从光驱安装。
列出活动的和不活动的域:
# virsh list --all
/var/lib/libvirt/images/
中的卷可以被访问。如果你使用 SELinux 并且在卷方面有问题,确保卷位于该目录,或是其它存储池的标记正常。用 virt-install 新建域[编辑 | 编辑源代码]
对于很详细的域(虚拟机)配置,可以#用 virt-manager 新建域更简单地完成。但是,基础配置同样可以用 virt-install
完成并且同样顺利运行。最小配置包括 --name
,--memory
,存储(--disk
,--filesystem
或 --nodisks
)和安装介质(通常来说是 .iso
文件或 CD)。查看 virt-install(1) 得到未列出的选项和更多的详情。
安装 Arch Linux(创建了 2 GiB qcow2 格式卷;用户网络):
$ virt-install \ --name arch-linux_testing \ --memory 1024 \ --vcpus=2,maxvcpus=4 \ --cpu host \ --cdrom $HOME/Downloads/arch-linux_install.iso \ --disk size=2,format=qcow2 \ --network user \ --virt-type kvm
Fedora testing (Xen, 非默认池,无默认控制台):
$ virt-install \ --connect xen:/// \ --name fedora-testing \ --memory 2048 \ --vcpus=2 \ --cpu=host \ --cdrom /tmp/fedora20_x84-64.iso \ --os-type=linux --os-variant=fedora20 \ --disk pool=testing,size=4 \ --network bridge=br0 \ --graphics=vnc \ --noautoconsole $ virt-viewer --connect xen:/// fedora-testing
Windows:
$ virt-install \ --name=windows7 \ --memory 2048 \ --cdrom /dev/sr0 \ --os-variant=win7 \ --disk /mnt/storage/domains/windows7.qcow2,size=20GiB \ --network network=vm-net \ --graphics spice
osinfo-query --fields=name,short-id,version os
来获得 --os-variant
的参数,这可以帮助定制域的一些规格。然而 --memory
和 --disk
是必须被输入的。如果需要查看这些规格,可以看看 /usr/share/libosinfo/db/oses/os.xml
(译注:此处可能已过时)。在安装后,推荐安装 Spice Guest Tools,其中包括 VirtIO 驱动。Windows 的 VirtIO 网络驱动可通过 virtio-winAUR 获得。要使用 VirtIO,需要在虚拟机 .xml
配置中使用 <model type='virtio' />
。更多的信息可以参考 QEMU 页面.导入现有的卷:
$ virt-install \ --name demo \ --memory 512 \ --disk /home/user/VMs/mydisk.img \ --import
用 virt-manager 新建域[编辑 | 编辑源代码]
首先,连接到虚拟运行环境(例如 QEMU/KVM system 或用户 session,在连接上右击并选择 新建,然后跟随向导完成。
- 在第四步中取消选中立即分配全部虚拟磁盘空间会加快创建过程并节省实际虚拟磁盘空间占用;然而,这将导致将来花费额外的磁盘整理时间。
- 在第五步中打开高级选项并确认虚拟化类型设为 kvm(这通常是首选模式)。如果要求附加的硬件配置,选中安装前定制选项。
管理域[编辑 | 编辑源代码]
启动域:
$ virsh start domain $ virt-viewer --connect qemu:///session domain
正常关闭域;强制关闭域:
$ virsh shutdown domain $ virsh destroy domain
在 libvirtd 启动时自动启动域:
$ virsh autostart domain $ virsh autostart domain --disable
在宿主机关闭时自动关闭域:
- 通过使用
libvirt-guests.service
Systemd 服务,运行中的域可以在宿主机关闭时自动挂起/关闭。同时这个服务还可以让挂起/休眠的域在宿主机启动的时候自动恢复。可查看 libvirt-guests(8) 了解相关选项。
编辑一个域的 XML 配置:
$ virsh edit domain
参考 libvirt 维基的 XML 格式一节了解关于 XML 配置文件的信息。
网络[编辑 | 编辑源代码]
这里是有关 libvirt 网络的的概述。
可将以下四种网络连接到域:
- bridge — 这是一个虚拟设备,它通过一个物理接口直接共享数据。使用场景为:宿主机有 静态 网络、不需与其它域连接、要占用全部进出流量,并且域运行于 系统 层级。网桥必须要在 libvirt 外配置,详细操作可参考网桥。网桥创建后,需要将它指定到相应客户机的
.xml
配置文件中。 - network — 这是一个虚拟网络,它可以与其它虚拟机共用。Libvirt 提供多种虚拟网络模式,例如 NAT(Network address translation,网络地址转换)模式,路由模式和隔离模式。使用场景为:宿主机有 动态 网络(例如:NetworkManager)或使用无线网络。
- macvtap — 直接连接到宿主机的一个物理网络接口。相较桥接更加简单,代价是宿主机无法通过该接口与域通信。Libvirt 可以很方便地配置该类网络。
- user — 本地网络,仅用于用户 会话。
绝大多数用户都可以通过 virsh
的各种可选项创建具有各种功能的网络,一般来说通过 GUI 程序(像 virt-manager
之类)更方便,也可以按 #用 virt-install 新建域 所述实现。
- libvirt 通过 dnsmasq包 处理 DHCP 和 DNS 请求,为每个虚拟网络创建一个实例。它也会为特定的路由添加 iptables 规则并启用
ip_forward
内核参数。这也意味着宿主机上无需预先运行 dnsmasq(并可能干扰到 libvirt 的 dnsmasq 实例)。 - 如果无法启动默认网络,请确保已安装 iptables-nft包 和 dnsmasq包。
通过以下命令获取虚拟机的 IP(假设它连接到 default
网络并通过 DHCP 获取 IP):
$ virsh net-dhcp-leases default
如果 VM 上运行有 qemu-guest-agent
:
$ virsh domifaddr --source agent $vm
将 $vm
替换为实际的虚拟机名称(或域 ID)。
管理并修改网络[编辑 | 编辑源代码]
修改网络前建议先阅读 libvirt 维基的用于虚拟网络的基本命令行用法一节。另外也建议通过 libvirt 网络维基了解用法。
IPv6[编辑 | 编辑源代码]
当通过任何配置工具试图添加 IPv6 地址时,你可能会遇到这样的错误:
Check the host setup: enabling IPv6 forwarding with RA routes without accept_ra set to 2 is likely to cause routes loss. Interfaces to look at: eth0
要修复这个问题,运行如下命令(将 eth0
改为你的物理接口的名称),并重新启动系统。
# sysctl net.ipv6.conf.eth0.accept_ra=2
Macvtap[编辑 | 编辑源代码]
要创建 macvtap 网络,先创建该文件:
macvtap.xml
<network> <name>macvtap-net</name> <forward mode='bridge'> <interface dev='eth0'/> </forward> </network>
然后定义并启用网络:
$ virsh net-define macvtap.xml $ virsh net-autostart macvtap-net $ virsh net-start macvtap-net
现在已创建好 macvtap-net
网络并已持久化,它通过 eth0
桥接到外部网络。
快照[编辑 | 编辑源代码]
快照保存某一时刻域的磁盘、内存和设备状态以供将来使用。快照有很多用处,例如在进行可能的破坏性操作时保存一份干净的域状态。快照使用唯一名称进行标识。
快照保存在卷之中,卷必须为 qcow2 或 raw 格式。快照使用增量存储,所以并不会占用很多空间。
创建快照[编辑 | 编辑源代码]
Once a snapshot is taken it is saved as a new block device and the original snapshot is taken offline. Snapshots can be chosen from and also merged into another (even without shutting down the domain).
Print a running domain's volumes (running domains can be printed with virsh list
):
# virsh domblklist domain
Target Source ------------------------------------------------ vda /vms/domain.img
To see a volume's physical properties:
# qemu-img info /vms/domain.img
image: /vms/domain.img file format: qcow2 virtual size: 50G (53687091200 bytes) disk size: 2.1G cluster_size: 65536
Create a disk-only snapshot (the option --atomic
will prevent the volume from being modified if snapshot creation fails):
# virsh snapshot-create-as domain snapshot1 --disk-only --atomic
List snapshots:
# virsh snapshot-list domain
Name Creation Time State ------------------------------------------------------------ snapshot1 2012-10-21 17:12:57 -0700 disk-snapshot
One can then copy the original image with cp --sparse=true
or rsync -S
and then merge the original back into snapshot:
# virsh blockpull --domain domain --path /vms/domain.snapshot1
domain.snapshot1
becomes a new volume. After this is done the original volume (domain.img
and snapshot metadata can be deleted. The virsh blockcommit
would work opposite to blockpull
but it seems to be currently under development (including snapshot-revert feature
, scheduled to be released sometime next year.
其它管理操作[编辑 | 编辑源代码]
连接到非默认的虚拟运行环境:
$ virsh --connect xen:/// virsh # uri xen:///
通过 SSH 连接到 QEMU 虚拟运行环境,并且以相同方式登录:
$ virsh --connect qemu+ssh://username@host/system $ LIBVIRT_DEBUG=1 virsh --connect qemu+ssh://username@host/system
通过 SSH 连接到一个图形控制台:
$ virt-viewer --connect qemu+ssh://username@host/system domain $ virt-manager --connect qemu+ssh://username@host/system domain
连接到 VirtualBox(libvirt 对 VirtualBox 的支持尚不稳定,可能会导致 libvirtd 崩溃):
$ virsh --connect vbox:///system
网络配置:
$ virsh -c qemu:///system net-list --all $ virsh -c qemu:///system net-dumpxml default
Hooks[编辑 | 编辑源代码]
Hooks are scripts that are triggered by different events happening while starting and running the libvirt daemon. They can be used to execute commands needed in preparation to launch a guest like setup networks or reserve memory.
The following hooks exists:
- daemon - occasions to trigger: start, shutdown, reload
- qemu - occasions to trigger: prepare, prepare, start, started, stopped, release, migrate, restore, reconnect, attach
- lxc - occasions to trigger: prepare, start, started, stopped, release, reconnect
- libxl - occasions to trigger: prepare, start, started, stopped, release migrate, reconnect
- network - occasions to trigger: start, started, stopped, port-created, updated, port-deleted
See the libvirt Documentation for details about each hook and trigger.
Create a hook[编辑 | 编辑源代码]
Hooks are represented by scripts located at /etc/libvirt/hooks
. If the folder does not exist, you have to create it.
Each hook is represented by a script in this folder with the same name (e.g. /etc/libvirt/hooks/qemu
) or a subfolder (e.g. /etc/libvirt/hooks/qemu.d/
). The later can contain different scripts, which are all run at the trigger points. The scripts are run like any other scripts, so they need to start whith the declaration of the command interpreter to use (e.g. #!/bin/bash
).
The script have to be executable by the libvirt user (chown +x /etc/libvirt/hooks/qemu
).
Everytime a trigger point is met, the script is run. For example, the daemon script would run at least two times in a start/stop cycle of the system, at start and at shutdown. To run an command only at a given point, you have to implement conditions in the script. To do this, libvirt passes parameters which can be used to identify the current trigger condition.
According to the libvirt documentation these parameters are defined as follows:
- Parameter 1: The name of the object involved in the operation
- Parameter 2: The name of the operation being performed
- Parameter 3: Used if a sub-operation is to be named
- Parameter 4: An extra argument if needed
If one of the arguments is not applicable, a dash is passed.
示例[编辑 | 编辑源代码]
To run an command everytime you start an qemu guest, before any ressources are allocated, you can use the qemu hook. At this point, libvirt runs the hooks like this: /etc/libvirt/hooks/qemu <guest_name> prepare begin -
The script for this could like this:
/etc/libvirt/hooks/qemu
#!/bin/bash guest_name="$1" libvirt_task="$2" if [ "$libvirt_task" = "prepare" ]; then <run some important code here> fi
If the guest is stopped, the same script would be run, but this time the daemon would start the command like this: /etc/libvirt/hooks/qemu <guest_name> stopped end -
宿主机与虚拟机间共享数据[编辑 | 编辑源代码]
Virtio-FS[编辑 | 编辑源代码]
The description here will use hugepages to enable the usage of shared folders. Sharing files with Virtio-FS lists an overview of the supported options to enable filesharing with the guest.
First you need to enable hugepages which are used by the virtual machine:
/etc/sysctl.d/40-hugepage.conf
vm.nr_hugepages = nr_hugepages
To determine the number of hugepages needed check the size of the hugepages:
$ grep Hugepagesize /proc/meminfo
The number of hugepages is memory size of virtual machine / Hugepagesize. Add to this value some additional pages. You have to reboot after this step, so that the hugepages are allocated.
Now you have to prepare the configuration of the virtual machine:
# virsh edit name_of_virtual_machine
<domain> ... <memoryBacking> <hugepages/> </memoryBacking> ... <cpu ...> <numa> <cell memory='memory size of virtual machine' unit='KiB' memAccess='shared'/> </numa> </cpu> ... <devices> ... <filesystem type='mount' accessmode='passthrough'> <driver type='virtiofs'/> <source dir='path to source folder on host'/> <target dir='mount_tag'/> </filesystem> ... </devices> </domain>
It is necessary to add the NUMA definition so that the memory access can be declared as shared. id and cpus values for NUMA will be inserted by virsh.
It should now be possible to mount the folder in the shared machine:
# mount -t virtiofs mount_tag /mnt/mount/path
Add the following fstab entry to mount the folder automatically at boot:
/etc/fstab
... mount_tag /mnt/mount/path virtiofs rw,noatime,_netdev 0 0
9p[编辑 | 编辑源代码]
File system directories can be shared using the 9P protocol. Details are available in QEMU's documentation of 9psetup.
Configure the virtual machine as follows:
<domain> ... <devices> ... <filesystem type="mount" accessmode="mapped"> <target dir="mount_tag"/> </filesystem> </devices> </domain>
Boot the guest and mount the shared directory from it using:
# mount -t 9p -o trans=virtio,version=9p2000.L mount_tag /path/to/mount_point/on/guest
See https://docs.kernel.org/filesystems/9p.html for more mount options.
To mount it at boot, add it to the guest's fstab:
/etc/fstab
... mount_tag /path/to/mount_point/on/guest 9p trans=virtio,version=9p2000.L 0 0
The module for the 9p transport (i.e. 9pnet_virtio
for trans=virtio
) will not be automatically loaded, so mounting the file system from /etc/fstab
will fail and you will encounter an error like 9pnet: Could not find request transport: virtio
. The solution is to preload the module during boot:
/etc/modules-load.d/9pnet_virtio.conf
9pnet_virtio
Samba / SMB[编辑 | 编辑源代码]
An other easy way to share data between guest and host is to use the smb protocol. While performance and latency may not be as good as in the other described ways, its sufficient for simple tasks like transfering simple files like images or documents from and to the guest.
The smb server can be set up directly on either the host, or the guest, for example using Samba, eliminating the need for a dedicated file server. Windows guests have the ability to create smb shares included right after installation (Microsoft Supportpage).
One possible way to access the share under linux (either from the host, or from the guest, depending, where you have installed your server) is to create an entry in your fstab. The samba包 package is required.
/etc/fstab
#Accessing a samba share on my vm from the host //my_vm/my_share /home/archuser/my_vm cifs _netdev,noauto,nofail,user,credentials=/home/archuser/.config/my_vm.key,gid=1000,uid=984 0 0
_netdev,noauto,nofail
ensures that the share is only mounted when needed without causing issues if the vm is not booted. user,credentials=/home/user/.config/my_vm.key,gid=1000,uid=984
gives you the ability to mount the share on the fly while first accessing it, without needing a password.
UEFI 支持[编辑 | 编辑源代码]
Libvirt 可以通过 QEMU 和 OVMF 来支持 UEFI 虚拟机。
安装 edk2-ovmf包。
重启 libvirtd
。
你现在就可以创建 UEFI 虚拟机了。通过 virt-manager包 创建一台虚拟机,在到达新建虚拟机向导的最后一页时,进行如下操作:
- 勾选在安装前自定义配置,之后点击完成。
- 在概况屏幕, 将固件改为:
- UEFI x86_64: /usr/share/edk2/x64/OVMF_CODE.4m.fd:无安全启动支持的 x64 UEFI,
- UEFI x86_64: /usr/share/edk2/x64/OVMF_CODE.secboot.4m.fd:带安全启动支持的 x64 UEFI(无预置证书)。
- 点击应用。
- 点击开始安装
参考 Fedora:Using UEFI with QEMU 获得更多信息。
小技巧[编辑 | 编辑源代码]
Python 连接代码[编辑 | 编辑源代码]
libvirt-python包 在 /usr/lib/python3.x/site-packages/libvirt.py
提供了一个 Python API。
常用例子在 /usr/share/doc/libvirt-python-your_libvirt_version/examples/
给出。
一个使用 qemu-desktop包 和 openssh包 的例子(非官方):
#! /usr/bin/env python3 import socket import sys import libvirt conn = libvirt.open("qemu+ssh://xxx/system") print("Trying to find node on xxx") domains = conn.listDomainsID() for domainID in domains: domConnect = conn.lookupByID(domainID) if domConnect.name() == 'xxx-node': print("Found shared node on xxx with ID {}".format(domainID)) domServ = domConnect break
先进格式化 4K 原生硬盘[编辑 | 编辑源代码]
To turn a disk into an Advanced Format 4Kn disk, both its physical and logical sector size needs to be set to 4 KiB. For virtio-blk and virtio-scsi this can be done by setting the logical_block_size
and physical_block_size
options with the <blockio> element. For example:
# virsh edit name_of_virtual_machine
<domain> ... <devices> ... <disk type='file' device='disk'> .. <blockio logical_block_size='4096' physical_block_size='4096'/> </disk> ... </devices> </domain>
控制 QEMU[编辑 | 编辑源代码]
Libvirt is capable of passing on QEMU command line arguments to the underlying QEMU instance running the VM. This functionality is highly useful when libvirt does not provide QEMU features (yet). For examples, see the entire Intel GVT-g article.
modify VM XML schema for QEMU[编辑 | 编辑源代码]
This serves to enable QEMU-specific elements. Change
$ virsh edit vmname
<domain type='kvm'>
to
$ virsh edit vmname
<domain xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0' type='kvm'>
QEMU 命令行参数[编辑 | 编辑源代码]
In libvirt, QEMU command line arguments separated by whitespaces need to be provided separately.
The correct location to insert them is at the end of the <domain>
element, i. e. right above the closing </domain>
tag.
-display gtk,gl=es,zoom-to-fit=off
Becomes
$ virsh edit vmname
... </devices> <qemu:commandline> <qemu:arg value="-display"/> <qemu:arg value="gtk,gl=es,zoom-to-fit=off"/> </qemu:commandline> </domain>
排障[编辑 | 编辑源代码]
系统实例下的 PulseAudio[编辑 | 编辑源代码]
PulseAudio 守护进程通常在你的普通用户下运行,并且只接受来自相同用户的连接。然而 libvirt 默认使用 root 运行 QEMU。为了让 QEMU 在普通用户下运行,编辑 /etc/libvirt/qemu.conf
并将 user
设置为你的用户名。
user = "dave"
你同样需要告诉 QEMU 使用 PulseAudio 后端并识别要连接的服务器。使用 virsh edit
将如下内容添加到你的域配置中:
<audio id="1" type="pulseaudio" serverName="/run/user/1000/pulse/native"> <input latency="20000"/> <output latency="20000"/> </audio>
1000
是你的用户 ID,如有必要可修改。
You can omit the latency settings (in microseconds) but using the defaults might result in crackling.
Hypervisor CPU use[编辑 | 编辑源代码]
Default VM configuration generated by virt-manager may cause rather high (10-20%) CPU use caused by the QEMU process. If you plan to run the VM in headless mode, consider removing some of the unnecessary devices.
Virtual machine cannot be un-paused on virt-manager[编辑 | 编辑源代码]
If you are using a disk image format such as qcow2 which has a specified virtual capacity, but only stores what is needed, then you need to have space on the host partition for the image to grow. If you see I/O related errors when attempting to start the VM, it's possible that the host partition holding the virtual disk image is full. You can run df -h
on the host to verify how much free space is available.
If this is the case, see System maintenance#Clean the filesystem for ways to free up space.
Redirect USB Device is greyed out in virt-manager[编辑 | 编辑源代码]
If the Redirect USB Device menu item is greyed out, check that the following hardware is configured for the VM:
- A USB Controller.
- One or more USB Redirectors.
Error starting domain: Requested operation is not valid[编辑 | 编辑源代码]
When you try to open a virtual machine this error may pop up. This is because when you try to open a existing virtual machine libvirt tries to search for the default network which is not available. To make it available you have to autostart your network interface so that whenever your restart your computer your network interface is always active. See libvirt networking page.
Look at the name of your network interface with the following command:
# virsh net-list --all
To autostart your network interface:
# virsh net-autostart name_of_the_network
To start your network interface:
# virsh net-start name_of_the_network
Virt Manager Error 'Virt Manager doesn't have search permissions'[编辑 | 编辑源代码]
Ensure the folder containing your virtual machine files and installation ISO are owned by the libvirt-qemu
group
$ sudo chown -R $USER:libvirt-qemu /path/to/virtual/machine