摘自 《KVM实战:原理、进阶与性能调优》

《KVM实战:原理、进阶与性能调优》
《KVM实战:原理、进阶与性能调优》

目录

1. libvirt

1.1 libvirt 简介

什么是 libvirt

libvirt 是目前使用最为广泛的对 KVM 虚拟机进行管理的工具和 API,主要作为连接底层 Hypervisor上层应用程序的一个中间适配层

libvirt 支持多种 Hypervisor
libvirt 支持多种 Hypervisor
主要模块

libvirt 主要包含三个模块

  • 守护进程libvirtd:接收并处理 API 请求
  • API 库:可基于此 API 开发管理工具,例如virt-manager
  • virsh是经常会使用到的 KVM 命令行管理工具
层次结构
libvirt 的层次结构
libvirt 的层次结构

libvirt 总体上可分为三个层次

  • 公共接口层(Public API Layer)
  • 驱动接口层(Driver API Layer)
  • 驱动实现层(Driver Implementation Layer)
重要概念

另外,在libvirt 中涉及到以下几个重要概念

  • 节点Node:是一个物理机器,上面可能运行着多个虚拟客户机。HypervisorDomain都运行在节点上
  • Hypervisor:也称虚拟机监控器(VMM),如 KVM、Xen、VMWare、Hyper-V 等,是虚拟化中的一个底层软件层,它可以虚拟化一个节点使其运行多个虚拟客户机
  • Domain:是在Hypervisor上运行的一个客户机操作系统实例。域也被称为实例(instance)客户机操作系统(Guest OS)虚拟机(VM),它们都是同一个概念
管理功能

libvirt 的管理功能主要包含以下五个部分

  1. 域的管理:包括对节点上的域的各个生命周期的管理,如启动、停止、暂停、保存、恢复和动态迁移,以及对多种设备类型的热拔插操作
  2. 远程节点的管理:只要物理节点上运行了libvirtd守护进程,远程的管理程序就可以连接到该节点进行管理操作。libvirt 支持多种网络远程传输类型,如 SSHTCP 套接字Unix domain socketTLS 的加密传输等。例如,可通过virsh -c qemu+ssh://root@example.com/system连接到example.com上,从而管理其上的域
  3. 存储的管理:任何运行了libvirtd守护进程的主机,都可以通过 libvirt 来管理不同类型的存储,如创建不同格式的客户机镜像、挂载 NFS、查看现有的 LVM 卷组、创建新的 LVM 卷组和逻辑卷、对磁盘设备分区、挂载 iSCSI 共享存储、使用 Ceph 系统支持的 RBD 远程存储等
  4. 网络的管理:列出现有的网络接口、配置网络接口、创建虚拟网络接口、桥接、VLAN 管理、NAT 网络设置、为客户机分配虚拟网络等
  5. 提供一个稳定、可靠、高效的 API,以便可以完成前面的四个管理功能

1.2 libvirt 的安装与配置

安装 libvirt

CentOS 7.5中,部分 libvirt 相关的包如下所示:

> yum install libvirt

> rpm -qa | grep libvirt
libvirt-daemon-driver-network-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-driver-storage-mpath-4.5.0-10.el7_6.6.x86_64
libvirt-libs-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-config-network-4.5.0-10.el7_6.6.x86_64
libvirt-python-4.5.0-1.el7.x86_64
libvirt-daemon-driver-storage-rbd-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-kvm-4.5.0-10.el7_6.6.x86_64
libvirt-gconfig-1.0.0-1.el7.x86_64
libvirt-bash-completion-4.5.0-10.el7_6.6.x86_64
libvirt-glib-1.0.0-1.el7.x86_64
libvirt-daemon-driver-secret-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-driver-lxc-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-driver-storage-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-driver-nwfilter-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-driver-storage-gluster-4.5.0-10.el7_6.6.x86_64
libvirt-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-driver-storage-iscsi-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-driver-interface-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-config-nwfilter-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-driver-storage-scsi-4.5.0-10.el7_6.6.x86_64
libvirt-devel-4.5.0-10.el7_6.6.x86_64
libvirt-client-4.5.0-10.el7_6.6.x86_64
libvirt-gobject-1.0.0-1.el7.x86_64
libvirt-daemon-driver-nodedev-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-driver-qemu-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-driver-storage-disk-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-driver-storage-core-4.5.0-10.el7_6.6.x86_64
libvirt-daemon-driver-storage-logical-4.5.0-10.el7_6.6.x86_64
libvirt 的配置文件

