Libvirt (简体中文)

From ArchWiki
Jump to: navigation, search
翻译状态: 本文是英文页面 Libvirt翻译,最后翻译时间:2018-01-02,点击这里可以查看翻译后英文页面的改动。

Tango-preferences-desktop-locale.png本页面需要更新翻译,内容可能已经与英文脱节。要贡献翻译,请访问简体中文翻译组Tango-preferences-desktop-locale.png

附注: 请持续翻译并及时更新。

Libvirt 是一组软件的汇集,提供了管理虚拟机和其它虚拟化功能(如:存储和网络接口等)的便利途径。这些软件包括:一个长期稳定的 C 语言 API、一个守护进程(libvirtd)和一个命令行工具(virsh)。Libvirt 的主要目标是提供一个单一途径以管理多种不同虚拟化方案以及虚拟化主机,包括:KVM/QEMUXenLXCOpenVZVirtualBox 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):

  • 其他受支持的管理程序,包括 LXCVirtualBoxXen。请参见它们各自的安装说明。
    • Libvirt 的 LXC 驱动 并不依赖 lxc 提供的用户空间工具。因此,即便需要使用这个驱动也并不是必须安装该工具。
    • Libvirt 能支持 Xen,但默认未内建支持。需要用 ABS 编辑 libvirtPKGBUILD ,去掉 --without-xen 选项后重新构建(built)libvirt。由于 VirtualBox 尚未正式支持 Xen,所以应当用 --without-vbox 选项替换前述选项。

对于网络连接,安装这些包:

客户端

客户端是用于管理和访问虚拟机的用户界面。

兼容 libvirt 的软件列表见 这里.

配置

对于系统 级别的管理任务(如:全局配置和镜像 位置),libvirt 要求至少要设置授权启动守护进程

注意: 对于用户会话 级别的管理任务,守护进程的安装和设置不是 必须的。授权总是仅限本地,前台程序将启动一个 libvirtd 守护进程的本地实例。

设置授权

来自 libvirt:连接授权

Libvirt 守护进程允许管理员分别为客户端连接的每个网络 socket 选择不同授权机制。这主要是通过 libvirt 守护进程的主配置文件 /etc/libvirt/libvirtd.conf 来实现的。每个 libvirt socket 可以有独立的授权机制配置。目前的可选项有 nonepolkitsasl

由于 libvirt 在安装时将把 polkit 作为依赖一并安装,所以 polkit 通常是 unix_sock_auth 参数的默认值(来源)。但基于文件的权限仍然可用。

使用 polkit

注意: 为使 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)就会被提示输入该用户的口令。