首先查看libvirtd的使用说明:

> libvirtd --help

Usage:
  libvirtd [options]

Options:
  -h | --help            Display program help:
  -v | --verbose         Verbose messages.
  -d | --daemon          Run as a daemon & write PID file.
  -l | --listen          Listen for TCP/IP connections.
  -t | --timeout <secs>  Exit after timeout period.
  -f | --config <file>   Configuration file.
  -V | --version         Display version information.
  -p | --pid-file <file> Change name of PID file.

libvirt management daemon:

  Default paths:

    Configuration file (unless overridden by -f):
      /etc/libvirt/libvirtd.conf

    Sockets:
      /var/run/libvirt/libvirt-sock
      /var/run/libvirt/libvirt-sock-ro

    TLS:
      CA certificate:     /etc/pki/CA/cacert.pem
      Server certificate: /etc/pki/libvirt/servercert.pem
      Server private key: /etc/pki/libvirt/private/serverkey.pem

    PID file (unless overridden by -p):
      /var/run/libvirtd.pid

CentOS 7.5为例,libvirt 的相关配置文件都在/etc/libvirt/目录中

/etc/libvirt > ls -hl
total 80K
-rw-r--r--  1 root root  450 Mar 14 18:25 libvirt-admin.conf
-rw-r--r--  1 root root  547 Mar 14 18:25 libvirt.conf
-rw-r--r--  1 root root  17K Mar 14 18:25 libvirtd.conf
-rw-r--r--  1 root root 1.2K Mar 14 18:25 lxc.conf
drwx------. 2 root root 4.0K Apr 24 16:29 nwfilter
drwx------. 3 root root   55 May 30 11:18 qemu
-rw-r--r--  1 root root  30K Mar 14 18:25 qemu.conf
-rw-r--r--  1 root root 2.2K Mar 14 18:25 qemu-lockd.conf
drwx------. 2 root root    6 Nov 13  2018 secrets
drwxr-xr-x  3 root root  116 Apr 25 09:22 storage
-rw-r--r--  1 root root 3.2K Mar 14 18:25 virtlockd.conf
-rw-r--r--  1 root root 3.2K Mar 14 18:25 virtlogd.conf

/etc/libvirt > cd qemu

/etc/libvirt/qemu > ls -hl
total 16K
drwx------. 3 root root   42 Apr 25 10:23 networks
-rw-------  1 root root 4.1K May 30 11:18 win10.xml
-rw-------  1 root root 4.5K Apr 25 10:21 win7.xml

其中几个重要的配置文件和目录介绍如下:

(1) /etc/libvirt/libvirt.conf

libvirt.conf文件用于配置本地默认的URI连接以及一些常用libvirt远程连接的别名:

#
# This can be used to setup URI aliases for frequently
# used connection URIs. Aliases may contain only the
# characters  a-Z, 0-9, _, -.
#
# Following the '=' may be any valid libvirt connection
# URI, including arbitrary parameters

#uri_aliases = [
#  "hail=qemu+ssh://root@hail.cloud.example.com/system",
#  "sleet=qemu+ssh://root@sleet.cloud.example.com/system",
#]

#
# These can be used in cases when no URI is supplied by the application
# (@uri_default also prevents probing of the hypervisor driver).
#
#uri_default = "qemu:///system"
uri_aliases = [
        "abelsu7-ubuntu=qemu+ssh://root@abelsu7-ubuntu/system",
        "centos-1=qemu+ssh://root@centos-1/system"
]

配置别名后,即可使用abelsu7-ubuntu来替代qemu+ssh://root@abelsu7-ubuntu/system远程的libvirt连接

> systemctl reload libvirtd # 重启 libvirtd

> virsh -c abelsu7-ubuntu # 使用别名连接至远程 libvirt
Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands
       'quit' to quit

virsh # hostname
abelsu7-ubuntu

virsh #

当然在代码中也可以使用这个别名,例如以下 Go 代码

package main

import (
    libvirt "github.com/libvirt/libvirt-go"
)

func main() {
    // conn, err := libvirt.NewConnect("qemu+ssh://root@abelsu7-ubuntu/system")
    conn, err := libvirt.NewConnect("abelsu7-ubuntu")
    ...
    ...
}
(2) /etc/libvirt/libvirtd.conf

libvirtd.conf是 libvirt 的守护进程libvirtd的配置文件,被修改后需要让 libvirtd 重新加载配置文件重启 libvirtd 才会生效。

libvirtd.conf中配置了libvirtd启动时的许多设置,包括是否建立 TCP、UNIX domain socket 等连接方式及其最大连接数,以及这些连接的认证机制设置libvirtd的日志级别

例如修改libvirtd.conf中的以下配置:

listen_tls = 0     # 关闭 TLS 安全认证的连接(默认是打开的)
listen_tcp = 1     # 打开 TCP 连接(默认是关闭的)
tcp_port = "16666" # 设置 TCP 监听的端口
unix_sock_dir = "/var/run/libvirt" # 设置 UNIX domain socket 的保存目录
auth_tcp = "none"  # TCP 连接不使用认证授权方式

要让 TCP、TLS 等连接生效,需要在启动libvirtd时加上--listen参数

修改完成后,使用systemctl命令重启libvirtd服务

> systemctl daemon-reload

> systemctl restart libvirtd

> systemctl status libvirtd
● libvirtd.service - Virtualization daemon
   Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-06-03 11:08:57 CST; 8s ago
     Docs: man:libvirtd(8)
           https://libvirt.org
 Main PID: 12192 (libvirtd)
    Tasks: 19 (limit: 32768)
   Memory: 13.6M
   CGroup: /system.slice/libvirtd.service
           ├─ 1827 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper
           ├─ 1828 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper
           └─12192 /usr/sbin/libvirtd --listen

Jun 03 11:08:57 centos-2 systemd[1]: Starting Virtualization daemon...
Jun 03 11:08:57 centos-2 systemd[1]: Started Virtualization daemon.
Jun 03 11:08:57 centos-2 dnsmasq[1827]: read /etc/hosts - 5 addresses
Jun 03 11:08:57 centos-2 dnsmasq[1827]: read /var/lib/libvirt/dnsmasq/default.addnhosts - 0 addresses
Jun 03 11:08:57 centos-2 dnsmasq-dhcp[1827]: read /var/lib/libvirt/dnsmasq/default.hostsfile

可以看到libvirtd的启动命令已经添加了--listen参数。测试一下 TCP 连接是否可用:

> virsh -c qemu+tcp://localhost:16666/system
Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands
       'quit' to quit

virsh # exit

> ll /var/run/libvirt/
total 0
drwxr-xr-x 2 root root 100 Jun  3 11:08 network
srwx------ 1 root root   0 Jun  3 11:08 libvirt-admin-sock
srwxrwxrwx 1 root root   0 Jun  3 11:08 libvirt-sock
srwxrwxrwx 1 root root   0 Jun  3 11:08 libvirt-sock-ro
drwxr-xr-x 2 root root  40 May 30 11:32 qemu
srw-rw-rw- 1 root root   0 May 30 11:19 virtlogd-admin-sock
drwxr-xr-x 2 root root  40 May 29 09:47 lxc
drwxr-xr-x 2 root root  40 May 29 09:47 hostdevmgr
drwx------ 2 root root  40 May 29 09:47 nwfilter-binding
drwxr-xr-x 2 root root  40 May 29 09:47 storage
srw-rw-rw- 1 root root   0 May 29 09:47 virtlockd-sock
srw-rw-rw- 1 root root   0 May 29 09:47 virtlogd-sock
(3) /etc/libvirt/qemu.conf