注意: 要求口令的提示由系统中的认证代理给出(参阅:Polkit (简体中文)#身份认证组件)。文本控制台默认的认证代理是 pkttyagent 它可能因工作不正常而导致各种问题。
提示: 如果要配置无口令认证,参阅 Polkit (简体中文)#跳过口令提示

从 libvirt 1.2.16 版开始(提案见:[1]),libvirt 组的成员用户默认可以无口令访问读写模式 socket。最简单的判断方法就是看 libvirt 组是否存在并且用户是否该组成员。如果要把 kvm 组访问读写模式后台 socket 的认证策略改为免认证模式,可创建下面的文件:

/etc/polkit-1/rules.d/50-libvirt.rules
/* Allow users in kvm group to manage the libvirt daemon without authentication(允许 kvm 组的用户管理 libvirt 而无需认证)
*/
polkit.addRule(function(action, subject) {
    if (action.id == "org.libvirt.unix.manage" &&
        subject.isInGroup("kvm")) {
            return polkit.Result.YES;
    }
});

然后添加用户kvm 组并重新登录。kvm 也可以是任何其它存在的组并且用户是该组成员(详阅用户和用户组)。

修改组之后不要忘记重新登录才能生效。

基于文件的权限授权

为了给 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.servicevirtlogd.service这两个服务单元都要启动。可以把 libvirtd.service 设置为启用,这时系统将同时启用 virtlogd.servicevirtlockd.socket 两个服务单元,因此后二者不必再设置为启用

非加密的 TCP/IP sockets

警告: 这种方法常用于在可信网络中快速连接远程虚拟机做协助。这是最不安全 的连接方式,应当仅仅 用于测试或用于安全、私密和可信的网络环境。这时 SASL 没有启用,所以所有的 TCP 通讯都是明文传输。在正式的应用场合应当始终 启用 SASL。

编辑 /etc/libvirt/libvirtd.conf

/etc/libvirt/libvirtd.conf
listen_tls = 0
listen_tcp = 1
auth_tcp="none"

It is also necessary to start the server in listening mode by editing /etc/conf.d/libvirtd:

/etc/conf.d/libvirtd
LIBVIRTD_ARGS="--listen"

用主机名访问虚拟机

在非隔离的、桥接的网络中从宿主机访问客户机,可以通过启用 libvirt 提供的 libvirt NSS 模块实现。

编辑 /etc/nsswitch.conf

/etc/nsswitch.conf
hosts: files libvirt dns myhostname
注意: pingssh 这类命令用于虚拟机主机名可以正常工作,但 hostnslookup 这类命令可能会失败或产生非预期结果,因后者依赖 DNS 。应改用 getent hosts <vm-hostname> 命令。

测试

测试 libvirt 在系统级工作是否正常:

$ virsh -c qemu:///system

测试 libvirt 在用户会话级工作是否正常:

$ virsh -c qemu:///session

管理

绝大部分的 libvirt 管理可以通过三个工具实现:virt-manager(图形界面)、virshguestfish(它是 libguestfsAUR 的一部分)。

virsh

Visrsh 用于管理客户(译注:即虚拟机),在脚本式虚拟化管理环境中工作良好。由于需要通过通讯管道与超级管理程序通讯,绝大部分 virsh 命令需要管理员权限。尽管如此,一些典型的管理操作如虚拟机的创建、运行等则如 VirtualBox 那样也可以以普通用户身份执行。

Virsh 允许带命令行选项执行。如果不带则进入其内置的交互式终端:virsh。交互式终端支持 tab 键命令补全。

从命令行执行:

$ virsh [可选项] <命令> [参数]...

在交互式终端里运行:

virsh # <命令> [参数]...

帮助也是可用的:

$ virsh help [option*] or [group-keyword*]

存储池

存储池是指保存的位置。Libvirt 中的定义相当于其他系统中虚拟磁盘虚拟机镜像的概念。存储池应该是一个目录、一个网络文件系统或一个分区(此处包括 LVM)。存储池可以在活动与不活动之间切换,可以为其分配存储空间。

系统级别,默认被激活的存储池是 /var/lib/libvirt/images/;在用户会话级别,virt-manager 将存储池创建在 $HOME/VirtualMachines 目录。

列出活动和不活动的存储池的命令:

$ 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 存储池而言:
  • 最佳实践是仅把一个卷组分配给一个存储池。
  • 请为存储池选择一个与 LVM 卷组不同的名字。否则当存储池被删除时,该卷组也将被删除。

用 virt-manager 新建存储池

First, connect to a hypervisor (e.g. QEMU/KVM system, or user-session). Then, right-click on a connection and select Details; select the Storage tab, push the + button on the lower-left, and follow the wizard.

存储卷

Once the pool has been created, volumes can be created inside the pool. If building a new domain (virtual machine), this step can be skipped as a volume can be created in the domain creation process.

用 virsh 新建卷

Create volume, list volumes, resize, and delete:

$ 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.

virt-manager 后备存储类型的 bug

On newer versions of virt-manager you can now specify a backing store to use when creating a new disk. This is very useful, in that you can have new domains be based on base images saving you both time and disk space when provisioning new virtual systems. There is a bug (https://bugzilla.redhat.com/show_bug.cgi?id=1235406) in the current version of virt-manager which causes virt-manager to choose the wrong type of the backing image in the case where the backing image is a qcow2 type. In this case, it will errantly pick the backing type as raw. This will cause the new image to be unable to read from the backing store, and effectively remove the utility of having a backing store at all.

There is a workaround for this issue. qemu-img has long been able to do this operation directly. If you wish to have a backing store for your new domain before this bug is fixed, you may use the following command.

$ qemu-img create -f qcow2 -o backing_file=<path to backing image>,backing_fmt=qcow2 <disk name> <disk size>

Then you can use this image as the base for your new domain and it will use the backing store as a COW volume saving you time and disk space.

虚拟机

虚拟机被称作“域”。 If working from the command line, use virsh to list, create, pause, shutdown domains, etc. virt-viewer can be used to view domains started with virsh. Creation of domains is typically done either graphically with virt-manager or with virt-install (a command line program installed as part of the virt-install package).

Creating a new domain typically involves using some installation media, such as an .iso from the storage pool or an optical drive.

Print active and inactive domains:

# virsh list --all
Note: SELinux has a built-in exemption for libvirt that allows volumes in /var/lib/libvirt/images/ to be accessed. If using SELinux and there are issues with the volumes, ensure that volumes are in that directory, or ensure that other storage pools are correctly labeled.

用 virt-install 新建虚拟机

For an extremely detailed domain (virtual machine) setup, it is easier to #用 virt-manager 新建虚拟机. However, basics can easily be done with virt-install and still run quite well. Minimum specifications are --name, --memory, guest storage (--disk, --filesystem, or --nodisks), and an install method (generally an .iso or CD).See virt-install(1) for more details and information about unlisted options.

Arch Linux install (two GiB, qcow2 format volume create; user-networking):

$ 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=raw  \
  --network user            \
  --virt-type kvm

Fedora testing (Xen hypervisor, non-default pool, do not originally view):

$ 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
Tip: Run osinfo-query --fields=name,short-id,version os to get argument for --os-variant; this will help define some specifications for the domain. However, --memory and --disk will need to be entered; one can look within the appropriate /usr/share/libosinfo/db/oses/os.xml if needing these specifications. After installing, it will likely be preferable to install the Spice Guest Tools that include the VirtIO drivers. For a Windows VirtIO network driver there is also virtio-winAUR. These drivers are referenced by a <model type='virtio' /> in the guest's .xml configuration section for the device. A bit more information can also be found on the QEMU article.

Import existing volume:

$ 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

Gracefully attempt to shutdown a domain; force off a domain:

$ virsh shutdown domain
$ virsh destroy  domain

Autostart domain on libvirtd start:

$ virsh autostart domain
$ virsh autostart domain --disable

Shutdown domain on host shutdown:

Running domains can be automatically suspended/shutdown at host shutdown using the libvirt-guests.service systemd service. This same service will resume/startup the suspended/shutdown domain automatically at host startup. Read /etc/conf.d/libvirt-guests for service options.

Edit a domain's XML configuration:

$ virsh edit domain
Note: Virtual Machines started directly by QEMU are not managable by libvirt tools.

网络

这里是有关 libvirt 网络的一个正宗的概述。

默认情况下,当 libvirtd 服务启动后,即创建了一个名为 default 的 NAT 网桥与外部网络联通(仅 IPv4)。对于其他的网络连接需求,可创建下列四种类型的网络以连接到虚拟机:

  • bridge — 这是一个虚拟设备,它通过一个物理接口直接共享数据。使用场景为:宿主机有 静态 网络、虚拟机不需与其它虚拟机连接、虚拟机要占用全部进出流量,并且虚拟机运行于 系统 层级。有关如何在现有默认网桥时增加另一个网桥的方法,请参阅 网桥。网桥创建后,需要将它指定到相应客户机的 .xml 配置文件中。
  • network — 这是一个虚拟网络,它可以与其它虚拟机共用。使用场景为:宿主机有 动态 网络(例如:NetworkManager)或使用无线网络。
  • macvtap — 直接连接到宿主机的一个物理网络接口。
  • user — 本地网络,仅用于用户 会话

绝大多数用户都可以通过 virsh 的各种可选项创建具有各种功能的网络,一般来说比通过 GUI 程序(像 virt-manager 之类)更容易做到。也可以按 #用 virt-install 新建虚拟机 所述实现。

注意: libvirt 通过 dnsmasq 处理 DHCP 和 DNS 请求,以启动每个虚拟网络的不同实例。也会为特定的路由添加 iptables 规则并启用 ip_forward 内核参数。This also means that having dnsmasq running on the host system is not necessary to support libvirt requirements (and could interfere with libvirt dnsmasq instances).

IPv6

When adding an IPv6 address through any of the configuration tools, you will likely receive the following error:

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

Fix this by creating the following file (replace eth0 with the name of your physical interface). Reboot your machine afterwards.

/etc/sysctl.d/libvirt-bridge.conf
net.ipv6.conf.eth0.accept_ra = 2

快照

Snapshots take the disk, memory, and device state of a domain at a point-of-time, and save it for future use. They have many uses, from saving a "clean" copy of an OS image to saving a domain's state before a potentially destructive operation. Snapshots are identified with a unique name.

Snapshots are saved within the volume itself and the volume must be the format: qcow2 or raw. Snapshots use deltas so they have the potentiality to not take much space.

创建快照

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 they copy the original image with cp --sparse=true or rsync -S and then merge the 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.

其他管理操作

Connect to non-default hypervisor:

$ virsh --connect xen:///
virsh # uri
xen:///

Connect to the QEMU hypervisor over SSH; and the same with logging:

$ virsh --connect qemu+ssh://username@host/system
$ LIBVIRT_DEBUG=1 virsh --connect qemu+ssh://username@host/system

Connect a graphic console over SSH:

$ virt-viewer  --connect qemu+ssh://username@host/system domain
$ virt-manager --connect qemu+ssh://username@host/system domain
Note: If you are having problems connecting to a remote RHEL server (or anything other than Arch, really), try the two workarounds mentioned in FS#30748 and FS#22068.

Connect to the VirtualBox hypervisor (VirtualBox support in libvirt is not stable yet and may cause libvirtd to crash):

$ virsh --connect vbox:///system

Network configurations:

$ virsh -c qemu:///system net-list --all
$ virsh -c qemu:///system net-dumpxml default

Python 连接代码

The libvirt-python package provides a python2 API in /usr/lib/python2.7/site-packages/libvirt.py.

General examples are given in /usr/share/doc/libvirt-python-your_libvirt_version/examples/

Unofficial example using qemu and openssh:

#! /usr/bin/env python2
# -*- coding: utf-8 -*-
import socket
import sys
import libvirt
if (__name__ == "__main__"):
   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 " + str(domainID)
           domServ = domConnect
           break

UEFI 支持

Libvirt 可以通过 qemu 和 OVMF 来支持 UEFI 虚拟机。

OVMF - QEMU workaround

  • 安装 ovmf
  • 添加下面的内容到 /etc/libvirt/qemu.conf
/etc/libvirt/qemu.conf
nvram = [
    "/usr/share/ovmf/ovmf_code_x64.bin:/usr/share/ovmf/ovmf_vars_x64.bin"
]

  • 重启 libvirtd

现在你可以创建一个 UEFI 虚拟机了。 你可以通过 virt-manager 来创建。 When you get to the final page of the 'New VM' wizard, do the following:

  • Click 'Customize before install', then select 'Finish'
  • On the 'Overview' screen, Change the 'Firmware' field to select the 'UEFI x86_64' option.
  • Click 'Begin Installation'
  • The boot screen you'll see should use linuxefi commands to boot the installer, and you should be able to run efibootmgr inside that system, to verify that you're running an UEFI OS.

For more information about this, refer to this fedora wiki page.

PulseAudio

The PulseAudio daemon normally runs under your regular user account, and will only accept connections from the same user. This can be a problem if QEMU is being run as root through libvirt. To run QEMU as a regular user, edit /etc/libvirt/qemu.conf and set the user option to your username.

user = "dave"

You will also need to tell QEMU to use the PulseAudio backend and identify the server to connect to. First add the qemu namespace to you domain.

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>

Then add the following section to your domain configuration using virsh edit.

 <qemu:commandline>
   <qemu:env name='QEMU_AUDIO_DRV' value='pa'/>
   <qemu:env name='QEMU_PA_SERVER' value='/run/user/1000/pulse/native'/>
 </qemu:commandline>

1000 is your user id. Change it if necessary.

修正 KVM 组权限

If you are getting the error

 Unable to complete install: 'unsupported configuration: CPU mode 'custom' for x86_64 kvm domain on x86_64 host is not supported by hypervisor'

Then simply edit /etc/libvirt/qemu.conf and change group="78" to group="kvm". Then restart libvirtd.service. See this forum post for more information.


参阅