qemu.conf是 libvirt 对 QEMU 的驱动配置文件,包括 VNC、SPICE 等,以及连接它们时采用的权限认证方式的配置,也包括内存大页、SELinux、Cgroups 等相关配置。

(4) /etc/libvirt/qemu 目录

qemu目录下存放的是使用 QEMU 驱动的域的配置文件,查看qemu目录如下:

> ls -l
total 16
drwx------. 3 root root   42 Apr 25 10:23 networks
-rw-------  1 root root 4165 May 30 11:18 win10.xml
-rw-------  1 root root 4560 Apr 25 10:21 win7.xml

其中包括了两个域的 XML 配置文件win10.xmlwin7.xml),这是使用virt-manager工具创建的两个域,默认会将其保存到/etc/libvirt/qemu/目录下。

另一个networks目录则保存了创建一个域时默认使用的网络配置

libvirtd 的使用

libvirtd是虚拟化管理系统中服务端的守护进程。要想让某个节点能够利用 libvirt 进行管理,就需要在这个节点上运行libvirtd守护进程,以便让其他上层管理工具可以连接到该节点。

RHEL 7.3CentOS 7.5中,libvirtd是作为一个服务配置在系统中的:

> systemctl list-unit-files | grep libvirtd
libvirtd.service                              enabled

> systemctl is-enabled libvirtd
enabled

> systemctl is-active libvirtd
active

> systemctl status libvirtd
● libvirtd.service - Virtualization daemon
   Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-06-03 11:08:57 CST; 22h ago
     Docs: man:libvirtd(8)
           https://libvirt.org
 Main PID: 12192 (libvirtd)
    Tasks: 20 (limit: 32768)
   Memory: 23.2M
   CGroup: /system.slice/libvirtd.service
           ├─ 1827 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper
           ├─ 1828 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper
           └─12192 /usr/sbin/libvirtd --listen

Jun 03 17:19:33 centos-2 libvirtd[12192]: 2019-06-03 09:19:33.679+0000: 12195: warning : qemuProcessVerifyHypervFeatures:3936 : host doesn't support hyper...d' feature
Jun 03 17:19:33 centos-2 libvirtd[12192]: 2019-06-03 09:19:33.679+0000: 12195: warning : qemuProcessVerifyHypervFeatures:3936 : host doesn't support hyper...c' feature
Jun 03 17:19:33 centos-2 libvirtd[12192]: 2019-06-03 09:19:33.679+0000: 12195: warning : qemuProcessVerifyHypervFeatures:3936 : host doesn't support hyper...s' feature
Jun 03 17:20:41 centos-2 dnsmasq-dhcp[1827]: DHCPDISCOVER(virbr0) 192.168.122.176 52:54:00:b1:88:3b
Jun 03 17:20:41 centos-2 dnsmasq-dhcp[1827]: DHCPOFFER(virbr0) 192.168.122.176 52:54:00:b1:88:3b
Jun 03 17:20:41 centos-2 dnsmasq-dhcp[1827]: DHCPREQUEST(virbr0) 192.168.122.176 52:54:00:b1:88:3b
Jun 03 17:20:41 centos-2 dnsmasq-dhcp[1827]: DHCPACK(virbr0) 192.168.122.176 52:54:00:b1:88:3b DESKTOP-RKPPR8A
Jun 03 17:20:46 centos-2 dnsmasq-dhcp[1827]: DHCPREQUEST(virbr0) 192.168.122.176 52:54:00:b1:88:3b
Jun 03 17:20:46 centos-2 dnsmasq-dhcp[1827]: DHCPACK(virbr0) 192.168.122.176 52:54:00:b1:88:3b DESKTOP-RKPPR8A
Jun 03 17:31:35 centos-2 libvirtd[12192]: 2019-06-03 09:31:35.081+0000: 12192: error : qemuMonitorIO:718 : internal error: End of file from qemu monitor
Hint: Some lines were ellipsized, use -l to show in full.
  • 默认情况下,libvirt 监听一个本地的 Unix domain socket,而没有监听基于网络的 TCP/IP socket,需要使用-l或者--listen命令行参数来开启对libvirtd.conf配置文件中TCP/IP socket的监听
  • libvirtd守护进程的启动或停止,并不会直接影响正在运行中的客户机
  • libvirtd在启动或重启完成时,只要客户机的 XML 配置文件是存在的,libvirtd就会自动加载这些客户机的配置,获取它们的信息
  • 如果客户机没有基于libvirt格式的 XML 文件来运行(例如直接通过qemu命令行启动的客户机),libvirtd就不会自动发现它们
libvirtd 常用的命令行参数

libvirtd常用的命令行参数如下:

  • -d--daemon:作为守护进程后台运行
  • -f--config FILE:指定配置文件FILE,默认为/etc/libvirt/libvirtd.conf
  • -l--listen:监听配置文件中的 TCP Socket
  • -p--pid-file FILE:将libvirtd进程的 PID 写入FILE文件中,默认为/var/run/libvirtd.pid
  • -t--timeout SECONDS:设置超时时间SECONDS
  • -v--verbose:调整日志级别Verbose
  • -V--version版本号
> libvirtd --help

Usage:
  libvirtd [options]

Options:
  -h | --help            Display program help:
  -v | --verbose         Verbose messages.
  -d | --daemon          Run as a daemon & write PID file.
  -l | --listen          Listen for TCP/IP connections.
  -t | --timeout <secs>  Exit after timeout period.
  -f | --config <file>   Configuration file.
  -V | --version         Display version information.
  -p | --pid-file <file> Change name of PID file.

libvirt management daemon:

  Default paths:

    Configuration file (unless overridden by -f):
      /etc/libvirt/libvirtd.conf

    Sockets:
      /var/run/libvirt/libvirt-sock
      /var/run/libvirt/libvirt-sock-ro

    TLS:
      CA certificate:     /etc/pki/CA/cacert.pem
      Server certificate: /etc/pki/libvirt/servercert.pem
      Server private key: /etc/pki/libvirt/private/serverkey.pem

    PID file (unless overridden by -p):
      /var/run/libvirtd.pid

1.3 域的 XML 配置文件

配置文件格式示例

在 libvirt 中,客户机(即域)的配置是采用 XML 格式来描述的。例如下面是我使用virt-manager创建的客户机配置文件fedora-30.xml

<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
  virsh edit fedora-30
or other application using the libvirt API.
-->

<domain type='kvm'>
  <name>fedora-30</name>
  <uuid>70b8f58a-1589-4b83-bfd1-90dfd0cc8a56</uuid>
  <memory unit='KiB'>16777216</memory>
  <currentMemory unit='KiB'>16777216</currentMemory>
  <vcpu placement='static'>4</vcpu>
  <os>
    <type arch='x86_64' machine='pc-i440fx-2.11'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <vmport state='off'/>
  </features>
  <cpu mode='host-model' check='partial'>
    <model fallback='allow'/>
  </cpu>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/bin/kvm-spice</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/generic.qcow2'/>
      <target dev='hda' bus='ide'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <target dev='hdb' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>
    <controller type='usb' index='0' model='ich9-ehci1'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pci-root'/>
    <controller type='ide' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <controller type='virtio-serial' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </controller>
    <interface type='network'>
      <mac address='52:54:00:36:59:c3'/>
      <source network='default'/>
      <model type='rtl8139'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
        <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <channel type='spicevmc'>
      <target type='virtio' name='com.redhat.spice.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <graphics type='spice' autoport='yes' listen='0.0.0.0'>
      <listen type='address' address='0.0.0.0'/>
      <image compression='off'/>
    </graphics>
    <sound model='ich6'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </sound>
    <video>
      <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <redirdev bus='usb' type='spicevmc'>
      <address type='usb' bus='0' port='1'/>
    </redirdev>
    <redirdev bus='usb' type='spicevmc'>
      <address type='usb' bus='0' port='2'/>
    </redirdev>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
    </memballoon>
  </devices>
</domain>

如需编辑fedora-30.xml,请使用virsh edit fedora-30命令

在该域的 XML 文件中,所有的有效配置都在<domain></domain>标签之间,这表明该配置文件是一个域的配置。

通过 libvirt 启动客户机,经过文件解析命令参数的转换,最终也会调用qemu命令行工具来实际完成客户机的创建。该命令行参数非常详尽冗长,通过ps命令查询到的创建命令如下:

> ps -ef | grep qemu | grep fedora-30
libvirt+ 20817     1  0 10:23 ?        00:02:39 
qemu-system-x86_64 
    -enable-kvm 
    -name guest=fedora-30,debug-threads=on 
    -S -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-35-fedora-30/master-key.aes 
    -machine pc-i440fx-2.11,accel=kvm,usb=off,vmport=off,dump-guest-core=off 
    -cpu Skylake-Client-IBRS,ss=on,vmx=on,hypervisor=on,tsc_adjust=on,clflushopt=on,ssbd=on,xsaves=on,pdpe1gb=on 
    -m 16384 -realtime mlock=off 
    -smp 4,sockets=4,cores=1,threads=1 
    -uuid 70b8f58a-1589-4b83-bfd1-90dfd0cc8a56
    -no-user-config -nodefaults 
    -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain-35-fedora-30/monitor.sock,server,nowait 
    -mon chardev=charmonitor,id=monitor,mode=control 
    -rtc base=utc,driftfix=slew 
    -global kvm-pit.lost_tick_policy=delay 
    -no-hpet 
    -no-shutdown 
    -global PIIX4_PM.disable_s3=1 
    -global PIIX4_PM.disable_s4=1 
    -boot strict=on 
    -device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x5.0x7 
    -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5 
    -device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x5.0x1 
    -device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x5.0x2 
    -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 
    -drive file=/var/lib/libvirt/images/generic.qcow2,format=qcow2,if=none,id=drive-ide0-0-0 
    -device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 
    -drive if=none,id=drive-ide0-0-1,readonly=on 
    -device ide-cd,bus=ide.0,unit=1,drive=drive-ide0-0-1,id=ide0-0-1 
    -netdev tap,fd=27,id=hostnet0 
    -device rtl8139,netdev=hostnet0,id=net0,mac=52:54:00:36:59:c3,bus=pci.0,addr=0x3 
    -chardev pty,id=charserial0
    -device isa-serial,chardev=charserial0,id=serial0 
    -chardev spicevmc,id=charchannel0,name=vdagent 
    -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0 
    -spice port=5900,addr=0.0.0.0,disable-ticketing,image-compression=off,seamless-migration=on 
    -device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,max_outputs=1,bus=pci.0,addr=0x2 
    -device intel-hda,id=sound0,bus=pci.0,addr=0x4 
    -device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 
    -chardev spicevmc,id=charredir0,name=usbredir 
    -device usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=1 
    -chardev spicevmc,id=charredir1,name=usbredir 
    -device usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=2 
    -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7
    -msg timestamp=on
CPU、内存、启动顺序等基本配置

关于 CPU 的配置如下:

<vcpu placement='static'>4</vcpu>
<features>
  <acpi/>
  <apic/>
</features>
<cpu mode='custom' match='exact'>
  <model fallback='allow'>Haswell-noTSX</model>
</cpu>

关于内存的配置如下:

<domain>
  ...
  <memory unit='KiB'>16777216</memory>
  <currentMemory unit='KiB'>16777216</currentMemory>
  ...
</domain>

关于客户机类型启动顺序配置如下:

<os>
  <type arch='x86_64' machine='pc-i440fx-2.11'>hvm</type>
  <boot dev='hd'/>
  <boot dev='cdrom'/>
</os>
网络的配置

更新中…

参考文章

  1. 《KVM实战:原理、进阶与性能调优》
  2. libvirt
  3. XML Format | libvirt
  4. QEMU