From a2e01b40fa8f53b277be0348bb1fc0ff00c21602 Mon Sep 17 00:00:00 2001 From: chopupu Date: Mon, 11 Aug 2025 20:36:05 +0800 Subject: [PATCH 1/4] add virt files --- .../nestos/installation_and_deployment.md | 126 +++ docs/zh/virtualization/_toc.yaml | 10 + .../stratovirt/_toc.yaml | 20 + .../figures/StratoVirt_architecture.jpg | Bin 0 -> 214833 bytes .../stratovirt/install_stratovirt.md | 32 + .../stratovirt/interconnect_isula.md | 220 ++++++ .../stratovirt/interconnect_libvirt.md | 637 +++++++++++++++ .../stratovirt/prepare_env.md | 164 ++++ .../stratovirt/stratovirt_introduction.md | 47 ++ .../stratovirt_vfio_instructions.md | 222 ++++++ .../stratovirt/vm_configuration.md | 686 ++++++++++++++++ .../stratovirt/vm_management.md | 741 ++++++++++++++++++ 12 files changed, 2905 insertions(+) create mode 100644 docs/zh/virtualization/_toc.yaml create mode 100644 docs/zh/virtualization/virtualization_platform/stratovirt/_toc.yaml create mode 100644 docs/zh/virtualization/virtualization_platform/stratovirt/figures/StratoVirt_architecture.jpg create mode 100644 docs/zh/virtualization/virtualization_platform/stratovirt/install_stratovirt.md create mode 100644 docs/zh/virtualization/virtualization_platform/stratovirt/interconnect_isula.md create mode 100644 docs/zh/virtualization/virtualization_platform/stratovirt/interconnect_libvirt.md create mode 100644 docs/zh/virtualization/virtualization_platform/stratovirt/prepare_env.md create mode 100644 docs/zh/virtualization/virtualization_platform/stratovirt/stratovirt_introduction.md create mode 100644 docs/zh/virtualization/virtualization_platform/stratovirt/stratovirt_vfio_instructions.md create mode 100644 docs/zh/virtualization/virtualization_platform/stratovirt/vm_configuration.md create mode 100644 docs/zh/virtualization/virtualization_platform/stratovirt/vm_management.md diff --git a/docs/zh/cloud/nestos/nestos/installation_and_deployment.md b/docs/zh/cloud/nestos/nestos/installation_and_deployment.md index e69de29b..aba81fd1 100644 --- a/docs/zh/cloud/nestos/nestos/installation_and_deployment.md +++ b/docs/zh/cloud/nestos/nestos/installation_and_deployment.md @@ -0,0 +1,126 @@ +# 安装与部署 + +## 在 VMware 上部署 NestOS + +本指南展示了如何在VMware虚拟机管理程序上配置最新的 NestOS。 + +目前NestOS仅支持x86_64架构。 + +### 开始之前 + +​在开始部署 NestOS 之前,需要做如下准备工作: + +- 下载 NestOS ISO +- 准备 config.bu 文件 +- 配置 butane 工具(Linux环境/win10环境) +- 安装有VMware的宿主机 + +### 初步安装与启动 + +#### 启动 NestOS + +初次启动 NestOS ,ignition 尚未安装,可根据系统提示使用 nestos-installer 组件进行ignition的安装。 + +### 配置 ignition 文件 + +#### 获取 Butane + +可以通过 Butane 将 bu 文件转化为 ignition 文件。ignition 配置文件被设计为可读但不可写,是为了阻止用户尝试手动编写配置。Butane 提供了多种环境的支持,可以在 linux/windows 宿主机中或容器环境中进行配置。 + +```shell +docker pull quay.io/coreos/butane:release +``` + +#### 生成登录密码 + +在宿主机执行如下命令,并输入你的密码。 + +```shell +# openssl passwd -1 -salt yoursalt +Password: +$1$yoursalt$1QskegeyhtMG2tdh0ldQN0 +``` + +#### 生成ssh-key + +在宿主机执行如下命令,获取公钥和私钥以供后续 ssh 登录。 + +```shell +# ssh-keygen -N '' -f ./id_rsa +Generating public/private rsa key pair. +Your identification has been saved in ./id_rsa +Your public key has been saved in ./id_rsa.pub +The key fingerprint is: +SHA256:4fFpDDyGHOYEd2fPaprKvvqst3T1xBQuk3mbdon+0Xs root@host-12-0-0-141 +``` + +```shell +The key's randomart image is: ++---[RSA 3072]----+ +| ..= . o . | +| * = o * . | +| + B = * | +| o B O + . | +| S O B o | +| * = . . | +| . +o . . | +| +.o . .E | +| o*Oo ... | ++----[SHA256]-----+ +``` + +可以在当前目录查看id_rsa.pub公钥: + +```shell +# cat id_rsa.pub +ssh-rsa +AAAAB3NzaC1yc2... +``` + +#### 编写bu文件 + +进行最简单的初始配置,如需更多详细的配置,参考后面的 ignition 详解。 +如下为最简单的 config.bu 文件: + +```shell +variant: fcos +version: 1.1.0 +passwd: + users: + - name: nest + password_hash: "$1$yoursalt$1QskegeyhtMG2tdh0ldQN0" + ssh_authorized_keys: + - "ssh-rsa + AAAAB3NzaC1yc2EAAA..." +``` + +#### 生成ignition文件 + +将 config.bu 通过 Butane 工具转换为 config.ign 文件,如下为在容器环境下进行转换。 + +```shell +# docker run --interactive --rm quay.io/coreos/butane:release \ +--pretty --strict < your_config.bu > transpiled_config.ign +``` + +### 安装 NestOS + +将宿主机生成的config.ign文件通过scp拷贝到前面初步启动的 NestOS 中,该OS目前运行在内存中, +并没有安装到硬盘。 + +```shell +sudo -i +scp root@your_ipAddress:/root/config.ign /root +``` + +根据系统所给提示,执行如下指令完成安装。 + +```shell +nestos-installer install /dev/sda --ignition-file config.ign +``` + +安装完成后重启 NestOS 。 + +```shell +systemctl reboot +``` diff --git a/docs/zh/virtualization/_toc.yaml b/docs/zh/virtualization/_toc.yaml new file mode 100644 index 00000000..14ad99f9 --- /dev/null +++ b/docs/zh/virtualization/_toc.yaml @@ -0,0 +1,10 @@ +label: 虚拟化 +sections: + - label: 虚拟化平台 + sections: + - href: ./virtualization_platform/virtualization/_toc.yaml + - href: ./virtualization_platform/stratovirt/_toc.yaml + - label: openStack用户指南 + href: >- + https://openstack-sig.readthedocs.io/zh/latest/ + description: 一个开源的云计算管理平台项目 \ No newline at end of file diff --git a/docs/zh/virtualization/virtualization_platform/stratovirt/_toc.yaml b/docs/zh/virtualization/virtualization_platform/stratovirt/_toc.yaml new file mode 100644 index 00000000..49bff4be --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/stratovirt/_toc.yaml @@ -0,0 +1,20 @@ +label: StratoVirt用户指南 +isManual: true +description: StratoVirt是计算产业中面向云数据中心的企业级虚拟化平台,实现了一套架构支持虚拟机、容器、Serverless三种场景 +sections: + - label: StratoVirt介绍 + href: ./stratovirt_introduction.md + - label: 安装StratoVirt + href: ./install_stratovirt.md + - label: 准备使用环境 + href: ./prepare_env.md + - label: 虚拟机配置 + href: ./vm_configuration.md + - label: 虚拟机管理 + href: ./vm_management.md + - label: 对接iSula安全容器 + href: ./interconnect_isula.md + - label: 对接libvirt + href: ./interconnect_libvirt.md + - label: StratoVirt VFIO 使用说明 + href: ./stratovirt_vfio_instructions.md \ No newline at end of file diff --git a/docs/zh/virtualization/virtualization_platform/stratovirt/figures/StratoVirt_architecture.jpg b/docs/zh/virtualization/virtualization_platform/stratovirt/figures/StratoVirt_architecture.jpg new file mode 100644 index 0000000000000000000000000000000000000000..93f1697131dd2a6f8c010def9f42ad067b9b0bd9 GIT binary patch literal 214833 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 literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/stratovirt/install_stratovirt.md b/docs/zh/virtualization/virtualization_platform/stratovirt/install_stratovirt.md new file mode 100644 index 00000000..b338a05b --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/stratovirt/install_stratovirt.md @@ -0,0 +1,32 @@ +# 安装StratoVirt + +## 软硬件要求 + +### 最低硬件要求 + +- 处理器架构:仅支持AArch64和x86_64处理器架构。AArch64需要ARMv8及更高版本且支持虚拟化扩展;x86_64支持VT-x。 + +- 2核CPU +- 4GiB内存 +- 16GiB可用磁盘空间 + +### 软件要求 + +操作系统:openEuler 22.03 LTS SP4 + +## 安装组件 + +使用StratoVirt虚拟化,需要安装StratoVirt。安装前,请确保已经配置了openEuler yum源。 + +1. 使用root权限,安装StratoVirt组件,参考命令如下: + + ```sh + # yum install stratovirt + ``` + +2. 查看是否安装成功。 + + ```sh + $ stratovirt -version + StratoVirt 2.1.0 + ``` diff --git a/docs/zh/virtualization/virtualization_platform/stratovirt/interconnect_isula.md b/docs/zh/virtualization/virtualization_platform/stratovirt/interconnect_isula.md new file mode 100644 index 00000000..d5c2efd7 --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/stratovirt/interconnect_isula.md @@ -0,0 +1,220 @@ +# 对接iSula安全容器 + +## 概述 + +为了给容器提供更好的隔离环境,提高系统安全性,可以使用 iSula 安全容器,即通过 StratoVirt 对接 iSula 安全容器。 + +## 对接iSula安全容器 + +### **前提条件** + +已安装 iSulad 和 kata-containers,并确保 iSulad 支持 containerd-kata-shim-v2 容器运行时和 devicemapper 存储驱动。 + +此处给出安装 iSulad 和 kata-containers 并进行相应配置的参考方法。 + +1. 配置 yum 源,使用 root 权限安装 iSulad 和 kata-containers : + + ```shell + # yum install iSulad + # yum install kata-containers + ``` + +2. 制作并配置存储 Storage: + + 需要用户规划好磁盘如/dev/sdxx,该磁盘会被格式化。 + + ```shell + # pvcreate /dev/sdxx + # vgcreate isulaVG0 /dev/sdxx + # lvcreate --wipesignatures y -n thinpool isulaVG0 -l 95%VG + # lvcreate --wipesignatures y -n thinpoolmeta isulaVG0 -l 1%VG + # lvconvert -y --zero n -c 512K --thinpool isulaVG0/thinpool --poolmetadata isulaVG0/thinpoolmeta + ``` + + 在配置文件 /etc/lvm/profile/isulaVG0-thinpool.profile 中添加如下: + + ```conf + activation { + thin_pool_autoextend_threshold=80 + thin_pool_autoextend_percent=20 + } + ``` + + 更改配置文件/etc/isulad/daemon.json中的storage-driver 和 storage-opts 如下:将默认存储驱动类型 overlay 配置成 devicemapper 。 + + ```conf + "storage-driver": "devicemapper", + "storage-opts": [ + "dm.thinpooldev=/dev/mapper/isulaVG0-thinpool", + "dm.fs=ext4", + "dm.min_free_space=10%" + ], + ``` + +3. 重启 isulad : + + ```shell + # systemctl daemon-reload + # systemctl restart isulad + ``` + +4. 确认 iSula 存储驱动是否配置成功: + + ```shell + # isula info + ``` + + 若回显有如下信息,说明配置成功。 + + ```text + Storage Driver: devicemapper + ``` + +### **对接指导** + +StratoVirt 通过对接 kata-containers来接入 isula 容器生态,此处给出对接 kata-containers 的操作指导。 + +#### 对接轻量虚拟机 + +1. 修改 kata 配置文件(默认路径为 /usr/share/defaults/kata-containers/configuration.toml,也可以参考同一目录下的configuration-stratovirt.toml进行配置) 。将安全容器的 hypervisor 类型修改为 stratovirt,kernel 修改为 kata-containers 的 kernel 镜像绝对路径,initrd 修改为 kata-containers 的 initrd 镜像文件(使用 yum 安装 kata-containers 时,默认会下载这两个镜像文件并存放在 /var/lib/kata/ 目录,配置时也可以使用其他镜像 )。 + + 替换的配置内容参考如下: + + ```shell + [hypervisor.stratovirt] + path = "/usr/bin/stratovirt" + kernel = "/var/lib/kata/kernel" + initrd = "/var/lib/kata/kata-containers-initrd.img" + machine_type = "microvm" + block_device_driver = "virtio-mmio" + use_vsock = true + enable_netmon = true + internetworking_model="tcfilter" + sandbox_cgroup_with_emulator = false + disable_new_netns = false + disable_block_device_use = false + disable_vhost_net = true + ``` + +2. 使用 root 权限和 **isula** 命令运行 busybox 安全容器,完成 StratoVirt 和 安全容器的对接。 + + ```shell + # isula run -tid --runtime "io.containerd.kata.v2" --net=none --name test busybox:latest sh + ``` + +3. 使用 **isula ps** 确认安全容器 test 正常运行,然后通过以下命令进入 test 容器。 + + ```shell + # isula exec -ti test sh + ``` + +4. 通过虚拟机快照加速安全容器的启动速度,降低虚拟机内存开销。 + + 修改 kata 配置文件 configuration.toml,将配置项 enable_template 设置为 true,即允许虚拟机通过制作快照方式进行启动: + + ```shell + [factory] + # VM templating support. Once enabled, new VMs are created from template + # using vm cloning. They will share the same initial kernel, initramfs and + # agent memory by mapping it readonly. It helps speeding up new container + # creation and saves a lot of memory if there are many kata containers running + # on the same host. + # + # When disabled, new VMs are created from scratch. + # + # Note: Requires "initrd=" to be set ("image=" is not supported). + # + # Default false + enable_template = true + ``` + + 配置项 enable_template 设置为 true 后,kata-containers 创建安全容器时,将会检查默认路径(/run/vc/vm/template)下是否存在快照文件,如果存在,直接以该快照文件启动虚拟机,如果不存在,则会创建虚拟机快照,创建完成后,以该快照文件启动虚拟机。 + +5. 通过安全组件 ozone 进一步增强安全容器的隔离性。 + + 修改 kata 配置文件 configuration.toml,将配置项 ozone_path 设置为 ozone 可执行文件的路径(如果使用 yum 安装 stratovirt,ozone 可执行文件默认在 /usr/bin 目录下)。配置该项后,将打开 ozone 安全沙箱功能,作为虚拟化层隔离被攻击者突破后的保险,进一步增强 StratoVirt 安全容器的隔离性: + + ```shell + # Path for the ozone specific to stratovirt + # If the ozone path is set, stratovirt will be launched in + # ozone secure environment. It is disabled by default. + ozone_path = "/usr/bin/ozone" + ``` + + 至此,可以在 test 容器内运行容器命令。 + +#### 对接标准虚拟机 + +使用 StratoVirt 标准虚拟机作为安全容器的 sandbox,需要额外修改少量配置。具体步骤如下: + +1. 配置参考如下: + + ```shell + [hypervisor.stratovirt] + path = "/usr/bin/stratovirt" + kernel = "/var/lib/kata/kernel" + initrd = "/var/lib/kata/kata-containers-initrd.img" + # x86_64 架构 + machine_type = "q35" + # aarch64 架构 + machine_type = "virt" + block_device_driver = "virtio-blk" + pcie_root_port = 2 + use_vsock = true + enable_netmon = true + internetworking_model = "tcfilter" + sandbox_cgroup_with_emulator = false + disable_new_netns = false + disable_block_device_use = false + disable_vhost_net = true + ``` + + 上述配置中,需要根据主机架构,修改对应的虚拟机机型。需要将 block_device_driver 驱动类型改为 virtio-blk。另外,StratoVirt 只支持将设备热插到root port,根据需要热插的设备数量,合理设置 pcie_root_port 值。 + +2. 安装启动标准虚拟机需要的固件 + + x86_64 架构: + + ```shell + # yum install -y edk2-ovmf + ``` + + aarch64 架构: + + ```shell + # yum install -y edk2-aarch64 + ``` + +3. 编译替换为 kata-containers 2.x 版本二进制 + + 当前只为 kata-containers 2.x 版本(对应 kata-containers 源码仓的 openEuler-21.09 分支)适配了 StratoVirt 标准虚拟机作为 sandbox。因此,需要手动下载 kata-containers 源码,编译并替换 `/usr/bin` 目录下的 containerd-shim-kata-v2 二进制文件。 + + ```shell + # mkdir -p /root/go/src/github.com/ + # cd /root/go/src/github.com/ + # git clone https://gitee.com/src-openeuler/kata-containers.git + # cd kata-containers + # git checkout openEuler-21.09 + # ./apply-patches + # cd src/runtime + # make + ``` + + 编译出的二进制位 containerd-shim-kata-v2,需要将默认 `/usr/bin/` 目录的 kata 二进制备份后替换: + + ```shell + # cp /usr/bin/containerd-shim-kata-v2 /usr/bin/containerd-shim-kata-v2.bk + # cp containerd-shim-kata-v2 /usr/bin/containerd-shim-kata-v2 + ``` + +4. 使用 root 权限 和 **isula** 命令运行 busybox 安全容器,完成 StratoVirt 和 安全容器的对接。 + + ```shell + # isula run -tid --runtime "io.containerd.kata.v2" --net=none --name test busybox:latest sh + ``` + +5. 使用 **isula ps** 确认安全容器 test 正常运行,然后通过以下命令进入 test 容器。 + + ```shell + # isula exec -ti test sh + ``` diff --git a/docs/zh/virtualization/virtualization_platform/stratovirt/interconnect_libvirt.md b/docs/zh/virtualization/virtualization_platform/stratovirt/interconnect_libvirt.md new file mode 100644 index 00000000..ef8bd6ec --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/stratovirt/interconnect_libvirt.md @@ -0,0 +1,637 @@ +# 对接 libvirt + +## 概述 + +libvirt 是一个管理 hypervisor 的上层软件,它通过不同的驱动统一管理不同类型的 hypervisor ,并对外提供统一、稳定的应用程序接口。 + +在云场景中,业内广泛使用 libvirt 管理大规模的虚拟机。为了方便地对大规模的 StratoVirt 虚拟机进行部署、编排和管理,StratoVirt 标准虚拟化支持对接 libvirt,打通了 libvirt 北向接口。用户可以通过 libvirt 对应的 XML 文件描述一个虚拟机,包括虚拟机名称、CPU、磁盘等。 + +本章介绍 StratoVirt 平台支持的 XML 配置,以及如何使用 virsh 命令管理虚拟机。 + +## 前提条件 + +StratoVirt 对接 libvirt,主机需要满足如下条件: + +- 已正确配置 yum 源 +- 已正确安装并启动 libvirt +- 已正确安装 StratoVirt + +## 虚拟机配置 + +libvirt 工具采用 XML 格式的文件描述一个虚拟机特征,包括虚拟机名称、CPU、内存、磁盘、网卡等信息。用户可以通过修改配置文件,对虚拟机进行管理。 + +StratoVirt 对接 libvirt 之前,需要先配置 XML 文件。本小节介绍 StratoVirt 对接 libvirt 时支持的 XML 配置项以及配置方式。 + +> [!NOTE]说明 +> +> 使用 libvirt 管理 StratoVirt 虚拟机前,应该注意到 StratoVirt 当前支持的特性、特性之间的互斥关系、特性的配置前提条件、规格等,详细信息请参见命令行方式的 "[虚拟机配置](https://docs.openeuler.org/zh/docs/22.03_LTS_SP4/docs/StratoVirt/%E8%99%9A%E6%8B%9F%E6%9C%BA%E9%85%8D%E7%BD%AE.html)”章节。 + +### 虚拟机描述 + +虚拟机 XML 文件必须包含描述虚拟机的最基本元素: domain 和 name 。 + +#### 元素介绍 + +- domain:虚拟机配置的根元素,用于配置运行 StratoVirt 虚拟机的 hypervisor 类型。 + + 属性 type:domain 的类型,在 StratoVirt 虚拟化中,该值为 kvm 。 + +- name:虚拟机名称。 + + 虚拟机名称是一个长度不超过 255 字符的字符串。同一个主机上的虚拟机名称不能重复,虚拟机名称必须由数字、字母、“_”、“-”、“:” 组成。 + +#### 配置示例 + +假设配置虚拟机名称为 StratoVirt ,示例为: + +```shell + + StratoVirt + ... + +``` + +### 虚拟CPU和内存 + +本节介绍虚拟 CPU 和虚拟内存的配置。 + +#### 元素介绍 + +- vcpu:虚拟处理器的个数。 + +- memory:虚拟内存大小。 + + 属性 unit :指定内存单位,属性值支持 KiB(210 字节)、MiB(220 字节)、GiB(230 字节)、TiB(240 字节)等。 + + > [!NOTE]说明 + > + > StratoVirt 暂不支持 CPU 拓扑结构,请勿配置该项。 + +#### 配置示例 + +配置 8GiB 内存,4 个虚拟处理器的示例如下: + +```xml + + ... + 4 + 8 + ... + +``` + +### 虚拟机设备 + +本节介绍如何使用 XML 文件配置虚拟机设备:磁盘,网卡,rng,balloon,console,vsock 设备。 + +#### 磁盘 + +##### 元素介绍 + +- 属性 type :指定后端存储介质类型,在 StratoVirt 虚拟化中,该值为 file 。 + + 属性 device:呈现给虚拟机的存储介质类型,在 StratoVirt 虚拟化中,该值为 disk 。 + +- driver:指定后端驱动的详细信息。 + + 属性 type :磁盘的格式类型,在 StratoVirt 虚拟化中,该值为 raw 。StratoVirt 当前只支持 raw 格式的磁盘。 + + 属性 iothread:为磁盘配置 iothread ,取值为 iothread 编号。在配置磁盘的 iothread 之前,需使用 iothread 元素配置 iothread 的个数。 + +- source: 指定后端存储介质。 + + 属性 file:指定磁盘路径。 + +- target:指定后端驱动的详细信息。 + + 属性 dev:指定磁盘名称。 + + 属性 bus:指定磁盘设备的类型,在 StratoVirt 虚拟化中,该值为 virtio 。 + +- iotune: 指定磁盘 IO 特性。 + + 属性 total_iops_sec:设置磁盘 iops 的值。 + +- address:用于设置设备所要挂载的总线属性。 + + 属性 type:总线类型,在 StratoVirt 虚拟化中,该值为 pci 。 + + 属性 domain:虚拟机的域。 + + 属性 bus:设备将要挂载的 bus 号。 + + 属性 slot:设备将要挂载的 slot 号,取值范围为:[0, 31] 。 + + 属性 function:设备将要挂载的 function 号,取值范围为:[0, 7] 。 + +##### 配置示例 + +配置磁盘路径为:`/home/openEuler-22.03-LTS-SP4-stratovirt.img`,配置 1 个 iothread,并且磁盘 iothread 配置为 iothread1 ,iops 为 10000,并将其挂载在 bus 为 1、slot 为 0,function 为 0 的 PCI 总线上,示例为: + +```xml + + ... + 1 + + + + + + + 10000 + +
+ + ... + + +``` + +#### 网络设备 + +##### 元素介绍 + +- interface:网络接口 + + 属性 type:指定网络设备类型。 + +- mac:虚拟网卡地址 + + 属性 address:虚拟网卡地址。 + +- source: 指定后端网桥 + + 属性 bridge:指定网桥。 + +- target:指定后端网卡 + + 属性 dev:指定后端的 tap 设备。 + +- model: 虚拟网卡类型 + + 属性 type: 虚拟网卡类型,在 StratoVirt 虚拟化中,该值为 virtio。 + +- driver:用来指定是否开启 vhost 。 + + 属性 name:如果设置 name 为 qemu 则使用 virtio-net 设备,如果不配置 driver 或者 name 值为 vhost ,则使用 vhost-net 设备。 + +##### 配置示例 + +配置网络前请参考 [配置linux网桥](https://docs.openeuler.org/zh/docs/22.03_LTS_SP4/docs/Virtualization/%E5%87%86%E5%A4%87%E4%BD%BF%E7%94%A8%E7%8E%AF%E5%A2%83.html#%E5%87%86%E5%A4%87%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%BD%91%E7%BB%9C),配置好 Linux 网桥。配置 mac 地址为:`de:ad:be:ef:00:01`,网桥为配置好的 br0 ,使用 virtio-net 设备,并将其挂载在 bus 为 2、slot 为 0,function 为 0 的 PCI 总线上,示例为: + +```xml + + ... + + + + + + +
+ + ... + + +``` + +#### balloon 设备 + +##### 元素介绍 + +- memballoon:balloon 设备类型 + + 属性 model :指定 balloon 设备类型,在 StratoVirt 虚拟化中,该值为 virtio 。 + +- alias:balloon 设备的别名 + + 属性 name :balloon 设备的 id 。 + + 属性 autodeflate :设置 auto deflate(自动收缩)特性,可选值为:`on` 、`off` 。 + +##### 配置示例 + +配置 balloon 设备,开启 autodeflate 特性,并将其挂载在 bus 为 3、slot 为 0,function 为 0 的 PCI 总线上,示例为: + +```xml + + ... + + + + +
+ + ... + + +``` + +#### console 设备 + +由于 console 设备挂载在 virtio-serial 下的总线上,所以在创建 console 设备时,需要创建 virtio-serial 设备。 + +> [!NOTE]说明 +> +> StratoVirt 的 console 设备暂时不支持多端口特性,每个虚拟机只能配置一个 console 设备。 + +##### 元素介绍 + +- controller:控制器 + + 属性 type:控制器类型,此处值为 virtio-serial 。 + +- alias:别名 + + 属性 name:设备的 id。 + +- console:console 设备 + + 属性 type:指定 console 设备的重定向方式。支持的重定向方式有:pty , file 和 unix 。 + +- target:配置 console 设备。 + + 属性 type:指定 console 设备类型,在 StratoVirt 虚拟化中,该值为 virtio 。 + +##### 配置示例 + +配置重定向方式为 pty ,并将其挂载在 bus 为 4、slot 为 0,function 为 0 的 PCI 总线上,示例为: + +```xml + + ... + + + +
+ + + + + + ... + + +``` + +#### rng 设备 + +##### 元素介绍 + +- rng:rng 设备 + + 属性 model:指定 rng 设备类型,在 StratoVirt 虚拟化中,该值为 virtio 。 + +- rate:rng 设备产生随机数速率 + + 属性 period :用于设置随机数产生周期,单位为毫秒,当前 StratoVirt 不支持设置周期值,默认值为 1000 毫秒,请将该值设置为 1000。 + + 属性 bytes :周期内产生的最大字节数。 + +- backend:设置 rng 设备后端,值为 host 中 rng 设备的路径 + + 属性 model:用于指定后端设备类型,在 StratoVirt 虚拟化中,该值为 random 。 + +##### 配置示例 + +配置周期为 1000ms 内最多产生 1234 字节,rng 设备在 host 中路径为 `/dev/random` ,并将其挂载在 bus 为 5、slot 为 0,function 为 0 的 PCI 总线上,示例为: + +```xml + + ... + + + + /dev/random +
+ + ... + + +``` + +#### vsock 设备 + +##### 元素介绍 + +- vsock:vsock 设备 + + 属性 model:指定 vsock 设备类型,在 StratoVirt 虚拟化中,该值为 virtio 。 + +- cid:设置 vsock 设备的 cid + + 属性 address:用于设置 cid 的值 + +##### 配置示例 + +配置 cid 为 8,并将其挂载在 bus 为 6、slot 为 0,function 为 0 的 PCI 总线上,示例为: + +```xml + + ... + + + +
+ + ... + + +``` + +### 体系架构相关配置 + +XML 中还有一些体系架构相关的配置,如 pflash、主板等。 + +#### 元素介绍 + +- os:定义虚拟机启动参数 + + 子元素 type :指定虚拟机类型,属性 arch 表示架构,属性 machine 表示主板类型,在 StratoVirt 虚拟化中,AArch64 架构只支持 virt 主板,x86_64 架构只支持 Q35 主板。 + + 子元素 kernel :用于指定 kernel 路径。 + + 子元素 cmdline :指定命令行启动参数。 + + 子元素 loader :指定加载固件,属性 readonly 表示是否只读;属性 type 表示类型,在 StratoVirt 虚拟化中,该值为 pflash 。 + +- features:hypervisor 支持的以下特性 + + 子元素 acpi :是否支持 ACPI,在 StratoVirt 虚拟化中使用了 ACPI 特性,所以该特性必须配置。 + + 子元素 gic :ARM 处理器指定中断处理器,属性 version 表示 GIC 的版本,在 StratoVirt 虚拟化中,该值为 3 。 + +##### 配置示例 + +配置虚拟机 CPU 架构 ARM,主板为 virt ,启动命令行为:`console=ttyAMA0 root=/dev/vda reboot=k panic=1 rw` 。pflash 路径为:`/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw`,属性为只读。 kernel 路径为:`/home/std-vmlinuxz`。示例为: + +```xml + + ... + + hvm + /home/std-vmlinuxz + console=ttyAMA0 root=/dev/vda reboot=k panic=1 rw + `/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw` + + ... + +``` + +### 内存大页 + +#### 元素介绍 + +- memoryBacking:表示配置内存相关的信息 + +- hugepages:配置内存大页 + +- page:大页配置 + + 属性 size :内存大页的大小 + + 属性 unit :大页大小的单位 + +#### 配置示例 + +配置 2MiB 大页示例如下: + +```xml + + ... + + + + + + ... + +``` + +### 配置示例 + +#### x86 配置示例 + +配置一台名为 StratoVirt ,内存 8GiB ,配置 1GiB 单位的内存大页,4 个虚拟 CPU,架构为 x86_64 ,主板类型为 Q35 ,对应 XML 文件的配置示例如下: + +```xml + + StratoVirt + 8 + + + + + + + 4 + + 1 + + hvm + /path/to/standard_vm_kernel + console=hvc0 root=/dev/vda reboot=k panic=1 rw + /path/to/pflash + /path/to/OVMF_VARS + + + + + + /path/to/StratoVirt_binary_file + + + + + + + + + + + + + + + + 1000 + +
+ + + + + + +
+ + + + +
+ + + + + + + + +
+ + + + + /path/to/random_file +
+ + + + +
+ + + +``` + +#### ARM 配置示例 + +如果想要配置一台名为 StratoVirt ,内存 8GiB,配置 1GiB 单位大页,4 个虚拟 CPU,架构为 aarch64 ,主板类型为 virt ,对应 XML 文件的配置示例如下: + +```xml + + StratoVirt + 8 + + + + + + + 4 + + 1 + + hvm + /path/to/standard_vm_kernel + console=ttyAMA0 root=/dev/vda reboot=k panic=1 rw + /path/to/pflash + + + + + + + /path/to/StratoVirt_binary_file + + + + + + +
+ + 1000 + + + + + + + +
+ + + + +
+ + + + + + + + +
+ + + + + /path/to/random_file +
+ + + + +
+ + + +``` + +## 管理虚拟机 + +libvirt 使用 virsh 命令来管理虚拟机,当 StratoVirt 平台和 libvirt 对接时,仅支持以下与 StratoVirt 交互的命令: + +- create:创建虚拟机 + +- suspend:挂起虚拟机 + +- resume:恢复虚拟机 + +- destroy:销毁虚拟机 + +- console:通过 console 登录虚拟机 + +> [!NOTE]说明 +> +> StratoVirt 暂不支持虚拟机重启、虚拟机关机等命令。 + +### 管理虚拟机生命周期 + +假设用户已经按照需要完成一个名为 StratoVirt 的虚拟机配置文件 st.xml ,则对应生命周期管理的命令如下: + +- 创建虚拟机 + + ```shell + virsh create st.xml + ``` + + 虚拟机创建完成后,可以通过 **virsh list** 命令查看,会存在一个名为 StratoVirt 的虚拟机。 + +- 挂起虚拟机 + + ```shell + virsh suspend StratoVirt + ``` + + 虚拟机挂起后,虚拟机暂停运行。可以通过 **virsh list** 命令查看,虚拟机 StratoVirt 的状态为 paused 。 + +- 恢复虚拟机 + + ```sh + virsh resume StratoVirt + ``` + + 虚拟机恢复后,可以通过 **virsh list** 命令查看,虚拟机 StratoVirt 的状态为 running 。 + +- 销毁虚拟机 + + ```sh + virsh destroy StratoVirt + ``` + + 虚拟机销毁后,使用 **virsh list** 查看虚拟机,发现虚拟机 StratoVirt 不存在。 + +### 登录虚拟机 + +虚拟机创建完成后,可以通过 **virsh console** 登录虚拟机内部操作虚拟机。假设虚拟机名称为 StratoVirt,参考命令如下: + +```sh +virsh console StratoVirt +``` + +> [!NOTE]说明 +> +> 为了可以正常使用 virsh console 命令,需要在 XML 中配置 console 设备的重定向类型为 pty 。 diff --git a/docs/zh/virtualization/virtualization_platform/stratovirt/prepare_env.md b/docs/zh/virtualization/virtualization_platform/stratovirt/prepare_env.md new file mode 100644 index 00000000..6372640a --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/stratovirt/prepare_env.md @@ -0,0 +1,164 @@ +# 准备环境 + +## 使用说明 + +- StratoVirt仅支持运行于x86_64和AArch64处理器架构下并启动相同架构的Linux虚拟机。 +- 建议在 openEuler 22.03 LTS SP4 版本编译、调测和部署该版本 StratoVirt。 +- StratoVirt支持以非root权限运行。 + +## 环境要求 + +运行StratoVirt需要具备如下环境: + +- /dev/vhost-vsock设备(用于实现mmio) +- nmap工具 +- Kernel镜像和rootfs镜像 + +## 准备设备和工具 + +- StratoVirt运行需要实现mmio设备,所以运行之前确保存在设备`/dev/vhost-vsock` + + 查看该设备是否存在: + + ```sh + $ ls /dev/vhost-vsock + /dev/vhost-vsock + ``` + + 若该设备不存在,请执行如下命令生成/dev/vhost-vsock设备。 + + ```sh + $ modprobe vhost_vsock + ``` + +- 为了能够使用QMP命令,需要安装nmap工具,在配置yum源的前提下,可执行如下命令安装nmap。 + + ```sh + # yum install nmap + ``` + +## 准备镜像 + +### 制作kernel镜像 + +当前版本的StratoVirt仅支持x86_64和AArch64平台的PE格式内核镜像。此格式内核映像可通过以下方法生成。 + +1. 获取openEuler的kernel源代码,参考命令如下: + + ```sh + $ git clone https://gitee.com/openeuler/kernel.git + $ cd kernel + ``` + +2. 查看并切换kernel的版本到openEuler-22.03-LTS-SP4,参考命令如下: + + ```sh + $ git checkout openEuler-22.03-LTS-SP4 + ``` + +3. 配置并编译Linux kernel。目前有两种方式可以生成配置文件:1. 使用推荐配置([获取配置文件](https://gitee.com/openeuler/stratovirt/tree/master/docs/kernel_config)),将指定版本的推荐文件复制到kernel路径下并重命名为`.config`, 并执行命令`make olddefconfig`更新到最新的默认配置(否则后续编译可能有选项需要手动选择)。2. 通过以下命令进行交互,根据提示完成kernel配置,可能会提示缺少指定依赖,按照提示使用`yum install`命令进行安装。 + + ```sh + $ make menuconfig + ``` + +4. 使用下面的命令制作并转换kernel镜像为PE格式,转化后的镜像为vmlinux.bin。 + + ```sh + $ make -j vmlinux && objcopy -O binary vmlinux vmlinux.bin + ``` + +5. 如果想在x86平台使用bzImzge格式的kernel,可以使用如下命令进行编译。 + + ```sh + $ make -j bzImage + ``` + +## 制作rootfs镜像 + +rootfs镜像是一种文件系统镜像,在StratoVirt启动时可以装载带有init的ext4格式的镜像。下面是制作ext4 rootfs镜像的简单方法。 + +1. 准备一个大小合适的文件(例如在/home中创建10GiB空间大小的文件)。 + + ```sh + $ cd /home + $ dd if=/dev/zero of=./rootfs.ext4 bs=1G count=10 + ``` + +2. 在此文件上创建空的ext4文件系统。 + + ```sh + $ mkfs.ext4 ./rootfs.ext4 + ``` + +3. 挂载文件镜像。创建/mnt/rootfs,使用root权限,将rootfs.ext4挂载到/mnt/rootfs目录。 + + ```sh + $ mkdir /mnt/rootfs + # 返回刚刚创建文件系统的目录(如/home) + $ cd /home + $ sudo mount ./rootfs.ext4 /mnt/rootfs && cd /mnt/rootfs + ``` + +4. 获取对应处理器架构的最新alpine-mini rootfs。 + + - 对于AArch64处理器架构,从[alpine](http://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/)网站获取最新alpine-mini rootfs,例如:alpine-minirootfs-3.16.0-aarch64.tar.gz ,参考命令如下: + + ```sh + $ wget http://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/aarch64/alpine-minirootfs-3.16.0-aarch64.tar.gz + $ tar -zxvf alpine-minirootfs-3.16.0-aarch64.tar.gz + $ rm alpine-minirootfs-3.16.0-aarch64.tar.gz + ``` + + - 对于x86_64处理器架构,从[alpine](http://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/)网站获取指定架构最新alpine-mini rootfs,例如:alpine-minirootfs-3.16.0-x86_64.tar.gz,参考命令如下: + + ```sh + $ wget http://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/x86_64/alpine-minirootfs-3.16.0-x86_64.tar.gz + $ tar -zxvf alpine-minirootfs-3.16.0-x86_64.tar.gz + $ rm alpine-minirootfs-3.16.0-x86_64.tar.gz + ``` + +5. 为ext4文件镜像制作一个简单的/sbin/init,参考命令如下: + + ```sh + $ rm sbin/init; touch sbin/init && cat > sbin/init < /sys/bus/pci/devices/0000:03:00.0/driver/unbind + ``` + + 最后将该 PCI 设备重新绑定到 vfio-pci 驱动。 + + ```shell + lspci -ns 0000:03:00.0 |awk -F':| ' '{print 5" "6}' > /sys/bus/pci/drivers/vfio-pci/new_id + ``` + + 将网卡绑定到 vfio-pci 驱动后,在主机上无法查询到对应网卡信息,只能查询到对应的 PCI 设备信息。 + +### VFIO 设备直通 + +#### 简介 + +VFIO(Virtual Function I/O) 是内核提供的一种用户态设备驱动方案。VFIO 驱动可以安全地把设备 I/O,中断,DMA 等能力呈现给用户空间。StratoVirt 虚拟化平台使用 VFIO 设备直通方案后,在虚拟机可以极大限度地提升 I/O 性能。 + +#### 使用 VFIO 直通 + +StratoVirt 支持 libvirt 管理,可以使用 XML 文件配置虚拟机。以下内容介绍通过修改虚拟机 XML 文件的方式,使用 VFIO 设备直通功能。 + +一、修改 XML 文件 + +1. 在主机上执行如下命令,查询 CPU 架构信息 + + ```shell + # uname -m + ``` + +2. aarch64 和 x86_64 架构分别[下载](https://gitee.com/openeuler/stratovirt/tree/master/docs) StratoVirt 自带的 XML 文件 stratovirt_aarch64.xml 或 stratovirtvirt_x86.xml,并存放到任一目录,例如 /home: + + ```shell + # cp stratovirt/docs/stratovirt_$arch.xml /home + ``` + +3. 根据实际需求,修改XML文件中的VFIO配置。 bus,slot,function 为上述绑定到 vfio-pci 驱动的 PCI 设备。相关配置如下: + + ```shell + + + + +
+ + + ``` + + 上例中,设备类型为 PCI 设备,managed='yes' 表示 libvirt 将把 PCI 设备从主机解绑,并重新绑定到 vfio-pci 驱动。source 项配置了需要作为 VFIO 直通设备的 domain,bus,slot,function 信息。 + +二、使用 libvirt 命令行创建并登录虚拟机 + +```shell +# virsh create stratovirt_$arch.xml +# virsh list --all +Id Name State +-------------------- +1 StratoVirt running +# virsh console 1 +``` + +三、在虚拟机内查看并使用 VFIO 直通网卡 + +1. 配置前查看网卡信息 + + ```shell + # ip a + 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + 2: enp1s0: mtu 1500 qdisc noop state DOWN group default qlen 1000 + link/ether 72:b8:51:9d:d1:27 brd ff:ff:ff:ff:ff:ff + ``` + +2. 动态配置网卡的 IP 地址 + + ```shell + # dhclient + ``` + +3. 查询 IP 是否配置成功 + + ```shell + # ip a + 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + 2: enp1s0: mtu 1500 qdisc mq state UP group default qlen 1000 + link/ether 72:b8:51:9d:d1:27 brd ff:ff:ff:ff:ff:ff + inet 192.168.1.3/16 brd 192.168.255.255 scope global dynamic enp1s0 + valid_lft 86453sec preferred_lft 86453sec + ``` + + 如上回显可知,成功分配了 IP 地址 192.168.1.3,虚拟机可以直接使用配置的网卡 + + 说明:使用的直通网卡如果没有连接物理网络,将获取不到网络信息。 + +#### 解绑 VFIO 驱动 + +如果需要将直通给虚拟机使用的网卡解除绑定,可以登录主机,执行如下命令,将网卡设备重新绑定到主机上。其中,hinic是对应网卡设备驱动的类型: + +```shell +# echo 0000:03:00.0 > /sys/bus/pci/drivers/vfio-pci/unbind +# echo 0000:03:00.0 > /sys/bus/pci/drivers/hinic/bind +``` + +说明:绑定 VFIO 驱动前,可以再主机上执行 ethtool -i enp0 命令,获取网卡设备驱动类型。enp0 为对应网卡名称。 + +### SR-IOV 直通 + +#### 简介 + +使用 VFIO 设备直通时,虚拟机能直接访问硬件,但每个设备只能被一个虚拟机独占。SR-IOV 直通技术支持将一个 PF(Physical Function) 虚拟出多个 VF (Virtual Function),并直通给不同虚拟机,解决了设备直通的独占问题,增加可用的设备。 + +#### 操作步骤 + +1. 创建多个 VF: + + sriov_numvfs 文件用于描述 SR-IOV 提供的 VF 个数,存放在 `/sys/bus/pci/devices/domain\:bus\:slot.function/` 路径下,例如上述例子中的 bus 号 03,slot 号 00,function 号 0 的设备,可以使用如下命令创建4个 VF: + + ```shell + # echo 4 > /sys/bus/pci/devices/0000\:03\:00.0/sriov_numvfs + ``` + +2. 确认 VF 设备创建成功 + + ```shell + # lspci -v | grep "Eth" | grep 1822 + ``` + + 回显如下,说明成功创建了4个 VF 03:00.1、03:00.2、03:00.3、03:00.4: + + ```shell + 03:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (4*25GE) (rev 45) + 03:00.1 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.2 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.3 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.4 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + ``` + +3. 上述创建的 VF 设备均可以直通给虚拟机,使用 SR-IOV 设备的方法与普通 PCI 设备的直通方法相同。 diff --git a/docs/zh/virtualization/virtualization_platform/stratovirt/vm_configuration.md b/docs/zh/virtualization/virtualization_platform/stratovirt/vm_configuration.md new file mode 100644 index 00000000..e8355ca8 --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/stratovirt/vm_configuration.md @@ -0,0 +1,686 @@ +# 虚拟机配置 + +## 概述 + +使用 StratoVirt 时,可以通过命令行参数指定虚拟机配置,也支持对接 libvirt ,通过 XML 文件配置。本章介绍命令行方式的配置方式。 + +> [!NOTE]说明 +> +> 本文中的 /path/to/socket 为用户自定义路径下的 socket 文件。 +> +> 从 openEuler 21.09 版本开始,取消了对 json 文件的支持。 + +## 规格说明 + +StratoVirt 支持启动轻量级虚拟机和标准虚拟机。 + +- 轻量级虚拟机使用轻量级 microVM 主板,以及 mmio 总线。 +- 标准虚拟机支持标准启动,在 x86 平台使用 Q35 主板,AArch64 架构下使用 virt 主板以及 PCI 总线。 + +### 轻量级虚拟机 + +- 虚拟机 CPU 个数:[1, 254] +- 虚拟机内存大小:[128 MiB, 512 GiB],默认内存配置256MiB +- 虚拟机磁盘个数(包括热插的磁盘):[0, 6] +- 虚拟机网卡个数(包括热插的网卡):[0, 2] +- 虚拟机 console 设备仅支持单路连接 +- 主机 CPU 架构为 x86_64 时,最多可以配置 11 个 mmio 设备,但是除了磁盘和网卡,建议最多配置 2 个其他设备; AArch64 平台,最多可以配置 160 个 mmio 设备,但是除了磁盘和网卡,建议最多配置 12 个其他设备。 + +### 标准虚拟机 + +- 虚拟机 CPU 个数:[1, 254] +- 虚拟机内存大小:[128 MiB, 512 GiB],默认内存配置256MiB +- 虚拟机 console 设备仅支持单路连接 +- 只支持 1 个 console 设备 +- 最多支持 32 个 PCI 设备 +- PCI 设备挂载的 PCI 总线 slot 取值范围: [0, 32);function 取值范围 [0, 8) + +## 最小配置 + +StratoVirt 能够运行的最小配置为: + +- PE 格式或 bzImage 格式(仅 x86_64)的 Linux 内核镜像 +- 将 rootfs 镜像设置成 virtio-blk 设备,并添加到内核参数中 +- 使用 QMP 控制 StratoVirt +- 如果要使用串口登录,添加一个串口到内核启动命令行,AArch64平台标准机型为ttyAMA0,其他情况为ttyS0. + +## 配置介绍 + +### **命令格式** + +使用 cmdline 配置的命令格式如下: + +**$ /path/to/stratovirt** *-[参数1] [参数选项] -[参数2] [参数选项] ...* + +### **使用说明** + +1. 首先,为确保可以创建 QMP 需要的 socket,可以参考如下命令清理环境: + + ```sh + # rm [参数] [用户自定义socket文件路径] + ``` + +2. 然后,运行 cmdline 命令。 + + ```sh + # /path/to/stratovirt -[参数1] [参数选项] -[参数2] [参数选项] ... + ``` + +### 基本信息配置 + +基本配置信息如下表所示: + +| 参数 | 参数选项 | 说明 | +| ---------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| -name | *VMname* | 配置虚拟机名称(字符长度:1-255字符) | +| -kernel | /path/to/vmlinux.bin | 配置内核镜像 | +| -append | console=ttyS0 root=/dev/vda reboot=k panic=1 rw | 配置内核命令行参数,轻量级虚拟机固定配置为console=ttyS0(与架构平台无关)。标准虚拟化X86_64平台默认使用console=ttyS0,AArch64平台默认使用console=ttyAMA0。在配置了virtio-console设备但是没有配置serial串口设备时,需要配置为console=hvc0(与架构平台无关) | +| -initrd | /path/to/initrd.img | 配置initrd文件 | +| -smp | [cpus=]n[,maxcpus=,sockets=,dies=,clusters=,cores=,threads=] | cpus:配置cpu个数,范围[1, 254]。maxcpus:最大cpu个数,范围[1,254]。sockets:socket的个数,如果不设置它的值依赖于maxcpus;die:die的个数;cluster:cluster的个数;core:core的个数,如果不设置它的值依赖于maxcpus;thread:thread的个数,如果不设置它的值依赖于maxcpus;maxcpus=sockets *dies* clusters *cores* threads | +| -m | 内存大小MiB、内存大小GiB,默认单位MiB | 配置内存大小,范围[128 MiB, 512 GiB],默认内存配置256MiB | +| -qmp | unix:/path/to/socket,server,nowait | 配置QMP,运行前须保证socket文件不存在 | +| -D | /path/to/logfile | 配置日志文件 | +| -pidfile | /path/to/pidfile | 配置pid文件,必须和-daemonize一起使用。运行前须保证pid文件不存在 | +| -disable-seccomp | NA | 关闭Seccomp,默认打开 | +| -daemonize | NA | 开启进程daemon化 | + +### 虚拟机类型 + +通过-machine参数来指定启动的虚拟机的类型。 + +参数说明 + +- type:启动虚拟机的类型(轻量级虚拟化为“MicroVm”类型,标准虚拟化在x86_64平台为”q35“,在aarch64平台为”virt”)。 +- dump-guest-core:进程panic时,是否dump虚拟机内存(可选配置)。 +- mem-share:是否与其他进程共享内存(可选配置)。 + +### 磁盘配置 + +虚拟机磁盘配置包含以下配置项 + +- drive_id: 磁盘的id。 +- path_on_host: 磁盘的路径。 +- serial_num: 磁盘的串号(可选配置)。 +- read_only: 是否只读(可选配置)。 +- direct: 是否以“O_DIRECT”模式打开(可选配置)。 +- iothread: 配置iothread属性(可选配置)。 +- throttling.iops-total: 配置磁盘QoS,以限制磁盘的io操作(可选配置)。 +- if:driver的类型,block设备为“none”(可选配置,缺省值为“none”) +- bus:设备要挂载的bus。 +- addr:设备要挂载的slot和function号。 +- multifunction:是否开启pci多功能。(可选配置) +- bootindex:配置启动优先级属性,如果没有设置,默认最低优先级。配置范围从0到255,数字越小,优先级越高。(可选配置,只支持标准机型) + +#### 磁盘配置方式 + +磁盘的配置分为两步:driver的配置和block设备的配置 + +轻量虚拟机配置格式为: + +```Conf +-drive id=drive_id,file=path_on_host[,readonly=off][,direct=off][,throttling.iops-total=200][,if=none] +-device virtio-blk-device,drive=drive_id[,iothread=iothread1][,serial=serial_num] +``` + +标准虚拟机配置格式为: + +```Conf +-drive id=drive_id,file=path_on_host[,readonly=off][,direct=off][,throttling.iops-total=200][,if=none] +-device virtio-blk-pci,drive=drive_id,bus=pcie.0,addr=0x3.0x0[,iothread=iothread1,][serial=serial_num][,multifunction=on][,bootindex=1] +``` + +下面对throttling.iops-total和iothread两个配置项进行详细说明: + +#### 磁盘QoS + +##### 简介 + +QoS(Quality of Service)是服务质量的意思。在云场景中,单主机内会启动多台虚拟机,当某台虚拟机对磁盘访问压力大时,由于同主机的磁盘访问总带宽有限,这会挤占其他虚拟机的访问带宽,从而造成对其他虚拟机IO影响。为了降低影响,可以为虚拟机配置QoS属性,限制它们对磁盘访问的速率,从而降低对彼此的影响。 + +##### 注意事项 + +- 当前QoS支持配置磁盘的iops。 +- iops的设定范围是[0, 1000000],0为不限速;实际iops不会超过设定值,并且不会超过后端磁盘实际性能的上限。 +- 只能限制平均iops,无法限速瞬时的突发流量。 + +##### 配置方式 + +用法: + +**命令行** + +```Conf +-drive xxx,throttling.iops-total=200 +``` + +参数: + +- throttling.iops-total:当配置了iops后,本磁盘在虚拟机内部的IO下发速度,不会超过此配置值。 +- xxx:表示磁盘的其他设置。 + +#### iothread + +iothread配置细节见[iothread配置](#iothread配置) + +### 网卡配置 + +虚拟机网卡的配置包含以下配置项: + +- id:唯一的设备 id。 +- tap:指定 tap 设备。 +- ifname:host 上的 tap 设备名。 +- mac:设置虚拟机 mac 地址(可选配置)。 +- iothread:配置磁盘的 iothread 属性(可选配置)。网卡 iothread 配置详见 [iothread配置](#iothread配置) 。 + +#### 配置方式 + +> [!NOTE]说明 +> +> 使用网络前请先使用如下命令配置好 host 网桥和 tap 设备。 +> +> ```sh +> # brctl addbr qbr0 +> # ip tuntap add tap0 mode tap +> # brctl addif qbr0 tap0 +> # ifconfig qbr0 up; ifconfig tap0 up +> # ifconfig qbr0 192.168.0.1 +> ``` + +1. 配置 virtio-net(本文中 [] 表示可选参数) + + 轻量级虚拟机: + + ```Conf + -netdev tap,id=netdevid,ifname=host_dev_name[,vhostfd=2] + -device virtio-net-device,netdev=netdevid,id=netid[,iothread=iothread1,mac=12:34:56:78:9A:BC] + ``` + + 标准虚拟机: + + ```Conf + -netdev tap,id=netdevid,ifname=host_dev_name[,vhostfd=2] + -device virtio-net-pci,netdev=netdevid,id=netid,bus=pcie.0,addr=0x2.0x0[,multifunction=on,iothread=iothread1,mac=12:34:56:78:9A:BC] + ``` + +2. 配置 vhost-net + + 轻量级虚拟机: + + ```Conf + -netdev tap,id=netdevid,ifname=host_dev_name,vhost=on[,vhostfd=2] + -device virtio-net-device,netdev=netdevid,id=netid[,iothread=iothread1,mac=12:34:56:78:9A:BC] + ``` + + 标准虚拟机: + + ```Conf + -netdev tap,id=netdevid,ifname=host_dev_name,vhost=on[,vhostfd=2] + -device virtio-net-pci,netdev=netdevid,id=netid,bus=pcie.0,addr=0x2.0x0[,multifunction=on,iothread=iothread1,mac=12:34:56:78:9A:BC] + ``` + +### chardev 配置 + +将来自 Guest 的 I/O 重定向到宿主机的 chardev。chardev 后端的类型可以是:stdio、pty、socket 和 file。其中 file 仅支持输出时设置。配置项: + +- id:唯一的设备 id。 +- backend:重定向的类型。 +- path:设备重定向文件路径。仅 socket 和 file 类型的设备需要此参数。 +- server:将 chardev 作为服务器运行。仅 socket 类型的设备需要此参数。 +- nowait:预期状态为断开连接。仅 socket 类型的设备需要此参数。 + +使用 chardev 时,会创建并使用 console 文件,所以启动 stratovirt 之前,请确保 console 文件不存在。 + +#### 配置方式 + +```Conf +-chardev backend,id=chardev_id[,path=path,server,nowait] +``` + +### 串口配置 + +串口是虚拟机的设备,用于主机和虚拟机之间传送数据。使用串口时,kernel 命令行中配置 console=ttyS0 ,在 AArch64 平台上标准启动时,配置 console=ttyAMA0 。配置项: + +- chardev:重定向的 chardev 设备 +- backend、path、server、nowait:这些参数的含义与 chardev 中的相同。 + +#### 配置方式 + +```Conf +-serial chardev:chardev_id +``` + +或者: + +```Conf +-chardev backend[,path=path,server,nowait] +``` + +### console 设备配置 + +virtio-console 是通用的串口设备,用于主机和虚拟机之间传送数据。当只配 console 并通过 console 进行 I/O 操作时,kernel 启动参数中配置 console=hvc0。console 设备有如下配置项: + +- id: 设备的 id。 +- path:virtio console 文件路径。 +- socket:以 socket 的方式重定向。 +- chardev:重定向的 chardev 设备。 + +#### 配置方式 + +console 配置分为三步:首先指定 virtio-serial,然后创建字符设备,最后创建 virtconsole 设备。 + +轻量级虚拟机: + +```Conf +-device virtio-serial-device[,id=virtio-serial0] +-chardev socket,path=socket_path,id=virtioconsole1,server,nowait +-device virtconsole,chardev=virtioconsole1,id=console_id +``` + +标准虚拟机: + +```Conf +-device virtio-serial-pci,bus=pcie.0,addr=0x1.0x0[,multifunction=on,id=virtio-serial0] +-chardev socket,path=socket_path,id=virtioconsole1,server,nowait +-device virtconsole,chardev=virtioconsole1,id=console_id +``` + +### vsock 设备配置 + +vsock 也是主机和虚拟机之间通信的设备,类似于 console,但具有更好的性能。配置项: + +- id: 唯一的设备 id。 +- guest_cid: 唯一的 context id 。 + +#### 配置方式 + +轻量级虚拟机: + +```Conf +-device vhost-vsock-device,id=vsock_id,guest-cid=3 +``` + +标准虚拟机: + +```Conf +-device vhost-vsock-pci,id=vsock_id,guest-cid=3,bus=pcie.0,addr=0x1.0x0[,multifunction=on] +``` + +### 内存大页配置 + +#### 概述 + +StratoVirt 支持为虚拟机配置内存大页,相比传统的 4KiB 内存分页模式,大页内存可以有效减少 TLB Miss 次数和缺页中断次数,能够显著提升内存密集型业务性能。 + +#### 注意事项 + +- 指定的大页挂载的目录,必须是绝对路径。 +- 仅支持在启动时配置。 +- 仅支持静态大页。 +- 使用大页前, 在Host上需要配置好大页。 +- 使用大页特性, 指定虚拟机内存规格必须是**大页页面大小的整数倍**。 + +#### 互斥特性 + +- 内存大页和 ballon 特性互斥,同时配置时,balloon 特性无效。 + +#### 配置方式 + +##### 配置Host上大页 + +###### 挂载 + +将大页文件系统挂载到指定目录上,其中 `/path/to/hugepages`为用户自定义的空目录。 + +```sh +# mount -t hugetlbfs hugetlbfs /path/to/hugepages +``` + +###### 设置大页数目 + +- 设置静态大页数目, `num`为指定的大页数目 + + ```sh + # sysctl vm.nr_hugepages=num + ``` + +- 查询大页统计信息 + + ```sh + # cat /proc/meminfo | grep Hugepages + ``` + + 如果需要查看其他页面大小的大页统计信息, 可以查看 `/sys/kernel/mm/hugepages/hugepages-*/`目录下相关信息。 + +> [!NOTE]说明 +> +> 请根据大页使用情况,配置StratoVirt内存规格和大页。如果大页资源不足,虚拟机会启动失败。 + +#### 启动StratoVirt时添加大页配置 + +- 命令行 + + ```Conf + -mem-path /page/to/hugepages + ``` + + 其中 `/page/to/hugepages`为大页文件系统挂载的目录,仅支持绝对路径。 + +> [!NOTE]说明 +> +> **典型配置:**指定StratoVirt命令行中的mem-path项为:**大页文件系统挂载的目录**。 推荐使用典型配置使用StratoVirt大页特性。 + +### 配置iothread + +#### 简介 + +当StratoVirt启动了带iothread配置的虚拟机后,会在主机上启动独立于主线程的单独线程,这些单独线程可以用来处理设备的IO请求,一方面提升设备的IO性能,另一方面降低对管理面消息处理的影响。 + +#### 注意事项 + +- 支持配置最多8个iothread线程 +- 支持磁盘和网卡配置iothread属性 +- iothread线程会占用主机CPU资源,在虚拟机内部大IO压力情况下,单个iothread占用的CPU资源取决于磁盘的访问速度,例如普通的SATA盘会占用20%以内CPU资源。 + +#### 创建iothread线程 + +**命令行:** + +```shell +-object iothread,id=iothread1 -object iothread,id=iothread2 +``` + +参数: + +- id:用于标识此iothread线程,该id可以被设置到磁盘或网卡的iothread属性。当启动参数配置了iothread线程信息,虚拟机启动后会在主机上启动相应id名的线程。 + +#### 配置磁盘或网卡的iothread属性 + +**命令行配置** + +轻量虚拟机: + +磁盘 + +```Conf +-device virtio-blk-device xxx,iothread=iothread1 +``` + +网卡 + +```Conf +-device virtio-net-device xxx,iothread=iothread2 +``` + +标准虚拟机: + +磁盘 + +```Conf +-device virtio-blk-pci xxx,iothread=iothread1 +``` + +网卡 + +```Conf +-device virtio-net-pci xxx,iothread=iothread2 +``` + +参数: + +1. iothread:设置成 iothread 线程的 id,指明处理本设备 I/O 的线程。 +2. xxx: 表示磁盘或者网卡的其他配置 + +### 配置balloon设备 + +#### 简介 + +在虚拟机运行过程中,由虚拟机里的balloon驱动来动态占用或释放内存,从而动态改变这台虚拟机当前可用内存,达到内存弹性的效果。 + +#### 注意事项 + +- 启用balloon前须确保guest和host的页面大小相同。 +- guest内核须开启balloon特性支持。 +- 开启内存弹性时,有可能造成虚拟机内部轻微卡顿、内存性能下降。 + +#### 互斥特性 + +- 大页内存互斥。 +- 在x86下,由于中断数量有限,所以balloon设备和其他virtio的数量(默认使用6个block设备,2个net设备和1个串口设备)总和不得超过11个。 + +#### 规格 + +- 每个VM只能配置1个balloon设备。 + +#### 配置方式 + +轻量级虚拟机: + +```Conf +-device virtio-balloon-device[,deflate-on-oom=true|false][,free-page-reporting=true|false] +``` + +标准虚拟机: + +```Conf +-device virtio-balloon-pci,bus=pcie.0,addr=0x4.0x0[,deflate-on-oom=true|false][,free-page-reporting=true|false][,multifunction=on|off] +``` + +[!NOTE]说明 + +1. deflate-on-oom的取值为bool类型,表示是否开启auto deflate特性。开启时,如果balloon已经回收部分内存,当guest需要内存时,balloon设备会自动放气,归还内存给guest。不开启则不会自动归还。 +2. free-page-reporting的取值为bool类型,表示是否开启free page reporting特性。开启时,如果guest内核向balloon设备发送了free pages,balloon将释放free pages所占用的内存。不开启则guest内核不会向balloon设备发送free pages。 +3. 使用qmp命令回收虚拟机内存时,应确保回收后虚拟机仍然有足够的内存来保持最基本的运行。否则可能会出现一些操作超时,以及导致虚拟机内部无法申请到空闲内存等现象。 +4. 如果虚拟机内部开启内存大页,balloon不能回收大页占用内存。 + +> deflate-on-oom=false时,当Guest中内存不足时,balloon不会自动放气并归还内存,可能会引起Guest内部OOM,进程被Kill,甚至虚拟机无法正常运行。 + +### 配置RNG设备 + +#### 简介 + +Virtio RNG是半虚拟化的随机数生成器设备,用于为guest提供硬件随机数生成能力。 + +#### 配置方式 + +Virtio RNG可配置为Virtio mmio设备或者virtio PCI设备,Virtio RNG配置为Virtio mmio设备时,命令行参数如下: + +```Conf +-object rng-random,id=objrng0,filename=/path/to/random_file +-device virtio-rng-device,rng=objrng0,max-bytes=1234,period=1000 +``` + +Virtio RNG配置为Virtio PCI设备时,命令行参数如下: + +```Conf +-object rng-random,id=objrng0,filename=/path/to/random_file +-device virtio-rng-pci,rng=objrng0,max-bytes=1234,period=1000,bus=pcie.0,addr=0x1.0x0,id=rng-id[,multifunction=on] +``` + +参数: + +- filename:在host上用于生成随机数的字符设备路径,例如/dev/random; +- period:限制随机数字符速率的定时周期,单位为毫秒; +- max-bytes:在period时间内字符设备生成随机数的最大字节数; +- bus:Virtio RNG设备挂载的总线名称; +- addr:Virtio RNG设备地址,参数格式为addr=[slot].[function],分别表示设备的slot号和function号,均使用十六进制表示,其中Virtio RNG设备的function号为0x0。 + +#### 注意事项 + +- 如不配置period和max-bytes,则不对随机数字符读取速率进行限制; +- 如配置限速,则max-bytes/period\*1000的设定范围为[64, 1000000000],建议不应设置过小,以防获取随机数字符速率过慢; +- 只能限制平均随机数字符数,无法限制瞬间的突发流量; +- guest如需使用Virtio RNG设备,guest内核需要使能配置:CONFIG_HW_RANDOM=y,CONFIG_HW_RANDOM_VIA=y,CONFIG_HW_RANDOM_VIRTIO=y; +- 用户在配置Virtio RNG设备时,请检查熵池是否足够,以免引起虚拟机卡顿问题,例如配置字符设备路径为/dev/random,当前熵池大小可通过/proc/sys/kernel/random/entropy_avail查看,熵池满时的大小为4096,通常应该大于1000。 + +### 配置VNC + +#### 简介 + +用户可以通过VNC客户端登录虚拟机,输入鼠标键盘事件,并通过VNC显示的桌面完成与远程虚拟机系统的交互。 + +#### 注意事项 + +- 当前只有标准虚拟机支持VNC特性。 +- 目前只支持RFB3.3-3.8版本客户端连接。 +- 目前只支持单个客户端连接,暂不支持多个客户端同时连接。多个客户端连接会返回连接失败。 +- 目前仅支持在ARM环境上使用。 + +#### 互斥特性 + +- VNC特性暂不支持热迁移。 + +#### 规格 + +- 每个虚拟机只支持配置一个VNC Server。 + +#### 配置方式 + +标准虚拟机: + +```shell +-vnc 0.0.0.0:11 +``` + +[!NOTE]说明 + +1. 图像渲染用到`pixman`库,需要在虚拟机运行环境中安装`pixman.rpm`和`pixman-devel.rpm`两个包。 +2. 鼠标键盘输入需要配置一个`USB`控制器,以及鼠标键盘设备。 +3. 需要配置一个显示设备,如`virtio-gpu`、`ramfb`。 + +### 配置 USB 键盘和 USB 鼠标 + +#### 简介 + +StratoVirt 支持配置 USB 键盘和 USB 鼠标,用户可以通过 VNC 远程连接虚拟机,通过 USB 键盘鼠标对虚拟机进行图形化操作。USB 设备需要挂载在 USB 控制器上,因此需要提前在命令行里配置 USB 控制器。 + +#### 注意事项 + +- 当前只有标准虚拟机支持 USB 键盘鼠标。 + +#### 互斥特性 + +- USB 键盘鼠标暂不支持热迁移。 + +#### 规格 + +- 每个 VM 只能配置 1 个 USB 控制器 +- 每个 VM 只能配置 1 个 USB 键盘 +- 每个 VM 只能配置 1 个 USB 鼠标 + +#### 配置方式 + +USB 控制器在启动 StratoVirt 时命令行配置: + +```Conf +-device nec-usb-xhci,id=xhci,bus=pcie.0,addr=0xa.0x0 +``` + +参数: + +- id:唯一的设备 id。 +- bus:设备要挂载的 bus。 +- addr:设备要挂载的 slot 和 function 号。 + +注意需要合理配置设备的 bus 和 addr 参数,不能和其他配置的 PCI 设备冲突,否则可能会导致虚拟机启动失败。 + +USB 键盘在启动 StratoVirt 时命令行配置: + +```Conf +-device usb-bkd,id=kbd +``` + +参数: + +- id:唯一的设备 id。 + +USB 鼠标在启动 StratoVirt 时命令行配置: + +```Conf +-device usb-tablet,id=tablet +``` + +参数: + +- id:唯一的设备 id。 + +### 配置virtio-gpu设备 + +#### 简介 + +标准虚拟机可支持配置virtio-gpu显卡用于显示。 + +#### 注意事项 + +- 目前仅支持2D。 +- max_hostmem(即在host侧可占用内存)建议不小于256MiB,否则影响分辨率配置。 +- max_outputs(即支持的屏幕数量)配置不可大于16。 +- 不支持热迁移。 + +#### 规格 + +- 每个VM只能配置1个virtio-gpu设备。 + +#### 配置方式 + +标准虚拟机: + +```Conf +-device virtio-gpu-pci,id=XX,bus=pcie.0,addr=0x2.0x0[,max_outputs=XX][,edid=true|false][,xres=XX][,yres=XX][,max_hostmem=XX] +``` + +参数: + +1. max_outputs:当前显卡需要支持的屏幕数量,建议配置为1,最大值不超过16。 +2. edid:当前显卡是否支持edid,建议配置为true,虚拟机内核会检查显卡是否支持edid。 +3. xres/yres:登录窗口的横向/纵向大小。 +4. max_hostmem: 显卡最大可占用host侧内存, 以Byte为单位。 + +## 配置示例 + +### 轻量级虚拟机 + +此处给出创建一个轻量级虚拟机的最小配置示例。 + +1. 登录主机,删除 socket 文件,确保可以创建 QMP。 + + ```sh + # rm -f /tmp/stratovirt.socket + ``` + +2. 运行 StratoVirt 。 + + ```sh + # /path/to/stratovirt \ + -kernel /path/to/vmlinux.bin \ + -append console=ttyS0 root=/dev/vda rw reboot=k panic=1 \ + -drive file=/home/rootfs.ext4,id=rootfs,readonly=false \ + -device virtio-blk-device,drive=rootfs \ + -qmp unix:/tmp/stratovirt.socket,server,nowait \ + -serial stdio + ``` + + 运行成功后,将根据指定的配置参数创建并启动虚拟机。 + +### 标准虚拟机 + +此处给出在 ARM 平台创建一个标准虚拟机的最小配置示例。 + +1. 删除 socket 文件,确保可以创建 QMP 。 + + ```sh + # rm -f /tmp/stratovirt.socket + ``` + +2. 运行 StratoVirt 。 + + ```sh + # /path/to/stratovirt \ + -kernel /path/to/vmlinux.bin \ + -append console=ttyAMA0 root=/dev/vda rw reboot=k panic=1 \ + -drive file=/path/to/edk2/code_storage_file,if=pflash,unit=0[,readonly=true] \ + -drive file=/path/to/edk2/data_storage_file,if=pflash,unit=1, \ + -drive file=/home/rootfs.ext4,id=rootfs,readonly=false \ + -device virtio-blk-device,drive=rootfs,bus=pcie.0,addr=0x1 \ + -qmp unix:/tmp/stratovirt.socket,server,nowait \ + -serial stdio + ``` diff --git a/docs/zh/virtualization/virtualization_platform/stratovirt/vm_management.md b/docs/zh/virtualization/virtualization_platform/stratovirt/vm_management.md new file mode 100644 index 00000000..939fcb18 --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/stratovirt/vm_management.md @@ -0,0 +1,741 @@ +# 管理虚拟机 + +## 概述 + +StratoVirt可以查询虚拟机信息并对虚拟机的资源和生命周期进行管理。由于StratoVirt使用QMP管理虚拟机,所以查询虚拟机信息,也需要先连接到虚拟机。 + +## 查询虚拟机信息 + +### 简介 + +StratoVirt可以查询虚拟机状态、vCPU拓扑信息、vCPU上线情况等。 + +### 查询状态 + +使用query-status命令查询虚拟机的运行状态。 + +- 用法: + + **{ "execute": "query-status" }** + +- 示例: + +```shell +<- { "execute": "query-status" } +-> { "return": { "running": true,"singlestep": false,"status": "running" } +``` + +### 查询拓扑 + +使用query-cpus命令查询所有CPU的拓扑结构。 + +- 用法: + +**{ "execute": "query-cpus" }** + +- 示例: + +```shell +<- { "execute": "query-cpus" } +-> {"return":[{"CPU":0,"arch":"x86","current":true,"halted":false,"props":{"core-id":0,"socket-id":0,"thread-id":0},"qom_path":"/machine/unattached/device[0]","thread_id":8439},{"CPU":1,"arch":"x86","current":true,"halted":false,"props":{"core-id":0,"socket-id":1,"thread-id":0},"qom_path":"/machine/unattached/device[1]","thread_id":8440}]} +``` + +### 查询vCPU上线情况 + +使用query-hotpluggable-cpus命令查询所有vCPU的online/offline情况。 + +- 用法: + +**{ "execute": "query-hotpluggable-cpus" }** + +- 示例: + +```shell +<- { "execute": "query-hotpluggable-cpus" } +-> {"return":[{"props":{"core-id":0,"socket-id":0,"thread-id":0},"qom-path":"/machine/unattached/device[0]","type":"host-x86-cpu","vcpus-count":1},{"props":{"core-id":0,"socket-id":1,"thread-id":0},"qom-path":"/machine/unattached/device[1]","type":"host-x86-cpu","vcpus-count":1}]} +``` + +其中,online的vCPU具有`qom-path`项,offline的vCPU则没有。 + +## 管理虚拟机生命周期 + +### 简介 + +StratoVirt可以对虚拟机进行启动、暂停、恢复、退出等生命周期进行管理。 + +### 创建并启动虚拟机 + +通过命令行参数指定虚拟机配置,创建并启动虚拟机。 + +- 使用命令行参数给出虚拟机配置,创建并启动虚拟机的命令如下: + +```shell +$ /path/to/stratovirt -[参数1] [参数选项] -[参数2] [参数选项] ... +``` + +> [!NOTE]说明 +> +> 轻量虚拟启动后,内部会有eth0和eth1两张网卡。这两张网卡预留用于网卡热插拔。热插的第一张网卡是eth0,热插的第二张网卡是eth1,目前只支持热插两张virtio-net网卡。 + +### 连接虚拟机 + +StratoVirt当前采用QMP管理虚拟机,暂停、恢复、退出虚拟机等操作需要通过QMP连接到虚拟机进行管理。 + +在主机上打开新的命令行窗口B,并使用root权限进行api-channel连接,参考命令如下: + +```shell +# ncat -U /path/to/socket +``` + +连接建立后,会收到来自StratoVirt的问候消息,如下所示: + +```shell +{"QMP":{"version":{"qemu":{"micro":1,"minor":0,"major":4},"package":""},"capabilities":[]}} +``` + +现在,可以在窗口B中输入QMP命令来管理虚拟机。 + +> [!NOTE]说明 +> +> QMP提供了stop、cont、quit和query-status等来管理和查询虚拟机状态。 +> +> 管理虚拟机的QMP命令均在窗口B中进行输入。符号:`<-`表示命令输入,`->`表示QMP结果返回。 + +### 暂停虚拟机 + +QMP提供了stop命令用于暂停虚拟机,即暂停虚拟机所有的vCPU。命令格式如下: + +**{"execute":"stop"}** + +**示例:** + +使用stop暂停该虚拟机的命令和回显如下: + +```shell +<- {"execute":"stop"} +-> {"event":"STOP","data":{},"timestamp":{"seconds":1583908726,"microseconds":162739}} +-> {"return":{}} +``` + +### 恢复虚拟机 + +QMP提供了cont命令用于恢复处于暂停状态suspend的虚拟机,即恢复虚拟机所有vCPU的运行。命令格式如下: + +**{"execute":"cont"}** + +**示例:** + +使用cont恢复该虚拟机的命令和回显如下: + +```shell +<- {"execute":"cont"} +-> {"event":"RESUME","data":{},"timestamp":{"seconds":1583908853,"microseconds":411394}} +-> {"return":{}} +``` + +### 退出虚拟机 + +QMP提供了quit命令用于退出虚拟机,即退出StratoVirt进程。命令格式如下: + +**{"execute":"quit"}** + +**示例:** + +```shell +<- {"execute":"quit"} +-> {"return":{}} +-> {"event":"SHUTDOWN","data":{"guest":false,"reason":"host-qmp-quit"},"timestamp":{"ds":1590563776,"microseconds":519808}} +``` + +## 管理虚拟机资源 + +### 热插拔磁盘 + +StratoVirt支持在虚拟机运行过程中调整磁盘数量,即在不中断业务前提下,增加或删除虚拟机磁盘。 + +**注意事项** + +- 对于标准机型,需要虚拟机内核开启 CONFIG_HOTPLUG_PCI_PCIE=y 配置。 + +- 对于标准机型,目前支持热插拔设备到 Root Port 设备,Root Port 设备需要在虚拟机启动前配置。 + +- 不建议在虚拟机启动、关闭、内部高压力等状态下进行设备热插拔,可能会因为虚拟机内驱动没有及时响应导致虚拟机出现异常。 + +#### 热插磁盘 + +**用法:** + +轻量机型: + +```shell +{"execute": "blockdev-add", "arguments": {"node-name": "drive-0", "file": {"driver": "file", "filename": "/path/to/block"}, "cache": {"direct": true}, "read-only": false}} +{"execute": "device_add", "arguments": {"id": "drive-0", "driver": "virtio-blk-mmio", "addr": "0x1"}} +``` + +标准机型: + +```shell +{"execute": "blockdev-add", "arguments": {"node-name": "drive-0", "file": {"driver": "file", "filename": "/path/to/block"}, "cache": {"direct": true}, "read-only": false}} +{"execute":"device_add", "arguments":{"id":"drive-0", "driver":"virtio-blk-pci", "drive": "drive-0", "addr":"0x0", "bus": "pcie.1"}} +``` + +**参数** + +- 对于轻量机型,blockdev-add 中的 node-name 要和 device_add 中的 id 一致,如上都是 drive-0。 + +- 对于标准机型 drive 参数需要和 blockdev-add 中的 node-name 一致。 + +- /path/to/block 是被热插磁盘的镜像路径,不能是启动 rootfs 的磁盘镜像。 + +- 对于轻量机型,addr 参数从 0x0 开始与虚拟机的 vda 映射,0x1 与 vdb 映射,以此类推。为了兼容 QMP 协议,"addr" 也可以用 "lun" 代替,但是 lun=0 与客户机的 vdb 映射。对于标准机型,目前 addr 参数需要指定为 0x0。 + +- 对于标准机型,bus 为设备要挂载的总线名称,目前只支持热插到 Root Port 设备,需要和 Root Port 的 id 保持一致。 + +- 对于轻量机型,StratoVirt 支持的最大 virtio-blk 磁盘数量是6个,热插磁盘时请注意规格约束。对于标准机型,热插磁盘的数量取决于 Root Port 设备的数量。 + +**示例** + +轻量机型: + +```shell +<- {"execute": "blockdev-add", "arguments": {"node-name": "drive-0", "file": {"driver": "file", "filename": "/path/to/block"}, "cache": {"direct": true}, "read-only": false}} +-> {"return": {}} +<- {"execute": "device_add", "arguments": {"id": "drive-0", "driver": "virtio-blk-mmio", "addr": "0x1"}} +-> {"return": {}} +``` + +标准机型: + +```shell +<- {"execute": "blockdev-add", "arguments": {"node-name": "drive-0", "file": {"driver": "file", "filename": "/path/to/block"}, "cache": {"direct": true}, "read-only": false}} +-> {"return": {}} +<- {"execute":"device_add", "arguments":{"id":"drive-0", "driver":"virtio-blk-pci", "drive": "drive-0", "addr":"0x0", "bus": "pcie.1"}} +-> {"return": {}} +``` + +#### 热拔磁盘 + +**用法:** + +轻量机型: + +```shell +{"execute": "device_del", "arguments": {"id":"drive-0"}} +``` + +标准机型: + +```shell +{"execute": "device_del", "arguments": {"id":"drive-0"}} +{"execute": "blockdev-del", "arguments": {"node-name": "drive-0"}} +``` + +**参数:** + +- id 为热拔磁盘的 ID 号。 +- node-name 为磁盘后端名称。 + +**示例** + +轻量机型: + +```shell +<- {"execute": "device_del", "arguments": {"id": "drive-0"}} +-> {"event":"DEVICE_DELETED","data":{"device":"drive-0","path":"drive-0"},"timestamp":{"seconds":1598513162,"microseconds":367129}} +-> {"return": {}} +``` + +标准机型: + +```shell +<- {"execute": "device_del", "arguments": {"id":"drive-0"}} +-> {"return": {}} +-> {"event":"DEVICE_DELETED","data":{"device":"drive-0","path":"drive-0"},"timestamp":{"seconds":1598513162,"microseconds":367129}} +<- {"execute": "blockdev-del", "arguments": {"node-name": "drive-0"}} +-> {"return": {}} +``` + +当收到 DEVICE_DELETED 事件时,表示设备在 StratoVirt 侧被移除。 + +### 热插拔网卡 + +StratoVirt支持在虚拟机运行过程中调整网卡数量,即在不中断业务前提下,给虚拟机增加或删除网卡。 + +**注意事项** + +- 对于标准机型,需要虚拟机内核开启 CONFIG_HOTPLUG_PCI_PCIE=y 配置。 + +- 对于标准机型,目前支持热插拔设备到 Root Port 设备,Root Port 设备需要在虚拟机启动前配置。 + +- 不建议在虚拟机启动、关闭、内部高压力等状态下进行设备热插拔,可能会因为虚拟机内驱动没有及时响应导致虚拟机出现异常。 + +#### 热插网卡 + +**准备工作(需要使用root权限)** + +1. 创建并启用Linux网桥,例如网桥名为 qbr0 的参考命令如下: + + ```shell + # brctl addbr qbr0 + # ifconfig qbr0 up + ``` + +2. 创建并启用 tap 设备,例如设备名为 tap0 的参考命令如下: + + ```shell + # ip tuntap add tap0 mode tap + # ifconfig tap0 up + ``` + +3. 添加 tap 设备到网桥: + + ```shell + # brctl addif qbr0 tap0 + ``` + +**用法** + +轻量机型: + +```shell +{"execute":"netdev_add", "arguments":{"id":"net-0", "ifname":"tap0"}} +{"execute":"device_add", "arguments":{"id":"net-0", "driver":"virtio-net-mmio", "addr":"0x0"}} +``` + +标准机型: + +```shell +{"execute":"netdev_add", "arguments":{"id":"net-0", "ifname":"tap0"}} +{"execute":"device_add", "arguments":{"id":"net-0", "driver":"virtio-net-pci", "addr":"0x0", "netdev": "net-0", "bus": "pcie.1"}} +``` + +**参数** + +- 对于轻量机型,netdev_add 中的 id 应该和 device_add 中的 id 一致,ifname 是后端的 tap 设备名称。 + +- 对于标准机型,netdev 参数需要和 netdev_add 中的 id 一致。 + +- 对于轻量机型,addr 参数从 0x0 开始与虚拟机的 eth0 映射,0x1 和虚拟机的 eth1 映射。对于标准机型,目前 addr 参数需要指定为 0x0。 + +- 对于标准机型,bus 为设备要挂载的总线名称,目前只支持热插到 Root Port 设备,需要和 Root Port 的 id 保持一致。 + +- 对于轻量机型,由于 StratoVirt 支持的最大 virtio-net 数量为2个,热插网卡时请注意规格约束。对于标准机型,热插磁盘的数量取决于 Root Port 设备的数量。 + +**示例** + +轻量机型: + +```shell +<- {"execute":"netdev_add", "arguments":{"id":"net-0", "ifname":"tap0"}} +-> {"return": {}} +<- {"execute":"device_add", "arguments":{"id":"net-0", "driver":"virtio-net-mmio", "addr":"0x0"}} +-> {"return": {}} +``` + +其中,addr:0x0,对应虚拟机内部的eth0。 + +标准机型: + +```shell +<- {"execute":"netdev_add", "arguments":{"id":"net-0", "ifname":"tap0"}} +-> {"return": {}} +<- {"execute":"device_add", "arguments":{"id":"net-0", "driver":"virtio-net-pci", "addr":"0x0", "netdev": "net-0", "bus": "pcie.1"}} +-> {"return": {}} +``` + +#### 热拔网卡 + +**用法** + +轻量机型: + +```shell +{"execute": "device_del", "arguments": {"id": "net-0"}} +``` + +标准机型: + +```shell +{"execute": "device_del", "arguments": {"id":"net-0"}} +{"execute": "netdev_del", "arguments": {"id": "net-0"}} +``` + +**参数** + +- id:网卡的ID号,例如 net-0。 + +- netdev_del 中的 id 是网卡后端的名称。 + +**示例** + +轻量机型: + +```shell +<- {"execute": "device_del", "arguments": {"id": "net-0"}} +-> {"event":"DEVICE_DELETED","data":{"device":"net-0","path":"net-0"},"timestamp":{"seconds":1598513339,"microseconds":97310}} +-> {"return": {}} +``` + +标准机型: + +```shell +<- {"execute": "device_del", "arguments": {"id":"net-0"}} +-> {"return": {}} +-> {"event":"DEVICE_DELETED","data":{"device":"net-0","path":"net-0"},"timestamp":{"seconds":1598513339,"microseconds":97310}} +<- {"execute": "netdev_del", "arguments": {"id": "net-0"}} +-> {"return": {}} +``` + +当收到 DEVICE_DELETED 事件时,表示设备在 StratoVirt 侧被移除。 + +### 热插拔直通设备 + +StratoVirt 标准机型支持在虚拟机运行过程中调整直通设备数量,即在不中断业务前提下,给虚拟机增加或删除直通设备。 + +**注意事项** + +- 需要虚拟机内核开启 CONFIG_HOTPLUG_PCI_PCIE=y 配置。 + +- 目前支持热插拔设备到 Root Port 设备,Root Port 设备需要在虚拟机启动前配置。 + +- 不建议在虚拟机启动、关闭、内部高压力等状态下进行设备热插拔,可能会因为虚拟机内驱动没有及时响应导致虚拟机出现异常。 + +#### 热插直通设备 + +**用法** + +```shell +{"execute":"device_add", "arguments":{"id":"vfio-0", "driver":"vfio-pci", "bus": "pcie.1", "addr":"0x0", "host": "0000:1a:00.3"}} +``` + +**参数** + +- id 为热插设备的 ID 号。 + +- bus 为设备要挂载的总线名称。 + +- addr 为设备要挂载的 slot 和 function 号,目前 addr 参数需要指定为 0x0。 + +- host 为直通设备在主机上的 domain 号, bus 号, slot 号和 function 号。 + +**示例** + +```shell +<- {"execute":"device_add", "arguments":{"id":"vfio-0", "driver":"vfio-pci", "bus": "pcie.1", "addr":"0x0", "host": "0000:1a:00.3"}} +-> {"return": {}} +``` + +#### 热拔直通设备 + +**用法** + +```shell +{"execute": "device_del", "arguments": {"id": "vfio-0"}} +``` + +**参数** + +- id 为热拔设备的 ID 号。在热插设备时指定。 + +**示例** + +```shell +<- {"execute": "device_del", "arguments": {"id": "vfio-0"}} +-> {"return": {}} +-> {"event":"DEVICE_DELETED","data":{"device":"vfio-0","path":"vfio-0"},"timestamp":{"seconds":1614310541,"microseconds":554250}} +``` + +当收到 DEVICE_DELETED 事件时,表示设备在 StratoVirt 侧被移除。 + +## Ballon设备使用 + +使用balloon设备可以从虚拟机回收空闲的内存。Balloon通过qmp命令来调用。qmp命令使用如下: + +**用法:** + +```shell +{"execute": "balloon", "arguments": {"value": 2147483648‬}} +``` + +**参数:** + +- value: 想要设置的guest内存大小值,单位为字节。如果该值大于虚拟机启动时配置的内存值,则以启动时配置的内存值为准。 + +**示例:** + +启动时配置的内存大小为4GiB,在虚拟机内部通过free命令查询虚拟机空闲内存大于2GiB,那么可以通过qmp命令设置guest内存大小为2147483648字节。 + +```shell +<- {"execute": "balloon", "arguments": {"value": 2147483648‬}} +-> {"return": {}} +``` + +查询虚拟机的当前实际内存: + +```shell +<- {"execute": "query-balloon"} +-> {"return":{"actual":2147483648}} +``` + +## 虚拟机内存快照 + +### 简介 + +虚拟机内存快照是指将虚拟机的设备状态和内存信息保存在快照文件中。当虚拟机系统损坏时,可以使用内存快照将虚拟机恢复到快照对应时间点,从而提升系统的可靠性。 + +StratoVirt 支持对处于暂停状态(suspend)的虚拟机制作快照,并且支持虚拟机以快照文件为虚拟机模板批量创建新的虚拟机。只要制作快照的时间点在虚拟机启动完成并进入用户态之后,快速启动就能够跳过内核启动阶段和用户态服务初始化阶段,在毫秒级完成虚拟机启动。 + +### 互斥特性 + +虚拟机配置了如下设备或使用了如下特性时,不能制作和使用内存快照: + +- vhost-net 设备 +- vfio 直通设备 +- balloon 设备 +- 大页内存 +- mem-shared 特性 +- 配置了内存后端文件 mem-path + +### 制作快照 + +针对 StratoVirt 虚拟机,可以参考如下步骤制作存储快照: + +1. 创建并启动虚拟机。 + +2. 在 Host 上执行 QMP 命令暂停虚拟机: + + ```shell + <- {"execute":"stop"} + -> {"event":"STOP","data":{},"timestamp":{"seconds":1583908726,"microseconds":162739}} + -> {"return":{}} + + ``` + +3. 确认虚拟机处于暂停状态: + + ```shell + <- {"execute":"query-status"} + -> {"return":{"running":true,"singlestep":false,"status":"paused"}} + + ``` + +4. 执行如下 QMP 命令,在任一指定的绝对路径下创建虚拟机快照,例如 /path/to/template 路径,参考命令如下: + + ```shell + <- {"execute":"migrate", "arguments":{"uri":"file:/path/to/template"}} + -> {"return":{}} + + ``` + +5. 确认快照是否创建成功。 + + ```shell + <- {"execute":"query-migrate"} + + ``` + + 如果回显 {"return":{"status":"completed"}} ,说明快照创建成功。 + + 快照创建成功,会在指定路径 /path/to/template 生成 memory 和 state 两个目录。`state`文件包含虚拟机设备状态的信息,`memory`文件包含虚拟机内存的数据信息,memory 文件大小接近配置的虚拟机内存。 + +### 查询快照状态 + +当前在整个快照过程中,存在5种状态: + +- `None`: 快照资源没有准备完成 +- `Setup`: 快照资源准备完成,可以进行快照 +- `Active`: 处于制作快照状态中 +- `Completed`: 快照制作成功 +- `Failed`: 快照制作失败 + +可以通过在 Host 执行`query-migrate`qmp 命令查询当前快照的状态,如当虚拟机快照制作成功时查询: + +```shell +<- {"execute":"query-migrate"} +-> {"return":{"status":"completed"}} +``` + +### 恢复虚拟机 + +#### 注意事项 + +- 快照以及从快照启动特性支持的机型包括: + - microvm + - q35(x86_64) + - virt(aarch64平台) +- 在使用快照恢复时,配置的设备必须与制作快照时保持一致 +- 当使用 microvm 机型,并且在快照前使用了磁盘/网卡的热插特性,在恢复时需要将热插的磁盘/网卡配置进启动命令行 + +#### 从快照文件中恢复虚拟机 + +**命令格式** + +```shell +stratovirt -incoming URI + +``` + +**参数说明** + +URI:快照的路径,当前版本只支持 `file` 类型,后加上快照文件的绝对路径 + +**示例** + +假设制作快照所使用的虚拟机是通过以下命令创建的: + +```shell +$ stratovirt \ + -machine microvm \ + -kernel /path/to/kernel \ + -smp 1 -m 1024 \ + -append "console=ttyS0 pci=off reboot=k quiet panic=1 root=/dev/vda" \ + -drive file=/path/to/rootfs,id=rootfs,readonly=off,direct=off \ + -device virtio-blk-device,drive=rootfs \ + -qmp unix:/path/to/socket,server,nowait \ + -serial stdio + +``` + +那么,使用快照恢复虚拟机的参考命令如下(此处假设快照存放的路径为 /path/to/template ): + +```shell +$ stratovirt \ + -machine microvm \ + -kernel /path/to/kernel \ + -smp 1 -m 1024 \ + -append "console=ttyS0 pci=off reboot=k quiet panic=1 root=/dev/vda" \ + -drive file=/path/to/rootfs,id=rootfs,readonly=off,direct=off \ + -device virtio-blk-device,drive=rootfs \ + -qmp unix:/path/to/another_socket,server,nowait \ + -serial stdio \ + -incoming file:/path/to/template + +``` + +## 虚拟机热迁移 + +### 简介 + +StratoVirt 提供了虚拟机热迁移能力,也就是在虚机业务不中断的情况下,将虚拟机从一台服务器迁移到另一台服务器。 + +下列情形,可以使用虚拟机热迁移: + +- 当服务器负载过重时,可以使用虚拟机热迁移技术,将虚拟机迁移到另一台物理服务器上,达到负载均衡的目的。 +- 如果需要维护服务器,该服务器上的虚拟机可以在不中断业务的情形下,迁移到另一台物理服务器上。 +- 服务器出现故障,需要更换硬件或者调整组网时,为了避免虚拟机业务中断,可以将运行的虚拟机迁移到另一台物理机上。 + +### 热迁移操作 + +此处介绍热迁移虚拟机的操作方法,供用户参考。 + +**准备热迁移** + +1.使用 `root` 帐号,登录源端虚拟机所在的主机,执行如下命令(命令行参数,请根据实际情况修改),启动源端虚拟机。 + +```shell +./stratovirt \ + -machine q35 \ + -kernel ./vmlinux.bin \ + -append "console=ttyS0 pci=off reboot=k quiet panic=1 root=/dev/vda" \ + -drive file=path/to/rootfs,id=rootfs,readonly=off,direct=off \ + -device virtio-blk-pci,drive=rootfs,id=rootfs,bus=pcie.0,addr=0 \ + -qmp unix:path/to/socket1,server,nowait \ + -serial stdio \ +``` + +2.使用 `root` 帐号,登录目的端虚拟机所在的主机,执行如下命令(命令行参数需要和启动源端虚拟机保持一致),启动目的端虚拟机。 + +```shell +./stratovirt \ + -machine q35 \ + -kernel ./vmlinux.bin \ + -append "console=ttyS0 pci=off reboot=k quiet panic=1 root=/dev/vda" \ + -drive file=path/to/rootfs,id=rootfs,readonly=off,direct=off \ + -device virtio-blk-pci,drive=rootfs,id=rootfs,bus=pcie.0,addr=0 \ + -qmp unix:path/to/socket2,server,nowait \ + -serial stdio \ + -incoming tcp:192.168.0.1:4446 \ +``` + +> [!NOTE]说明 +> +> - 目的端虚拟机的启动命令行参数需要与源端虚拟机命令行保持一致。 +> - 如果需要将热迁移数据传输模式从 `TCP` 网络协议改为 `UNIX socket` 通信协议, + 只需要将目的端虚拟机的命令行 `-incoming tcp:192.168.0.1:4446`,改为 `-incoming unix:/tmp/stratovirt-migrate.socket`。但 `UNIX socket` 协议只支持单物理主机的不同虚拟机之间热迁移。 + +**开始热迁移** + +在源端虚拟机所在的主机,执行如下命令,启动虚拟机热迁移任务。 + +```shell +$ ncat -U path/to/socket1 +-> {"QMP":{"version":{"StratoVirt":{"micro":1,"minor":0,"major":0},"package":""},"capabilities":[]}} +<- {"execute":"migrate", "arguments":{"uri":"tcp:192.168.0.1:4446"}} +-> {"return":{}} +``` + +> [!NOTE]说明 +> +> 如果热迁移传输协议为 `UNIX socket` 通信协议,只需要将 QMP 命令中的 `"uri":"tcp:192.168.0.1:4446"`,改为 `"uri":"unix:/tmp/stratovirt-migrate.socket"`。 + +**结束热迁移** + +当执行上述迁移 `QMP` 命令后,虚拟机热迁移任务就开始执行。如果没有热迁移错误日志,则源端的虚拟机就迁移到了目的端,源端虚拟机会自动销毁。 + +### 取消热迁移 + +在热迁移过程中,可能出现迁移时间较长,或目的端虚拟机所在的主机负载发生变化,需要调整迁移策略。StratoVirt 提供了取消热迁移操作的特性。 + +取消热迁移的操作如下: +登录源端虚拟机所在的主机,执行如下 `QMP` 命令: + +```shell +$ ncat -U path/to/socket1 +-> {"QMP":{"version":{"StratoVirt":{"micro":1,"minor":0,"major":0},"package":""},"capabilities":[]}} +<- {"execute":"migrate_cancel"} +-> {"return":{}} +``` + +如果目的端虚拟机退出热迁移任务,并在日志提示取消热迁移,表示热迁移任务取消成功。 + +### 查询热迁移状态 + +热迁移存在如下几种状态: + +- `None`: 热迁移 vCPU,内存,设备等资源没有准备完成 +- `Setup`: 热迁移资源准备完成,可以进行热迁移 +- `Active`: 处于制作热迁移过程中 +- `Completed`: 热迁移完成 +- `Failed`: 热迁移失败 + +以下 `QMP` 命令表示查询当前热迁移处于完成状态: + +```shell +$ ncat -U path/to/socket +-> {"QMP":{"version":{"StratoVirt":{"micro":1,"minor":0,"major":0},"package":""},"capabilities":[]}} +<- {"execute":"query-migrate"} +-> {"return":{"status":"completed"}} +``` + +### 约束与限制 + +StratoVirt 只支持标准虚机主板热迁移: + +- q35 (x86_64平台) +- virt (aarch64平台) + +以下设备和特性不支持热迁移: + +- vhost-net 设备 +- vhost-user-net 设备 +- virtio balloon 设备 +- vfio 设备 +- 共享后端存储 +- 共享内存,后端内存特性 + +以下启动源端和目的端虚拟机命令行参数必须保持一致: + +- virtio-net: MAC 地址 +- device: BDF 号 +- smp +- m -- Gitee From 3f3e7c2375cb4b340ee8643db59abb8aca07f8e3 Mon Sep 17 00:00:00 2001 From: chopupu Date: Mon, 11 Aug 2025 21:12:45 +0800 Subject: [PATCH 2/4] add virt files --- docs/zh/virtualization/_toc.yaml | 2 +- .../stratovirt/_toc.yaml | 3 +- .../stratovirt/interconnect_libvirt.md | 2 +- .../virtualization/_toc.yaml | 36 + .../virtualization/appendix.md | 140 +++ .../virtualization/best_practices.md | 689 +++++++++++++ .../virtualization/environment_preparation.md | 366 +++++++ .../virtualization/figures/CertEnrollP1.png | Bin 0 -> 5880 bytes .../virtualization/figures/CertEnrollP2.png | Bin 0 -> 11246 bytes .../virtualization/figures/CertEnrollP3.png | Bin 0 -> 8778 bytes .../virtualization/figures/CertEnrollP4.png | Bin 0 -> 8734 bytes .../virtualization/figures/CertEnrollP5.png | Bin 0 -> 8931 bytes .../virtualization/figures/CertEnrollP6.png | Bin 0 -> 2782 bytes .../virtualization/figures/CertEnrollP7.png | Bin 0 -> 6827 bytes .../virtualization/figures/CertEnrollP8.png | Bin 0 -> 9004 bytes .../virtualization/figures/OSBootFlow.png | Bin 0 -> 55015 bytes .../virtualization/figures/SecureBootFlow.png | Bin 0 -> 139351 bytes .../figures/kvm-architecture.png | Bin 0 -> 16018 bytes .../figures/status-transition-diagram.png | Bin 0 -> 22222 bytes .../figures/virtual-network-structure.png | Bin 0 -> 15979 bytes .../figures/virtualized-architecture.png | Bin 0 -> 14455 bytes .../figures/zh-cn_image_0218587435.png | Bin 0 -> 1607 bytes .../figures/zh-cn_image_0218587436.png | Bin 0 -> 1858 bytes .../introduction_to_virtulization.md | 80 ++ .../virtualization/libcareplus.md | 379 ++++++++ .../virtualization/managing_devices.md | 877 +++++++++++++++++ .../virtualization/managing_vms.md | 788 +++++++++++++++ .../virtualization/skylark.md | 192 ++++ .../system_resource_management.md | 454 +++++++++ .../virtualization/tool_guide.md | 3 + .../virtualization/virtualization.md | 3 + .../virtualization_installation.md | 137 +++ .../virtualization/vm_configuration.md | 904 ++++++++++++++++++ .../virtualization/vm_live_migration.md | 377 ++++++++ .../vm_maintainability_managment.md | 24 + .../virtualization/vmtop.md | 196 ++++ 36 files changed, 5649 insertions(+), 3 deletions(-) create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/_toc.yaml create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/appendix.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/best_practices.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/environment_preparation.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP1.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP2.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP3.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP4.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP5.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP6.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP7.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP8.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/OSBootFlow.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/SecureBootFlow.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/kvm-architecture.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/status-transition-diagram.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/virtual-network-structure.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/virtualized-architecture.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/zh-cn_image_0218587435.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/figures/zh-cn_image_0218587436.png create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/introduction_to_virtulization.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/libcareplus.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/managing_devices.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/managing_vms.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/skylark.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/system_resource_management.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/tool_guide.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/virtualization.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/virtualization_installation.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/vm_configuration.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/vm_live_migration.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/vm_maintainability_managment.md create mode 100644 docs/zh/virtualization/virtualization_platform/virtualization/vmtop.md diff --git a/docs/zh/virtualization/_toc.yaml b/docs/zh/virtualization/_toc.yaml index 14ad99f9..9d8725fe 100644 --- a/docs/zh/virtualization/_toc.yaml +++ b/docs/zh/virtualization/_toc.yaml @@ -7,4 +7,4 @@ sections: - label: openStack用户指南 href: >- https://openstack-sig.readthedocs.io/zh/latest/ - description: 一个开源的云计算管理平台项目 \ No newline at end of file + description: 一个开源的云计算管理平台项目 diff --git a/docs/zh/virtualization/virtualization_platform/stratovirt/_toc.yaml b/docs/zh/virtualization/virtualization_platform/stratovirt/_toc.yaml index 49bff4be..18875e65 100644 --- a/docs/zh/virtualization/virtualization_platform/stratovirt/_toc.yaml +++ b/docs/zh/virtualization/virtualization_platform/stratovirt/_toc.yaml @@ -17,4 +17,5 @@ sections: - label: 对接libvirt href: ./interconnect_libvirt.md - label: StratoVirt VFIO 使用说明 - href: ./stratovirt_vfio_instructions.md \ No newline at end of file + href: ./stratovirt_vfio_instructions.md + \ No newline at end of file diff --git a/docs/zh/virtualization/virtualization_platform/stratovirt/interconnect_libvirt.md b/docs/zh/virtualization/virtualization_platform/stratovirt/interconnect_libvirt.md index ef8bd6ec..06ca5818 100644 --- a/docs/zh/virtualization/virtualization_platform/stratovirt/interconnect_libvirt.md +++ b/docs/zh/virtualization/virtualization_platform/stratovirt/interconnect_libvirt.md @@ -24,7 +24,7 @@ StratoVirt 对接 libvirt 之前,需要先配置 XML 文件。本小节介绍 > [!NOTE]说明 > -> 使用 libvirt 管理 StratoVirt 虚拟机前,应该注意到 StratoVirt 当前支持的特性、特性之间的互斥关系、特性的配置前提条件、规格等,详细信息请参见命令行方式的 "[虚拟机配置](https://docs.openeuler.org/zh/docs/22.03_LTS_SP4/docs/StratoVirt/%E8%99%9A%E6%8B%9F%E6%9C%BA%E9%85%8D%E7%BD%AE.html)”章节。 +> 使用 libvirt 管理 StratoVirt 虚拟机前,应该注意到 StratoVirt 当前支持的特性、特性之间的互斥关系、特性的配置前提条件、规格等,详细信息请参见命令行方式的 "[虚拟机配置](./vm_configuration.md)”章节。 ### 虚拟机描述 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/_toc.yaml b/docs/zh/virtualization/virtualization_platform/virtualization/_toc.yaml new file mode 100644 index 00000000..2b2d378e --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/_toc.yaml @@ -0,0 +1,36 @@ +label: 虚拟化用户指南 +isManual: true +description: 在openEuler系统中使用虚拟化技术创建和管理虚拟机 +sections: + - label: 认识虚拟化 + href: ./introduction_to_virtulization.md + - label: 安装虚拟化组件 + href: ./virtualization_installation.md + - label: 准备使用环境 + href: ./environment_preparation.md + - label: 虚拟机配置 + href: ./vm_configuration.md + - label: 管理虚拟机 + href: ./managing_vms.md + - label: 热迁移虚拟机 + href: ./vm_live_migration.md + - label: 管理系统资源 + href: ./system_resource_management.md + - label: 管理设备 + href: ./managing_devices.md + - label: 管理虚拟机可维护性 + href: ./vm_maintainability_managment.md + - label: 最佳实践 + href: ./best_practices.md + - label: 工具使用指南 + href: ./tool_guide.md + sections: + - label: vmtop + href: ./vmtop.md + - label: LibcarePlus + href: ./libcareplus.md + - label: Skylark虚拟机混部 + href: ./skylark.md + - label: 附录 + href: ./appendix.md + diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/appendix.md b/docs/zh/virtualization/virtualization_platform/virtualization/appendix.md new file mode 100644 index 00000000..d6b616c4 --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/appendix.md @@ -0,0 +1,140 @@ +# 附录 + +## 术语和缩略语 + +文档中使用的术语和缩略语请分别参见[表1](#table201236162279)和[表2](#table1423422319271)。 + +**表 1** 术语表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

术语

+

含义

+

AArch64

+

AArch64 是 ARMv8 架构的一种执行状态。AArch64不仅仅是32位 ARM 构架的扩展,还是ARMv8内全新的构架,完全使用全新的 A64 指令集

+

Domain

+

资源的一个可配置集合,包括内存、虚拟CPU,网络设备和磁盘设备。在 Domain 中运行虚拟机。一个 Domain 被分配虚拟资源,可以独立地被启动、停止和重启。

+

Libvirt

+

一套用于管理虚拟化平台的工具集,可用于管理KVM、QEMU、Xen及其他虚拟化。

+

Guest OS

+

即客户机操作系统,指运行在虚拟机上的操作系统。

+

Host OS

+

即宿主机操作系统,指被虚拟的物理机的操作系统。

+

Hypervisor

+

即虚拟机监视器VMM,是一种运行在基础物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享硬件。

+

虚拟机

+

使用虚拟化技术,通过软件模拟完整的计算机硬件系统功能,构造出的完整虚拟计算机系统。

+
+ +**表 2** 缩略语表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

缩略语

+

英文全称

+

中文全称

+

含义

+

NUMA

+

Non-Uniform Memory Access Architecture

+

非统一内存访问架构

+

NUMA是一种为多处理器计算机设计的内存架构。在NUMA下,处理器访问它自己的本地内存的速度比非本地内存(内存位于另一个处理器,或者是处理器之间共享的内存)快一些。

+

KVM

+

Kernel-based Virtual Machine

+

基于内核的虚拟机

+

KVM是基于内核的虚拟机,是Linux的一个内核模块,该模块使得Linux成为一个hypervisor

+

OVS

+

Open vSwitch

+

开放虚拟交换标准

+

OVS是一个高质量的多层虚拟交换机,使用开源Apache2.0许可协议。

+

QEMU

+

Quick Emulator

+

快速模拟器

+

QEMU是一个通用的可执行硬件虚拟化的开源模拟器。

+

SMP

+

Symmetric Multi-Processor

+

对称多处理

+

SMP是一种多处理器的计算机硬件架构。现在多数的处理器系统都采用对称多处理器架构。该架构系统拥有多个处理器,各处理器共享内存子系统和总线结构。

+

UEFI

+

Unified Extensible Firmware Interface

+

统一的可扩展固件接口

+

一种详细描述全新类型接口的标准。该接口用于操作系统自动从预启动的操作环境,加载到一种操作系统上。

+

VM

+

Virtual Machine

+

虚拟机

+

使用虚拟化技术,通过软件模拟完整的计算机硬件系统功能,构造出的完整虚拟计算机系统。

+

VMM

+

Virtual Machine Monitor

+

虚拟机监视器

+

是一种运行在基础物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享硬件。

+
diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/best_practices.md b/docs/zh/virtualization/virtualization_platform/virtualization/best_practices.md new file mode 100644 index 00000000..c98bad25 --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/best_practices.md @@ -0,0 +1,689 @@ +# 最佳实践 + +## 性能最佳实践 + +### halt-polling + +#### 概述 + +在计算资源充足的情况下,为使虚拟机获得接近物理机的性能,可以使用halt-polling特性。没有使用halt-polling特性时,当vCPU空闲退出后,主机会把CPU资源分配给其他进程使用。当主机开启halt-polling特性时,虚拟机vCPU处于空闲时会polling一段时间,polling的时间由具体配置决定。若该vCPU在polling期间被唤醒,可以不从主机侧调度而继续运行,减少了调度流程的开销,从而在一定程度上提高了虚拟机系统的性能。 + +>![!NOTE]说明 +>halt-polling的机制保证虚拟机的vCPU线程的及时响应,但在虚拟机空载的时候,主机侧也会polling,导致主机看到vCPU所在CPU占用率比较高,而实际虚拟机内部CPU占用率并不高。 + +#### 操作指导 + +系统默认开启了halt-polling特性,polling的时间默认为500000ns。用户可以通过文件halt\_poll\_ns内容动态修改vCPU用于halt-polling的时间,单位为ns。 + +例如设置polling时间为400000,使用root用户执行命令如下: + +```sh +# echo 400000 > /sys/module/kvm/parameters/halt_poll_ns +``` + +### IOThread配置 + +#### 概述 + +KVM平台上,对虚拟磁盘的读写在后端默认由QEMU主线程负责处理。这样会造成如下问题: + +- 虚拟机的I/O请求都由一个QEMU主线程进行处理,因此单线程的CPU利用率成为虚拟机I/O性能的瓶颈。 +- 虚拟机I/O在QEMU主线程处理时会持有QEMU全局锁\(qemu\_global\_mutex\),一旦I/O处理耗时较长,QEMU主线程长时间占有全局锁,会导致虚拟机vCPU无法正常调度,影响虚拟机整体性能及用户体验。 + +可以为virtio-blk磁盘或者virtio-scsi控制器配置IOThread属性,在QEMU后端单独开辟IOThread线程处理虚拟磁盘读写请求,IOThread线程和virtio-blk磁盘或virtio-scsi控制器可配置成一对一的映射关系,尽可能地减少对QEMU主线程的影响,提高虚拟机整体I/O性能,提升用户体验。 + +#### 配置说明 + +使用IOThread线程处理虚拟机磁盘读写请求,需要修改虚拟机配置,这里给出具体的配置说明。 + +- 配置虚拟机高性能虚拟磁盘的总数。例如通过配置IOThread线程的总数为4: + + ```conf + + VMName + 4194304 + 4194304 + 4 + 4 + ``` + +- 给virtio-blk磁盘配置IOThread属性。<**iothread**\>表示IOThread线程编号,编号从1开始配置,最大为的配置值,且编号不能重复使用。例如将编号为2的IOThread配置给virtio-blk磁盘使用: + + ```conf + + + + +
+ + ``` + +- 给virtio-scsi控制器配置IOThread属性。例如将编号为2的IOThread配置给virtio-scsi控制器使用: + + ```conf + + + +
+ + ``` + +- IOThread线程绑定物理CPU + + 虚拟磁盘IOThread线程的绑核配置,将IOThread线程绑定到用户指定的物理CPU范围内,不影响vCPU线程的资源占用诉求。表示IOThread线程编号,表示绑定的物理CPU编号。 + + ```conf + + + + + ``` + +### 裸设备映射 + +#### 概述 + +配置虚拟机存储设备时,除了将文件配置给虚拟机作为虚拟磁盘使用外,还可以将块设备(物理LUN、逻辑卷等)直接配置给虚拟机使用,从而提升存储性能。该配置方式称为裸设备映射。在该配置方式下,虚拟磁盘向虚拟机呈现为一个SCSI(Small Computer System Interface,小型计算机系统接口)设备,且支持大部分SCSI命令。 + +裸设备映射根据后端实现特点,分为虚拟裸设备映射和物理裸设备映射,物理裸设备映射相对虚拟裸设备映射具有更优秀的性能和更丰富的SCSI命令,但物理裸设备映射需要将整块SCSI磁盘挂载给虚拟机使用,如果使用分区、逻辑卷等方式配置,虚拟机将无法识别。 + +#### 配置示例 + +裸设备映射需要修改虚拟机配置文件,这里给出配置示例。 + +- 虚拟裸设备映射 + + 将主机上存在的SCSI磁盘“/dev/sdc”挂载给虚拟机作为虚拟裸设备的配置示例如下: + + ```conf + + + ... + + + + + +
+ + ... + + + ``` + +- 物理裸设备映射 + + 将主机上存在的SCSI磁盘“/dev/sdc”挂载给虚拟机作为物理裸设备的配置示例如下: + + ```conf + + + ... + + + + + +
+ + ... + + + ``` + +### kworker隔离绑定 + +#### 概述 + +kworker是Linux内核实现的per-CPU线程,用来执行系统中的workqueue请求。kworker线程会和vCPU线程争抢物理核资源,导致虚拟化业务性能抖动。为了使虚拟机能够稳定的运行,减少kworker线程对虚拟机的干扰,可以将主机上的kworker线程绑定到特定的CPU上运行。 + +#### 操作步骤 + +用户可以通过修改/sys/devices/virtual/workqueue/cpumask文件,将workqueue中的任务绑定到cpumask中指定的CPU上。cpumask中的掩码以十六进制表示,例如将kworker绑定到CPU0\~CPU7上,对应掩码为ff,使用root用户执行命令如下: + +```sh +# echo ff > /sys/devices/virtual/workqueue/cpumask +``` + +### 内存大页 + +#### 概述 + +相比传统的4K内存分页,openEuler也支持2MB/1GB的大内存分页。内存大页可以有效减少TLB miss,显著提升内存访问密集型业务的性能。openEuler使用两种技术来实现内存大页。 + +- 静态大页 + + 静态大页要求宿主机操作系统在加载前提前预留一个静态大页池,虚拟机创建时通过修改xml配置文件的方式,指定虚拟机的内存从静态大页池中分配。静态大页能保证虚拟机的所有内存在host上始终以大页形式存在,保证物理连续,但增加了部署的困难,修改静态大页池的页面大小后需要重启host才能生效。静态大页的页面大小支持2M或1G。 + +- 透明大页 + + 如果开启透明大页模式THP(Transparent Huge Pages),虚拟机分配内存时自动选择可用的2M连续页,同时自动完成大页的拆分合并,当没有可用的2M连续页时,它会选择可用的64K(AArch64架构)或4K(x86_64架构)页面进行分配。透明大页的好处是不需要用户感知,同时能尽量使用2M大页以提升内存访问性能。 + +在虚拟机完全使用静态大页的场景下,可以通过关闭透明大页的方法,减少宿主机操作系统的开销,以便虚拟机获得更稳定的性能。 + +#### 操作指导 + +- 使用静态大页 + + 在创建虚拟机之前通过修改XML的方式,为虚拟机配置使用静态大页。 + + ```conf + + + + + + ``` + + 以上XML片段表示为虚拟机配置1G静态大页。 + + ```conf + + + + + + ``` + + 以上XML片段表示为虚拟机配置2M静态大页。 + +- 使用透明大页 + + 通过sysfs可以动态开启使用透明大页: + + ```sh + # echo always > /sys/kernel/mm/transparent_hugepage/enabled + ``` + + 动态关闭使用透明大页: + + ```sh + # echo never > /sys/kernel/mm/transparent_hugepage/enabled + ``` + +### PV-qspinlock + +#### 概述 + +PV-qspinlock主要是针对虚拟化CPU超分场景自旋锁的优化,允许hypervisor将处于锁上下文中的vCPU置于block状态,并在锁释放后将对应的vCPU唤醒,在超分场景下能够更好地利用pCPU资源,对于编译的应用场景有一定的优化,可以减少编译应用的时长。 + +#### 操作指导 + +修改虚拟机/boot/efi/EFI/openEuler/grub.cfg配置文件,在命令行启动参数添加arm_pvspin,重启虚拟机后生效。PV-qspinlock生效后,虚拟机内部使用dmesg命令可以查到如下日志打印: + +```conf +[ 0.000000] arm-pv: PV qspinlocks enabled +``` + +>![!NOTE]说明 +>PV-qspinlock仅限于宿主机和虚拟机操作系统均为openEuler 20.09及以上版本支持,且虚拟机内核编译选项需要配置CONFIG_PARAVIRT_SPINLOCKS=y(openEuler默认配置)。 + +### Guest-Idle-Haltpoll + +#### 概述 + +为了保证公平性及降低功耗,当虚拟机vCPU空闲时,虚拟机将执行WFx/HLT指令退出到宿主机中,并触发上下文切换。宿主机将决定在物理CPU上调度其他进程或vCPU,或进入节能模式。但是,虚拟机和宿主机之间的切换、额外的上下文切换以及唤醒IPI中断开销较大,在频繁睡眠和唤醒的业务中该问题尤为突出。Guest-Idle-Haltpoll技术是指当虚拟机vCPU空闲时,不立刻执行WFx/HLT并发生VM-exit,而是在虚拟机内部轮询(polling)一段时间。在该时间段内,其他共享LLC的vCPU在该vCPU上的任务被唤醒不需要发送IPI中断,减少了发送和接收处理IPI的开销及虚拟机陷出(VM-exit)的开销,从而降低任务唤醒的时延。 + +>![!NOTE]说明 +>由于vCPU在虚拟机内部执行idle-haltpoll会增加vCPU在宿主机的CPU开销,所以开启该特性建议vCPU在宿主机独占物理核。 + +#### 操作指导 + +Guest-Idle-Haltpoll特性默认关闭,这里给出开启该特性的操作指导。 + +1. 使能Guest-Idle-Haltpoll特性。 + - 若宿主机处理器架构为x86,可以在宿主机的虚拟机XML中配置“hint-dedicated”使能该特性,通过虚拟机XML配置将vCPU独占物理核的状态传递给虚拟机。vCPU独占物理核的状态由宿主机保证。 + + ```conf + + ... + + + ... + + + + ... + + ``` + + 或者登录到虚拟机内部以虚拟机为粒度进行在线配置。该方法不依赖宿主机配置vCPU独占物理核。 + + ```sh + echo Y > /sys/module/cpuidle_haltpoll/parameters/force + ``` + + - 若宿主机处理器架构为AArch64,当前只支持在虚拟机内部进行在线配置的方式使能该特性。 + + ```sh + echo Y > /sys/module/cpuidle_haltpoll/parameters/force + ``` + +2. 确认Guest-Idle-Haltpoll特性是否生效。在虚拟机中执行如下命令,若返回haltpoll,说明特性已经生效。 + + ```sh + # cat /sys/devices/system/cpu/cpuidle/current_driver + ``` + +3. (可选)配置Guest-Idle-Haltpoll参数。 + 虚拟机的/sys/module/haltpoll/parameters/路径下提供了如下配置文件,用于调整配置参数,用户可以根据业务特点选择调整。 + + - guest\_halt\_poll\_ns: 全局参数,指vCPU空闲后polling的最大时长,默认值为200000(单位ns)。 + - guest\_halt\_poll\_shrink: 当唤醒事件发生在全局guest\_halt\_poll\_ns时间之后,用于收缩当前vCPU guest\_halt\_poll\_ns的除数因子,默认值为2。 + - guest\_halt\_poll\_grow: 当唤醒事件发生在当前vCPU guest\_halt\_poll\_ns之后且在全局guest\_halt\_poll\_ns之前,用于扩展当前vCPU guest\_halt\_poll\_ns的乘数因子,默认值为2。 + - guest\_halt\_poll\_grow\_start: 当系统空闲时,每个vCPU的guest\_halt\_poll\_ns最终会达到零。该参数用于设置当前vCPU guest\_halt\_poll\_ns的初始值,以便vCPU polling时长的收缩和扩展。默认值为50000(单位ns)。 + - guest\_halt\_poll\_allow\_shrink: 允许每个vCPU guest\_halt\_poll\_ns收缩的开关,默认值是Y(Y表示允许收缩,N表示禁止收缩)。 + + 可以使用root权限,参考如下命令修改参数值。其中 _value_ 表示需要设置的参数值, _configFile_ 为对应的配置文件。 + + ```sh + # echo value > /sys/module/haltpoll/parameters/configFile + ``` + + 例如设置全局guest\_halt\_poll\_ns为200000ns的命令如下: + + ```sh + # echo 200000 > /sys/module/haltpoll/parameters/guest_halt_poll_ns + ``` + +### Nvme磁盘直通 + +#### 概述 + +设备直通技术是一种基于硬件的虚拟化解决方案,通过该技术,虚拟机可以直接连接到指定的物理直通设备上。对于用户来说,如果需要提升虚拟机存储性能,可以采用将 Nvme 磁盘通过 PCI 直通技术直通给虚拟机的办法,从而获得更高的性能表现。 + +#### 操作指导 + +1. 使用前准备。 + + - 确认 Guest OS 内安装 Nvme 磁盘供应商所提供的驱动程序,否则 Nvme 磁盘无法正常工作。 + - 确认 Host OS 开启CPU的 VT-d 和 VT-x 支持。 + - 确认 Host OS 开启内核的 IOMMU 功能。 + - 确认 Host OS 开启内核的中断重映射功能。 + +2. 获取 Nvme 磁盘的 PCI BDF 信息。 + + 在Host上通过 **lspci** 命令获取主机上pci设备的资源列表,具体命令如下所示: + + ```sh + # lspci -vmm + Slot: 81:00.1 + Class: Non-Volatile memory controller + ... + ``` + + 命令回显其中的 **Slot** 选项即对应了 Nvme 磁盘的 PCI BDF 号,以上方命令为例,每个值的对应关系即81-bus号,00-slot号,1-function号。 + +3. 挂载 PCI 直通 Nvme 磁盘至虚拟机中。 + + 创建虚拟机时,在其对应的 xml 配置文件中加入 PCI Nvme 磁盘直通的配置选项。具体配置文件如下所示: + + ```conf + + +
+ + + ``` + + - hostdev.source.address.domain: Host OS 上 PCI 设备的 domain 号。 + - hostdev.source.address.bus: Host OS 上 PCI 设备的 bus 号。 + - hostdev.source.address.slot: Host OS 上 PCI 设备的 slot 号。 + - hostdev.source.address.function: Host OS 上 PCI 设备的 function 号。 + +4. 指定 Nvme 磁盘的 PCI bar 空间。 + + 为了进一步将 Nvme 磁盘的性能发挥到极致,需要指定直通 Nvme 磁盘在 Guest OS 内 PCI MSI-X 中断的 Bar 空间。具体配置如下: + + ```conf + + +
+ + +
+ + + + + + ``` + + 以上xml配置将直通的 Nvme 磁盘的中断信息处理指定在第2号 Bar 上,增加该项配置可以使 Guest OS 内的 Nvme 磁盘性能达到与 Host OS 上的 Nvme 磁盘性能几乎一致。 + +## 安全最佳实践 + +### Libvirt鉴权 + +#### 简介 + +用户使用libvirt远程调用功能时,如果不进行任何鉴权校验,所有连接到主机所在网络的第三方程序都可以通过libvirt的远程调用操作虚拟机,存在安全隐患。为了提升系统安全性,openEuler提供了libvirt鉴权功能,即用户通过libvirt远程调用操作虚拟机前,必须经过身份校验,只有特定用户允许访问虚拟机,从而保护组网中的虚拟机。 + +#### 开启libvirt鉴权 + +openEuler默认关闭libvirt远程调用功能,这里给出开启libvirt远程调用和libvirt鉴权功能的方法。 + +1. 使用root用户登录主机。 +2. 修改libvirt服务配置文件/etc/libvirt/libvirtd.conf,开启libvirt远程调用和libvirt鉴权功能。例如使用基于SASL(Simple Authentication and Security Layer)协议的TCP远程调用配置参考如下: + + ```sh + # 传输层安全协议,0表示关闭,1表示开启,由用户自行配置 + listen_tls = 0 + # 开启基于TCP的远程调用,开启libvirt远程调用和libvirt鉴权功能必须配置为1 + listen_tcp = 1 + # TCP远程调用所使用的协议,由用户自行配置,此处以sasl为例 + auth_tcp = "sasl" + ``` + +3. 修改/etc/sasl2/libvirt.conf配置文件,设置SASL认证机制和sasldb数据库。 + + ```sh + # sasl协议的认证机制 + mech_list: digest-md5 + # 存放用户和用户密码的数据库 + sasldb_path: /etc/libvirt/passwd.db + ``` + +4. 添加用于SASL验证的用户并设置其密码,假设用户名为userName,命令参考如下: + + ```sh + # saslpasswd2 -a libvirt userName + Password: + Again (for verification): + ``` + +5. 修改/etc/sysconfig/libvirtd配置文件,开启libvirt侦听选项。 + + ```sh + LIBVIRTD_ARGS="--listen" + ``` + +6. 重启libvirtd服务,使修改生效。 + + ```sh + # systemctl restart libvirtd + ``` + +7. 确认libvirt远程调用的鉴权功能是否生效。根据提示输入用户名和密码能够成功连接libvirt服务,说明开启成功。 + + ```sh + # virsh -c qemu+tcp://192.168.0.1/system + Please enter your authentication name: openeuler + Please enter your password: + Welcome to virsh, the virtualization interactive terminal. + + Type: 'help' for help with commands + 'quit' to quit + + virsh # + ``` + +#### 管理SASL + +这里给出管理SASL用户的操作,请使用root用户操作。 + +- 查询数据库中存在的用户 + + ```sh + # sasldblistusers2 -f /etc/libvirt/passwd.db + user@localhost.localdomain: userPassword + ``` + +- 从数据库中删除用户user + + ```sh + # saslpasswd2 -a libvirt -d user + ``` + +### qemu-ga + +#### 概述 + +qemu-ga(Qemu Guest Agent)它是运行在虚拟机内部的守护进程,它允许用户在host OS上通过QEMU提供带外通道实现对guest OS的多种管理操作:包括文件操作(open、read、write、close,seek、flush等)、内部关机、虚拟机休眠(suspend-disk、suspend-ram、suspend-hybrid),获取虚拟机内部的信息(包括内存,CPU,网卡,OS等相关信息 )等。 + +在一些对安全要求较高的使用场景,为了防止虚拟机内部信息泄露,qemu-ga提供了黑名单功能,用户可以通过黑名单选择性屏蔽qemu-ga提供的部分功能。 + +>![!NOTE]说明 +>qemu-ga对应的安装包是qemu-guest-agent-xx.rpm,openEuler默认不安装。xx为实际版本号。 + +#### 操作方法 + +请使用root用户按照如下操作步骤添加qemu-ga黑名单: + +1. 登录虚拟机,确定qemu-guest-agent服务存在且处于运行状态: + + ```sh + # systemctl status qemu-guest-agent |grep Active + Active: active (running) since Wed 2018-03-28 08:17:33 CST; 9h ago + ``` + +2. 查询qemu-ga哪些命令可以加入黑名单: + + ```sh + # qemu-ga --blacklist ? + guest-sync-delimited + guest-sync + guest-ping + guest-get-time + guest-set-time + guest-info + ... + ``` + +3. 设置黑名单。通过修改/usr/lib/systemd/system/qemu-guest-agent.service,将需要屏蔽的命令添加到该文件的--blacklist中,不同命令使用空格分隔。例如将guest-file-open和guest-file-close命令加入黑名单的配置参考如下: + + ```conf + [Service] + ExecStart=-/usr/bin/qemu-ga \ + --blacklist=guest-file-open guest-file-close + ``` + +4. 重启qemu-guest-agent服务: + + ```sh + # systemctl daemon-reload + # systemctl restart qemu-guest-agent + ``` + +5. 确认虚拟机开启qemu-ga黑名单功能是否生效,即qemu-ga进程配置的参数--blacklist是否正确: + + ```sh + # ps -ef|grep qemu-ga|grep -E "blacklist=|b=" + root 727 1 0 08:17 ? 00:00:00 /usr/bin/qemu-ga --method=virtio-serial --path=/dev/virtio-ports/org.qemu.guest_agent.0 --blacklist=guest-file-open guest-file-close guest-file-read guest-file-write guest-file-seek guest-file-flush -F/etc/qemu-ga/fsfreeze-hook + ``` + + >![!NOTE]说明 + >更多关于qemu-ga的资料可以参见[https://wiki.qemu.org/Features/GuestAgent](https://wiki.qemu.org/Features/GuestAgent)。 + +### sVirt保护 + +#### 概述 + +在只使用自由访问控制DAC(Discretionary Acces Control)策略的虚拟化环境中,主机上运行的恶意虚拟机可能存在攻击hypervisor或其他虚拟机的情况。为了提升虚拟化场景的安全性,openEuler使用了sVirt保护。sVirt是基于SELinux,适用于KVM虚拟化场景的安全防护技术。虚拟机本质是主机操作系统上的普通进程,sVirt机制在hypervisor将虚拟机对应的QEMU进程进行SELinux标记分类,除了使用type表示虚拟化专有进程和文件,还用不同的category(在seclevel区间)表示不同虚拟机,每个虚拟机只能访问自身相同category的文件设备,防止虚拟机访问非授权的主机或其他虚拟机的文件和设备,从而防止虚拟机逃逸,提升主机和虚拟机的安全性。 + +#### 开启sVirt保护 + +**一、使用root用户按照如下操作步骤开启主机的SELinux** + +1. 登录主机。 +2. 开启主机SELinux功能。 + 1. 修改系统启动的grub.cfg,将selinux设置为1。 + + ```conf + selinux=1 + ``` + + 2. 修改/etc/selinux/config,将SELINUX模式设置为enforcing。 + + ```conf + SELINUX=enforcing + ``` + +3. 重启主机。 + + ```sh + # reboot + ``` + +**二、创建开启sVirt功能的虚拟机** + +1. 虚拟机配置文件中添加如下配置: + + ```conf + + ``` + + 或确认没有下述配置: + + ```conf + + ``` + +2. 创建虚拟机。 + + ```sh + # virsh define openEulerVM.xml + ``` + +**三、确认sVirt开启成功** + +执行下述命令检查运行中的虚拟机QEMU进程是否已经启用sVirt防护,若存在"svirt\_t:s0:c"表示已经启用sVirt防护。 + +```sh +# ps -eZ|grep qemu |grep "svirt_t:s0:c" +system_u:system_r:svirt_t:s0:c200,c947 11359 ? 00:03:59 qemu-kvm +system_u:system_r:svirt_t:s0:c427,c670 13790 ? 19:02:07 qemu-kvm +``` + +### 虚拟机可信启动 + +#### 概述 + +可信启动包含度量启动和远程证明。其中虚拟化组件主要提供度量启动功能,远程证明由用户自己在虚拟机中安装相关软件(RA client)及搭建远程证明服务器(RA server)进行使能。 + +度量启动的两个基本要素是信任根和信任链,其基本思想是首先在计算机系统中建立一个信任根,信任根的可信性由物理安全、技术安全和管理安全共同确保,即CRTM(Core Root of Trust for Measurement)。然后建立一条信任链,从信任根开始到BIOS/BootLoader、操作系统、再到应用,一级度量认证一级,一级信任一级,最终把这种信任扩展到整个系统。上述过程看起来如同一根链条一样环环相扣,因此称之为“信任链”。 + +CRTM是度量启动的根,是系统启动的首个组件,没有其他代码来检查CRTM本身的完整性。所以,作为信任链的起点,必须保证它是绝对可信的信任源。因此,技术上需要将CRTM设计成一段只读或更新严格受限的代码,抵御BIOS攻击,防止远程注入恶意代码或在操作系统上层修改启动代码。通常物理主机中由CPU中的微码作为CRTM,在虚拟化环境中,一般选择vBIOS的sec部分为CRTM。 + +启动过程中,前一个部件度量(计算HASH值)后一个部件,然后把度量值扩展入可信存储区例如TPM的PCR中。CRTM度量BootLoader把度量值扩展到PCR中,BootLoader度量OS把度量值扩展到PCR中。 + +#### 配置vTPM设备,使能度量启动 + +**一、安装swtpm和libtpms软件** + +swtpm提供了一个可集成到虚拟化环境中的TPM仿真器(TPM1.2和TPM2.0)。到目前为止,它已经集成到了QEMU中,同时也作为RunC中的原型系统。swtpm是利用libtpms来提供TPM1.2和TPM2.0的模拟功能。 +目前openEuler 22.03 LTS 版本中提供了libtpms和swtpm的源,可以直接使用yum命令安装。 + +```sh +# yum install libtpms swtpm swtpm-devel swtpm-tools + +``` + +**二、虚拟机配置vTPM设备** + +1. 虚拟机配置文件中添加如下配置: + + ```conf + + ... + + ... + + + + ... + + ... + + ``` + + >[!NOTE]说明 + >目前,openEuler 20.09 版本 AArch64 架构上的虚拟机可信启动不支持 ACPI 特性,所以虚拟机请勿配置 ACPI 特性,否则启动虚拟机后无法识别 vTPM 设备。AArch64 架构在openEuler 22.03 LTS 之前的版本,tpm model 配置为 \。 + +2. 创建虚拟机。 + + ```sh + # virsh define MeasuredBoot.xml + ``` + +3. 启动虚拟机 + + 启动虚拟机前需要使用chmod命令给目录/var/lib/swtpm-localca/赋予如下权限,否则libvirt无法拉起swtpm。 + + ```sh + # chmod -R 777 /var/lib/swtpm-localca/ + # + # virsh start MeasuredbootVM + ``` + +**三、确认度量启动使能成功** + +度量启动功能使能与否由vBIOS决定,目前 openEuler 22.03 LTS 版本中的vBIOS已经具备了度量启动的能力。若宿主机采用其他版本的edk2组件,请确认其是否支持度量启动功能。 + +使用root用户登录虚拟机,确认虚拟机中是否安装了tpm驱动、tpm2-tss协议栈及tpm2-tools工具。 +openEuler 22.03 LTS 版本中默认安装了tpm驱动(tpm_tis.ko)、tpm2-tss协议栈和tpm2-tools工具。若使用其他操作系统,可以使用如下命令检查是否安装了驱动和相关工具。 + +```sh +# lsmod |grep tpm +# tpm_tis 16384 0 +# +# yum list installed | grep -E 'tpm2-tss|tpm2-tools' +# +# yum install tpm2-tss tpm2-tools +``` + +可以使用tpm2_pcrread(低版本tpm2_tools中使用tpm2_pcrlist)命令列出所有的pcr值。 + +```sh +# tpm2_pcrread +sha1 : + 0 : fffdcae7cef57d93c5f64d1f9b7f1879275cff55 + 1 : 5387ba1d17bba5fdadb77621376250c2396c5413 + 2 : b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236 + 3 : b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236 + 4 : e5d40ace8bb38eb170c61682eb36a3020226d2c0 + 5 : 367f6ea79688062a6df5f4737ac17b69cd37fd61 + 6 : b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236 + 7 : 518bd167271fbb64589c61e43d8c0165861431d8 + 8 : af65222affd33ff779780c51fa8077485aca46d9 + 9 : 5905ec9fb508b0f30b2abf8787093f16ca608a5a + 10 : 0000000000000000000000000000000000000000 + 11 : 0000000000000000000000000000000000000000 + 12 : 0000000000000000000000000000000000000000 + 13 : 0000000000000000000000000000000000000000 + 14 : 0000000000000000000000000000000000000000 + 15 : 0000000000000000000000000000000000000000 + 16 : 0000000000000000000000000000000000000000 + 17 : ffffffffffffffffffffffffffffffffffffffff + 18 : ffffffffffffffffffffffffffffffffffffffff + 19 : ffffffffffffffffffffffffffffffffffffffff + 20 : ffffffffffffffffffffffffffffffffffffffff + 21 : ffffffffffffffffffffffffffffffffffffffff + 22 : ffffffffffffffffffffffffffffffffffffffff + 23 : 0000000000000000000000000000000000000000 +sha256 : + 0 : d020873038268904688cfe5b8ccf8b8d84c1a2892fc866847355f86f8066ea2d + 1 : 13cebccdb194dd916f2c0c41ec6832dfb15b41a9eb5229d33a25acb5ebc3f016 + 2 : 3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969 + 3 : 3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969 + 4 : 07f9074ccd4513ef1cafd7660f9afede422b679fd8ad99d25c0659eba07cc045 + 5 : ba34c80668f84407cd7f498e310cc4ac12ec6ec43ea8c93cebb2a688cf226aff + 6 : 3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969 + 7 : 65caf8dd1e0ea7a6347b635d2b379c93b9a1351edc2afc3ecda700e534eb3068 + 8 : f440af381b644231e7322babfd393808e8ebb3a692af57c0b3a5d162a6e2c118 + 9 : 54c08c8ba4706273f53f90085592f7b2e4eaafb8d433295b66b78d9754145cfc + 10 : 0000000000000000000000000000000000000000000000000000000000000000 + 11 : 0000000000000000000000000000000000000000000000000000000000000000 + 12 : 0000000000000000000000000000000000000000000000000000000000000000 + 13 : 0000000000000000000000000000000000000000000000000000000000000000 + 14 : 0000000000000000000000000000000000000000000000000000000000000000 + 15 : 0000000000000000000000000000000000000000000000000000000000000000 + 16 : 0000000000000000000000000000000000000000000000000000000000000000 + 17 : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + 18 : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + 19 : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + 20 : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + 21 : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + 22 : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + 23 : 0000000000000000000000000000000000000000000000000000000000000000 +``` diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/environment_preparation.md b/docs/zh/virtualization/virtualization_platform/virtualization/environment_preparation.md new file mode 100644 index 00000000..93b35466 --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/environment_preparation.md @@ -0,0 +1,366 @@ +# 准备使用环境 + +## 准备虚拟机镜像 + +### 概述 + +虚拟机镜像是一个文件,包含了已经完成安装并且可启动操作系统的虚拟磁盘。虚拟机镜像具有不同格式,常见的有raw格式和qcow2格式。qcow2格式镜像相比raw格式,具有占用更小的空间,支持快照、Copy-On-Write、AES加密、zlib压缩等特性,但性能略逊于raw格式镜像。镜像文件的制作借助于qemu-img工具,本节以qcow2格式镜像文件为例,介绍虚拟机镜像制作过程。 + +### 制作镜像 + +制作qcow2格式镜像文件的操作步骤如下: + +1. 使用root用户安装qemu-img软件包。 + + ```sh + # yum install -y qemu-img + ``` + +2. 使用qemu-img工具的create命令,创建镜像文件,命令格式为: + + ```sh + # qemu-img create -f -o + ``` + + 其中,各参数含义如下: + + - _imgFormat_:镜像格式,取值为raw, qcow2等。 + - _fileOption_:文件选项,用于设置镜像文件的特性,如指定后端镜像文件,压缩,加密等特性。 + - _fileName_:文件名称。 + - _diskSize_:磁盘大小,用于指定块磁盘设备的大小,支持的单位有K、M、G、T,分别代表KiB、MiB、GiB、TiB。 + + 例如,创建一个磁盘设备大小为4GB、格式为qcow2的镜像文件openEuler-image.qcow2,命令和回显如下: + + ```sh + # qemu-img create -f qcow2 openEuler-image.qcow2 4G + Formatting 'openEuler-image.qcow2', fmt=qcow2 size=4294967296 cluster_size=65536 lazy_refcounts=off refcount_bits=16 + ``` + +### 修改镜像磁盘空间大小 + +当虚拟机需要更大的磁盘空间时,可以使用qemu-img工具,修改虚拟机镜像磁盘空间的大小,修改方法如下。 + +1. 查询当前虚拟机镜像磁盘空间大小,命令如下: + + ```sh + # qemu-img info + ``` + + 例如,查询openEuler-image.qcow2镜像磁盘空间大小的命令和回显如下,说明该镜像磁盘空间大小为4GiB。 + + ```sh + # qemu-img info openEuler-image.qcow2 + image: openEuler-image.qcow2 + file format: qcow2 + virtual size: 4.0G (4294967296 bytes) + disk size: 196K + cluster_size: 65536 + Format specific information: + compat: 1.1 + lazy refcounts: false + refcount bits: 16 + corrupt: false + ``` + +2. 修改镜像磁盘空间大小,命令如下,其中imgFiLeName为镜像名称,“+”和“-”分别表示需要增加或减小的镜像磁盘空间大小,单位为K、M、G、T,代表KiB、MiB、GiB、TiB。 + + ```sh + # qemu-img resize [+|-] + ``` + + 例如,将上述openEuler-image.qcow2镜像磁盘空间大小扩展到24GiB,即在原来4GiB基础上增加20GiB,命令和回显如下: + + ```sh + # qemu-img resize openEuler-image.qcow2 +20G + Image resized. + ``` + +3. 查询修改后的镜像磁盘空间大小,确认是否修改成功,命令如下: + + ```sh + # qemu-img info + ``` + + 例如,上述openEuler-image.qcow2镜像磁盘空间已扩展到24GiB,命令和回显如下: + + ```sh + # qemu-img info openEuler-image.qcow2 + image: openEuler-image.qcow2 + file format: qcow2 + virtual size: 24G (25769803776 bytes) + disk size: 200K + cluster_size: 65536 + Format specific information: + compat: 1.1 + lazy refcounts: false + refcount bits: 16 + corrupt: false + ``` + +## 准备虚拟机网络 + +### 概述 + +为了使虚拟机可以与外部进行网络通信,需要为虚拟机配置网络环境。KVM虚拟化支持Linux网桥、Open vSwitch网桥等多种类型的网桥。如[图1](#fig1785384714917)所示,数据传输路径为“虚拟机 -\> 虚拟网卡设备 -\> Linux网桥或Open vSwitch网桥 -\> 物理网卡”。创建网桥,除了为虚拟机配置虚拟网卡设备外,为主机创建网桥是连接虚拟机网络的关键。 + +本节给出搭建Linux网桥和Open vSwitch网桥的方法,使虚拟机连接到网络,用户可以根据情况选择搭建网桥的类型。 + +**图 1** 虚拟网络结构图
+![](./figures/virtual-network-structure.png) + +### 搭建Linux网桥 + +以物理网卡eth0绑定到Linux网桥br0的操作为例,使用root用户执行如下命令搭建Linux网桥: + +1. 安装bridge-utils软件包。 + + Linux网桥通常通过brctl工具管理,其对应的安装包为bridge-utils,安装命令如下: + + ```sh + # yum install -y bridge-utils + ``` + +2. 创建网桥br0。 + + ```sh + # brctl addbr br0 + ``` + +3. 将物理网卡eth0绑定到Linux网桥。 + + ```sh + # brctl addif br0 eth0 + ``` + + >![!NOTE]说明 + >若在ssh远程工具中操作命令brctl addif br0 eth0,ssh远程连接会断开,需要到iBMC界面进行后续如下操作以完成虚拟化网路配置。 + +4. eth0与网桥连接后,不再需要IP地址,安装net-tools软件包,将eth0的IP设置为0.0.0.0。 + + ```sh + # yum install -y net-tools + # ifconfig eth0 0.0.0.0 + ``` + +5. 设置br0的IP地址。 + - 如果有DHCP服务器,可以通过dhclient设置动态IP地址。 + + ```sh + # dhclient br0 + ``` + + - 如果没有DHCP服务器,给br0配置静态IP,例如设置静态IP为192.168.1.2,子网掩码为255.255.255.0。 + + ```sh + # ifconfig br0 192.168.1.2 netmask 255.255.255.0 + ``` + +### 搭建Open vSwitch网桥 + +Open vSwitch网桥,具有更便捷的自动化编排能力。搭建Open vSwitch网桥需要安装网络虚拟化组件,这里介绍总体操作。 + +**一、安装Open vSwitch组件** + +使用Open vSwitch提供虚拟网络,需要安装Open vSwitch网络虚拟化组件,使用root用户执行如下命令: + +1. 安装Open vSwitch组件。 + + ```sh + # yum install -y openvswitch + ``` + +2. 启动Open vSwitch服务。 + + ```sh + # systemctl start openvswitch + ``` + +**二、确认安装是否成功** + +确认Open vSwitch组件是否安装成功。 + +1. 确认openvswitch组件是否安装成功。若安装成功,可以看到软件包相关信息,命令和回显如下: + + ```sh + $ rpm -qi openvswitch + Name : openvswitch + Version : 2.12.4 + Release : 3.oe2203SP4 + Architecture: x86_64 + Install Date: Tue 09 May 2023 10:58:53 AM CST + Group : Unspecified + Size : 7920016 + License : ASL 2.0 and ISC + Signature : RSA/SHA256, Wed 19 Apr 2023 09:40:31 AM CST, Key ID 007fb747fb37bc6f + Source RPM : openvswitch-2.12.4-3.oe2203SP4.src.rpm + Build Date : Wed 19 Apr 2023 09:39:49 AM CST + Build Host : dc-64g.compass-ci + Packager : http://openeuler.org + URL : http://www.openvswitch.org/ + Summary : Production Quality, Multilayer Open Virtual Switch + Description : + Open vSwitch is a production quality, multilayer virtual switch licensed under + the open source Apache 2.0 license. + ``` + +2. 查看Open vSwitch服务是否启动成功。若服务处于“Active”状态,说明服务启动成功,可以正常使用Open vSwitch提供的命令行工具,命令和回显如下: + + ```sh + $ systemctl status openvswitch + ● openvswitch.service - LSB: Open vSwitch switch + Loaded: loaded (/etc/rc.d/init.d/openvswitch; generated) + Active: active (running) since Sat 2019-08-17 09:47:14 CST; 4min 39s ago + Docs: man:systemd-sysv-generator(8) + Process: 54554 ExecStart=/etc/rc.d/init.d/openvswitch start (code=exited, status=0/SUCCESS) + Tasks: 4 (limit: 9830) + Memory: 22.0M + CGroup: /system.slice/openvswitch.service + ├─54580 ovsdb-server: monitoring pid 54581 (healthy) + ├─54581 ovsdb-server /etc/openvswitch/conf.db -vconsole:emer -vsyslog:err -vfile:info --remote=punix:/var/run/openvswitch/db.sock --private-key=db:Open_vSwitch,SSL,private_key --certificate> + ├─54602 ovs-vswitchd: monitoring pid 54603 (healthy) + └─54603 ovs-vswitchd unix:/var/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfile:info --mlockall --no-chdir --log-file=/var/log/openvswitch/ovs-vswitchd.log --pidfile=/var/run/open> + ``` + +**三、搭建Open vSwitch网桥** + +以创建Open vSwitch一层网桥br0为例,介绍搭建方法,使用root用户执行如下命令: + +1. 创建Open vSwitch网桥br0。 + + ```sh + # ovs-vsctl add-br br0 + ``` + +2. 将物理网卡eth0添加到br0。 + + ```sh + # ovs-vsctl add-port br0 eth0 + ``` + +3. eth0与网桥连接后,不再需要IP地址,将eth0的IP设置为0.0.0.0。 + + ```sh + # ifconfig eth0 0.0.0.0 + ``` + +4. 为OVS网桥br0分配IP。 + - 如果有DHCP服务器,可以通过dhclient设置动态IP地址。 + + ```sh + # dhclient br0 + ``` + + - 如果没有DHCP服务器,给br0配置静态IP,例如192.168.1.2。 + + ```sh + # ifconfig br0 192.168.1.2 + ``` + +## 准备引导固件 + +### 概述 + +针对不同的架构,引导的方式有所差异。x86支持UEFI(Unified Extensible Firmware Interface)和Legacy方式启动,AArch64仅支持UEFI方式启动。openEuler默认已安装BIOS启动对应的引导文件,不需要用户额外操作。所以这里仅介绍UEFI启动方式的安装方法。 + +统一的可扩展固件接口UEFI是一种全新类型的接口标准,用于开机自检、引导操作系统的启动,是传统BIOS的一种替代方案。EDK II是一套实现了UEFI标准的开源代码,在虚拟化场景中,通常利用EDK II工具集,通过UEFI的方式启动虚拟机。使用EDK II工具需要在虚拟机启动之前安装对应的软件包 ,本节介绍EDK II的安装方法。 + +### 安装方法 + +如果使用UEFI方式引导,需要安装工具集EDK II,AArch64架构对应的安装包为edk2-aarch64,x86架构对应的安装包为edk2-ovmf。这里以AArch64架构为例,给出具体的安装方法,x86架构仅需将edk2-aarch64替换为edk2-ovmf。 + +1. 安装edk软件包,使用root用户执行如下命令: + + 在AArch64架构下edk2的包名为edk2-aarch64 + + ```sh + # yum install -y edk2-aarch64 + ``` + + 在x86\_64架构下edk2的包名为edk2-ovmf + + ```sh + # yum install -y edk2-ovmf + ``` + +2. 查询edk软件是否安装成功,命令如下: + + 在AArch64架构下查询如下: + + ```sh + $ rpm -qi edk2-aarch64 + ``` + + 若edk软件安装成功,回显示例如下: + + ```text + Name : edk2-aarch64 + Version : 202011 + Release : 11.oe2203SP4 + Architecture: noarch + Install Date: Tue 09 May 2023 11:28:22 AM CST + Group : Unspecified + ``` + + 在x86\_64架构下查询如下: + + ```sh + $ rpm -qi edk2-ovmf + ``` + + 若edk软件安装成功,回显类似如下: + + ```text + Name : edk2-ovmf + Version : 202011 + Release : 11.oe2203SP4 + Architecture: noarch + Install Date: Tue 09 May 2023 11:06:06 AM CST + ``` + +## 非root用户配置 + +### 概述 + +openEuler虚拟化使用virsh管理虚拟机。如果希望在非root用户使用virsh命令管理虚拟机,在使用之前需要进行相关配置,这里给出配置指导。 + +### 操作指导 + +允许非root用户使用virsh命令管理虚拟机的配置操作如下,以下命令中的userName请改为实际的非root用户名称: + +1. 使用root用户登录主机。 + +2. 将非root用户添加到libvirt用户组。 + + ```sh + # usermod -a -G libvirt userName + ``` + +3. 切换到非root用户。 + + ```sh + # su userName + ``` + +4. 配置非root用户的环境变量。使用vim打开~/.bashrc文件。 + + ```sh + $ vim ~/.bashrc + ``` + + 并在末尾加上如下内容后保存。 + + ```sh + export LIBVIRT_DEFAULT_URI="qemu:///system" + ``` + + 执行如下命令,使配置生效。 + + ```sh + $ source ~/.bashrc + ``` + +5. 在虚拟机XML配置文件中的domain根元素中添加如下内容,使qemu-kvm进程可以访问磁盘镜像文件。 + + ```conf + + ``` diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP1.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP1.png new file mode 100644 index 0000000000000000000000000000000000000000..536e0618a3ab5b70937292205242a08237e34712 GIT binary patch literal 5880 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 Q-D<#pZ{Qy4?&H7y7onGH@c;k- literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP2.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP2.png new file mode 100644 index 0000000000000000000000000000000000000000..0557c8782960188dbe9d84a1d0e66c9b45d2b303 GIT binary patch literal 11246 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 literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP3.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP3.png new file mode 100644 index 0000000000000000000000000000000000000000..326fcf1e8d5e3c795ebcde286d8e0fef14bec7d1 GIT binary patch literal 8778 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 TXz>3Z(C?Dp-qf&R???X$y6hgT literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP4.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP4.png new file mode 100644 index 0000000000000000000000000000000000000000..bc77c038e1e3a5ec30d7ba4f805ca937792e9327 GIT binary patch literal 8734 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 literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP5.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP5.png new file mode 100644 index 0000000000000000000000000000000000000000..0f22b3cbd84f7c93f74898a926bc3e32f231667f GIT binary patch literal 8931 zcmeHt3sh5gy6?93!knsgY^&%{;k2~Y3d+_bNK_g^^C0p_Hc3cwcC2&8Gk4~muCva$ z>)y3yt*{{fz4!P0egE(K|2AiS_hI6S=YI1X001lAe{bhr0C&W-v z=&vQTy@~GtP4bt2LccsqiQ5wg0L|=Wiy!|F^!q;@dyhZ^faibk{VeItYsdtER}0_Y z8MnWXXc>>me{K6$8wU@Y1@%9^bnxr=3-@BGU+>?UYuG`ZZPrn?vg$RxSYZK7p%2c>UCT9

W#XCj)PQ~4j=~s5R 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 literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP6.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP6.png new file mode 100644 index 0000000000000000000000000000000000000000..08235013ca71f1ec51e9af2f143629d1a6132fe9 GIT binary patch literal 2782 zcmds3ZBUch6~2goida9!28HrbWokt&xUx!=fG9*^@e=_BOx2AdF+_PyVt^#Lqy3nR{w` z%60&n*}l`qyxji$v%3yM04#bkyFALm7X`S3q307a&hN;_A3J}VloyhEnurG*BQ{2$ zBcjm}n?fR^&>Od)H$^mRm(&5UAaVE3?Wq@z>V}i^73eu$``Tn*pX2|M{aIgx`brrO zKW%-Fy2J8kdB@(~nIyz;lJF%{OIPy(o>Qv#at5@^0NC#`S(k(2koX`F7ZUml5b}CM z>~)*bXykVXF=|=_>p^j(VZ;N>U21ecPiH-+8(-CpMCylnSVV>Ogo>g%V852^Xi}_l zPSxpiRJ(Ab7eiA3bZ;<>z!&dfN+?W8xh>aO=o`hxFhPhaV&s)qg(xsa30q7CPhzlH zj<6Y@K$r6-{Wpg3A0t;9zE*l^J+tW;xHC%b10F~|^uX9lZ0v&kgG)<2z_aF$r;OHx z1R`N@x43FLMJ*5lUtfXCF9P{X~~hXSM1 z`h8k4UF*v{!BESwXW`$EU3)F@xr12)(@871Iu4PUx0q|;$WzJ$rWmSTQiXE!h^ClR>@b=%V!`^UjG`=Guz1%qPcU!wPkos0#@WS7+dy&LPkozB^)tNoon~Od zjPU(H+`NCn=zpjDzmLSv^lSfLYI|)O7?`jS13>X&<@5gt=HqsYKtKc_e%g;F7RSzf z0^nV41>y|BJF0_y8-1N+TZ?;N;cX)$8h5grOOWf4ye0#xVKh?t& zwbQdH=qgtcowh=7cx~_s`0X3`APfw;}dmfMe z&>$*3_Y$FBGEtLdS*rD=fhxP^f>eE45;eFWRub{y_)W&4#mbb8!$|aQI`X&cy z6j!UytsTnoIh6gTB@!(|-~C}6^)Q;eK`*oDC#J)M76jdSM;>T=kuwK)hOG`=PY`TL=j*-zKu6fPIp*!69b&R%o-FyN=@aE zVkJy2uduX^0+|RYmX<+AV^M0_7q7^7s?y&Ev9hhiXeL1+({$&kRuR~oGq#>XFEeW` zIaMv6LuvtDGSqQA*PX!ALF;tA5RVM69!VLVn@}&~|5i~;C%09G;|h*mv8L3Mv51xM z6hSQ70gbrkkK~ev%v{Dn2REh%w{q*-H_ZZVy4jLsZ^Cs}Gp45|ZM5c-blG6`05d9g zD}K|-$jueUbEjdlf}Sb=mdocMm?XQ@l->)+3YxH~Y|at16q0fbZHE+Qvb>|DZnA-g ze^6s1I6mOoe`v@uA7m?YRH7TVY|%+wmHAI5RRz;nsBg2O6%A<_e#9Ak&_Sr)p-@*A zJd)F49q-B*)eoW{EpSPzYrZ6~X{YIOqcEnxoaiVK;`XWg>EoT()AQaT#V~>@4l5MJ zWoZ$fPS6MC#%!ok)#;kLeWyDR3$cl_s?kGJ@nzfPcGuH0H8Nelde`WfKKMbRD6O>P zWTq3&)SNFx&+v(bu~s%@h6p_w>NnPHjr}xSq0=HeNztQ$?F+vUkO?oqPLq1tiMJ9orC!0FlRoPXcsa{jdk z1|Tx+@-_g1%4%jA^WT%#xM7y%LVDa(yL(njsMSaQAs)WvaF`zJ_|d6Xi{dKW@)PV% M*t4@S{`X(~4Y#wd{r~^~ literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP7.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP7.png new file mode 100644 index 0000000000000000000000000000000000000000..f934521d59dd4a75449fcb2ca8abc54045b9102b GIT binary patch literal 6827 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 literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP8.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/CertEnrollP8.png new file mode 100644 index 0000000000000000000000000000000000000000..9a8158e3378bf25dee05b892cc60f424542455d7 GIT binary patch literal 9004 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 V*zbw|Z~@-j^7iJIq(A-Z{{i5@nG65` literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/OSBootFlow.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/OSBootFlow.png new file mode 100644 index 0000000000000000000000000000000000000000..f9c03c86df145636015efaeab4dc076f62754cd9 GIT binary patch literal 55015 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 L?!4SDR_**3)&=EX literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/kvm-architecture.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/kvm-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..62b13a899ef6eb7ab3e6b2d4a754396734e3b6b3 GIT binary patch literal 16018 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 S1pJPi@8ofdW7MP0;r|1UqGLG# literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/status-transition-diagram.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/status-transition-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..e29d998e78064672bfc3641c26c0eb086d585000 GIT binary patch literal 22222 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 E5A<&ZDF6Tf literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/virtual-network-structure.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/virtual-network-structure.png new file mode 100644 index 0000000000000000000000000000000000000000..7feec03aa9434c7b5ed4479cbae3f76e4d44f86b GIT binary patch literal 15979 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 z zc=Vm(s8N*LE(mr%*U==brx#y;E5gI76&fUMgnzVJH+MAyv-6p9(<4Nc6jTCE!2E-&m_xTx5Uq5O(V(`QI#Nv-(F z+FSmQwaF!`BN)V`#5p+CoxNYXOg}xRBPgApZ`5>1!IzvLKrrVYBaQp5D1&+bQ9*2L ze^eGX-szXmn;`|mHaUrPb!SI+qI>OdR5`bGm+o2(uRZ~r&b_Pfmii4^>n6n4sca+F z+0hT{2=@ zAoHqLS*D(t&CPvx(OKAA{hdi7XLyYJ!Tcw0oA|usD;0}n!=ppQWZrWzKP95H$HlST zc{&$jId#0d@~o1m30EHVD7jXfkfB$OX!qY-yIMMEKCiXsZ@U=WpyCRjK@ix(WB#&x zlQ4OOhMJ%T$+*kdI{^Nsx@e$a$q{av&Y+I?+f%*aCKS}Km_}uE4&U5s36}Y6MO(R8R>bst9A6Z_cwP0*GN^7 z{qU-z=wL^s4ChkcyWV3L$wjpVm;vc!YDSxEbe?n08V_IXm+95CVAZnd9pg7Wcl(e< z4V}X_2nSmLcq(xV{e+e1UBsPSK|s8E=BT5Yjm#l`(dlunz?)5?LI z!fjn?%;#bjRh~eo`aVjq)Vn#_zw1@c`RwYIj8mMtSMf1swS$hfLrePJ{x*hqyy23l z&a|GoYyRHA1xi9s;kBFgL_b5p%cEoFuG7e%2E>Hd-HgN5Jkr{L z#Hkaz?)3I=ZVO7#KK-cMYdTZP9F=OczarjhtVsF#!fvi-r*7pi-0ZQ#b~keC2(UH3RY)H zH~+5<1_Uf}qCw;!({i_2XYW<>Fs59KML?I<#al|mSJYqRpm@vjR08ZpqjwniT0V{P zyb1hc_5Bx%#n^@~Fmh4yzIUz8yl8b&z!vdNL~rGvE{ejEtCC?_4B*bkVB|jM!Tg7I zeC*&Lq((^Bo+8V#Eq;s0EL>6lr?XD>Dv4v`JVf*dP%&xgJ&GGFbpby(K2huNfmi6C zUIu#O&_W5tqAx~$0ssLLNA`X5ZxBDJ9^JKiIQP)mh(t3Wpr{LUpeJ2`QpNQ8^xfy| z;qy7oz0i5HA$=%|s;Ngv;wF4~+xfOY(on5SnvnXeDov{kE-P+J`dBM;y9?^9`KzIeb_Oma2CA}TQEBFw)jid+9Ff7?+H32jJ%^)@>CcBSy^f=%0A-AY%8A-=%ZT2!!^s+pmkqL*D+;55 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 FV1id93qSw> literal 0 HcmV?d00001 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/figures/zh-cn_image_0218587436.png b/docs/zh/virtualization/virtualization_platform/virtualization/figures/zh-cn_image_0218587436.png new file mode 100644 index 0000000000000000000000000000000000000000..a32856aa08e459ed0f51f8fcf4c2f51511c12095 GIT binary patch literal 1858 zcmaJ?Yfuwc6i&s85>P0^#--)#Pef1Ye11=n9(+-JsC{G=&lnWY8&;87K**plNEYkT!6#jRvVz zLfR^}j3LvB(RB6ljW`;+afMvDF+<5y(Sib@00SR5(4eFOGHBLo3BEx{d*hc6*0y7q z2E8#MGlaCaq*lwKATfrc5Sz~NRU#}V#O2Wu4ui*JErpm2gbOpcFyiOSK==#}-;W24 z4;qMut5W$flF;#3U?-%dlcbIh!+O1*uJ@y3cp8lGcs!WFgqciVVBt$-X-S2_S4((J zc#xok5?AX;HKv7Z9u+BACMl!=rf*Zw=wz~Yj``0*zhHoGE;+UNvT9g11EHqTE%DiGY}D* z9V`(uSqKv1@9)nNix~)06f6$$7a_<5R;ndPg;t49VAb!jqK{(vVjNYF7%s=K^%LET zO2*+F>^M;rS8qU7p*W_2-js%~{y=yxD>#(RWpO}wKO6O6 zj+iIn^27*-%?1(x)Zb!NA4q!~%l%(049LK?zW%4r6GuQiw&gq3g3UYKqgo(#9H_e5 zczhbTEX`7hNN%`xyduu$MAFQ2-M1(W+I$LqoALnP$U= z4QXlHk0m4|6z|;W=;Rc4&}@D(HrC(UJIlo-Iw9f9iZJi6=H0t@gRfJJMkAh_5FcL| z85#MVDM%nt_IGwZv{=F(I!bSzZg2O3pk*%3_bir;27?c`u-t03DijKWAj0ey2zb25 zLqjK9T5^oW3a=TNgWcWTMYZO&B*_|GvKDcBHiib}&UULyzjL*#i<}2MRaI4M zYhWIS#ZslFS{^(o-?OK_zW(0byNeq)<>c(Gs&b(;G&IP|=iRgr$0cckX#<`RUf^Use42H>K{BO_NjI`aRBi;p)Kzp9+# z>gqc3;zhQ%9qqyG+bNf#F$~+jZCkKd+_4CRi=JOyU2ULJsg{S?N}24}v9Z9JOWd3n ze?E7v4_|P;xw$#EEnO6LE5vKoS&>J>)~#C$ieJ5Yb$i>$4CnBJ)cwLlvDhxMZJ|3; zZk0DxG`*fvH^BMUWJ-vOyV}>cFtKxuhlfY>{-TplhK8gyCX%$hf zhnY+!fj|H+U0PdP>wLGT$5k2lI1G0_x^G{9oBOoZW5>!)rlY90K#+~&r8jo%+Ew(a z#bPnUTY*-F8=IP#0R>-=U<5IA?V3BBpP!$dot@sPso1+W!iUt^+uKjNySbyI!M7({`J&?!NG$3`Sa#Y2gAYPvz@Q%@4ki=N%Hpxv73*RqA3t@fc)puk z;f@{PX1kOfI&{d+&TdWY;N)R%Z|{h_imvk@z1D+pqx{E`(v;tOu3x9loW4w;R4N;X zi;JC#LRgL$YJ65iMgnT5&*#=x|JL;=BQ0%_eL?btfOW-&k;0l9uft5>yR;-Pc`R{n nS(%?uC_7# +![](./figures/virtualized-architecture.png) + +## 虚拟化架构 + +当前的主流虚拟化技术按照VMM(Virtual Machine Monitor)实现结构不同分为两种: + +- Hypervisor模型 + + 在这种模型中,VMM被看做是一个完备的操作系统,同时还具备虚拟化功能,VMM直接管理所有的物理资源,包括处理器、内存和I/O设备等。 + +- 宿主模型 + + 这种模型中,物理资源是由宿主机操作系统管理。宿主机操作系统是传统的操作系统,如Linux,Windows等,宿主机操作系统不提供虚拟化能力,提供虚拟化能力的VMM作为系统的一个驱动或者软件运行在宿主操作系统上,VMM通过调用host OS的服务获得资源,实现处理器,内存和I/O设备的模拟,这种模型的虚拟化实现有KVM、Virtual Box等。 + +KVM(Kernel-based Virtual Machine)即基于内核的虚拟机,是Linux的一个内核模块,该内核模块使Linux成为一个hypervisor。KVM架构如[图2](#fig310953013541)所示。KVM本身未模拟任何硬件设备,它用于使能硬件提供的虚拟化能力,比如Intel VT-x, AMD-V, ARM virtualization extensions等。主板、内存及I/O等设备的模拟由用户态的QEMU完成。用户态QEMU配合内核KVM模块共同完成虚拟机的硬件模拟,客户操作系统运行在QEMU和KVM模拟的硬件上。 + +**图 2** KVM架构图 +![](./figures/kvm-architecture.png) + +## 虚拟化组件 + +openEuler软件包中提供的虚拟化相关组件: + +- KVM:提供核心的虚拟化基础设施,使Linux系统成为一个hypervisor,支持多个虚拟机同时在该主机上运行。 +- QEMU:模拟处理器并提供一组设备模型,配合KVM实现基于硬件的虚拟化模拟加速。 +- Libvirt:为管理虚拟机提供工具集,主要包含统一、稳定、开放的应用程序接口(API)、守护进程 (Libvirtd)和一个默认命令行管理工具(virsh)。 +- Open vSwitch:为虚拟机提供虚拟网络的工具集,支持编程扩展,以及标准的管理接口和协议(如NetFlow, sFlow,IPFIX, RSPAN, CLI, LACP, 802.1ag)。 + +## 虚拟化特点 + +业界普遍认可虚拟化有以下特点: + +- 分区 + + 虚拟化可以对一台物理服务器进行软件逻辑分割,实现运行多台不同规格的虚拟机(虚拟服务器)。 + +- 隔离 + + 虚拟化能够模拟虚拟硬件,为虚拟机运行完整操作系统提供硬件条件,每个虚拟机内部操作系统都是独立的,互相隔离的。例如一台虚拟机的操作系统由于故障或者受到恶意破坏而崩溃,其他虚拟机内部的操作系统和应用不会受到任何影响。 + +- 封装性 + + 以虚拟机为粒度封装,优秀的封装性使得虚拟机比物理机更灵活,可以实现虚拟机的热迁移、快照、克隆等功能,实现数据中心的快速部署和自动化运维。 + +- 硬件无关 + + 经过虚拟化层的抽象后,虚拟机与底层的硬件没有直接的绑定关系,可以在其他服务器上不加修改地运行虚拟机。 + +## 虚拟化优势 + +虚拟化为数据中心的基础设施带来了众多优势: + +- 灵活性和可扩展性 + + 用户可以根据需求进行动态资源分配和回收,满足动态变化的业务需求,同时也可以根据不同的产品需求,规划不同的虚拟机规格,在不改变物理资源配置的情况下进行规模调整。 + +- 更高的可用性和更好的运维手段 + + 虚拟化提供热迁移、快照、热升级、容灾自动恢复等运维手段,可以在不影响用户的情况下对物理资源进行删除、升级或变更,提高了业务连续性,同时可以实现自动化运维。 + +- 提高安全性 + + 虚拟化提供了操作系统级的隔离,同时实现基于硬件提供的处理器操作特权级控制,相比简单的共享机制具有更高的安全性,可实现对数据和服务进行可控和安全的访问。 + +- 更高的资源利用率 + + 虚拟化可支持实现物理资源和资源池的动态共享,提高资源利用率。 + +## openEuler虚拟化 + +openEuler提供了支持AArch64和x86_64处理器架构的KVM虚拟化组件。 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/libcareplus.md b/docs/zh/virtualization/virtualization_platform/virtualization/libcareplus.md new file mode 100644 index 00000000..5b952fc1 --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/libcareplus.md @@ -0,0 +1,379 @@ +# LibcarePlus + +## 概述 + +LibcarePlus 是一个用户态进程热补丁框架,可以在不重启进程的情况下对 Linux 系统上运行的目标进程进行热补丁操作。热补丁可以应用于 CVE 漏洞修复,也可以应用于不中断应用服务的紧急 bug 修复。 + +## 软硬件要求 + +在 openEuler 上使用 LibcarePlus,需要满足一定的软硬件要求: + +- 当前LibcarePlus支持 x86 体系架构和arm64体系架构。 +- LibcarePlus 可以在任何支持安装 **libunwind**、 **elfutils** 以及 **binutils** 的 Linux 发行版系统上运行。 +- LibcarePlus 使用ptrace()系统调用,需要对应Linux发行版本的相关编译选项支持。 +- LibcarePlus 制作热补丁时,依赖原可执行文件的符号表,因此,请勿过早将符号表strip掉。 +- 对于开启selinux的Linux系统,需要自行适配对应的selinux规则。 + +## 注意事项和约束 + +使用 LibcarePlus,需遵循以下热补丁规范和约束: + +- 仅支持对 C 语言编写的代码,不支持汇编语言等。 +- 代码文件名必须符合 C 语言标识符命名规范:由字母(A-Z,a-z)、数字 (0-9)、下划线“_”组成;并且首字符不能是数字,但可以是字母或者下划线;不能包含“-”、“$”等特殊符号。 +- 支持增量补丁,即支持对进程打多个补丁,但补丁加卸载管理需使用者执行设计,一般遵循FILO规则。 +- 不支持补丁自动加载,对于特定进程,需使用者自行设计。 +- 支持补丁查询功能。 +- 静态函数补丁受限于系统中能找到该函数的符号表。 +- 热补丁为进程粒度,即动态库热补丁只能对调用这个动态库的进程打补丁。 +- 单个进程支持的补丁数受限于跳转指令的跳转范围和虚拟内存地址空洞大小,一般支持[1, 512]。 +- 对于TLS变量,仅支持修改IE模式的TLS变量。 +- 后续补丁不能使用之前补丁中定义的符号。 +- 以下场景不支持热补丁: + - 死循环函数、不退出函数、inline 函数、初始化函数、NMI 中断处理函数。 + - 替换全局变量。 + - 小于5字节的短函数。 + - 修改头文件。 + - 增加和删除目标函数的出参和入参。 + - 数据结构成员变化(新增、删除、修改)。 + - 修改包含 __LINE__ , __FILE__ 等gcc编译宏的 C 文件。 + - 修改 intel 矢量汇编指令。 + +## 安装 LibcarePlus + +### 安装软件依赖 + +LibcarePlus 运行依赖于 **libunwind**、 **elfutils** 和 **binutils**,在配置了 yum 源的 openEuler 系统上,可以参考如下命令安装 LibcarePlus 的依赖软件。 + +``` shell +# yum install -y binutils elfutils elfutils-libelf-devel libunwind-devel +``` + +#### 安装 LibcarePlus + +```shell +# yum install libcareplus libcareplus-devel -y +``` + +查看安装是否成功: + +``` shell +# libcare-ctl -h +usage: libcare-ctl [options] [args] + +Options: + -v - verbose mode + -h - this message + +Commands: + patch - apply patch to a user-space process + unpatch- unapply patch from a user-space process + info - show info on applied patches + +``` + +## 制作 LibcarePlus 热补丁 + +### 概述 + +LibcarePlus 支持如下方式制作热补丁: + +- 手动制作 +- 通过脚本制作 + +手动制作热补丁的过程繁琐,对于代码量较大的工程,例如QEMU,手动制作热补丁极其困难。建议使用 LibcarePlus 自带脚本一键式地生成热补丁文件。 + +#### 手动制作 + +本节以原文件 foo.c 和补丁文件 bar.c 为例,给出手动制作热补丁的指导。 + +1. 准备 C 语言编写的原文件和补丁文件。例如原文件 foo.c 和补丁文件 bar.c。 + +
+ 点击展开 foo.c +

+ + ``` c + // foo.c + #include + #include + + void print_hello(void) + { + printf("Hello world!\n"); + } + + int main(void) + { + while (1) { + print_hello(); + sleep(1); + } + } + ``` + +

+
+ +
+ 点击展开 bar.c +

+ + ``` c + // bar.c + #include + #include + + void print_hello(void) + { + printf("Hello world %s!\n", "being patched"); + } + + int main(void) + { + while (1) { + print_hello(); + sleep(1); + } + } + ``` + +

+
+ +2. 编译得到原文件和补丁文件的汇编文件 **foo.s** 和 **bar.s**,参考命令如下: + + ``` shell + # gcc -S foo.c + # gcc -S bar.c + # ls + bar.c bar.s foo.c foo.s + ``` + +3. 使用 **kpatch_gensrc** 对比 foo.s 和 bar.s 差异,生成包含原文件的汇编内容和差异内容的 foobar.s,参考命令如下: + + ``` shell + # sed -i 's/bar.c/foo.c/' bar.s + # kpatch_gensrc --os=rhel6 -i foo.s -i bar.s -o foobar.s --force-global + ``` + + 由于 **kpatch_gensrc** 默认对同一 C 语言原文件进行对比,所以对比前需要使用 sed 命令将补丁汇编文件 bar.s 中的 bar.c 改为原文件名称 foo.c。随后调用 **kpatch_gensrc**,指定输入文件为 foo.s 与 bar.s,输出文件为 foobar.s。 + +4. 编译原文件的汇编文件 foo.s 和生成的汇编文件 foobar.s,得到可执行文件 foo 和 foobar,参考命令如下: + + ``` shell + # gcc -o foo foo.s + # gcc -o foobar foobar.s -Wl,-q + ``` + + 链接选项 **-Wl, -q** 将保留foobar中的重定位节。 + +5. 利用 **kpatch_strip** 去除可执行程序 foo 和 foobar 的相同内容,保留制作热补丁所需要的内容。 + + ``` shell + # kpatch_strip --strip foobar foobar.stripped + # kpatch_strip --rel-fixup foo foobar.stripped + # strip --strip-unneeded foobar.stripped + # kpatch_strip --undo-link foo foobar.stripped + ``` + + 上述命令中的各参数含义为: + + - **--strip** 用于去除 foobar 中对于补丁制作无用的 section; + - **--rel-fixup** 用于修复补丁内所访问的变量以及函数的地址; + - **strip --strip-unneeded** 用于去除对于热补丁重定位操作无用的符号信息; + - **--undo-link** 用于将补丁内符号的地址从绝对地址更改为相对地址。 + +6. 制作热补丁文件。 + + 通过以上操作,已经得到了热补丁制作所需的主要内容。接下来需要使用 **kpatch_make** 将原可执行文件的 **Build ID** 以及 **kpatch_strip** 的输出文件 **foobar.stripped** 作为参数传递给 **kpatch_make**,最终生成热补丁文件,参考命令如下: + + ``` shell + # str=$(readelf -n foo | grep 'Build ID') + # substr=${str##* } + # kpatch_make -b $substr -i 0001 foobar.stripped -o foo.kpatch + # ls + bar.c bar.s foo foobar foobar.s foobar.stripped foo.c foo.kpatch foo.s + ``` + + 至此,就得到了patch ID为0001的热补丁文件 foo.kpatch。 + +#### 通过脚本制作 + +本节介绍如何利用 LibcarePlus 自带的 **libcare-patch-make** 脚本制作热补丁文件,仍以原文件 foo.c 和补丁文件 bar.c 为例。 + +1. 利用 diff 命令生成 foo.c 和 bar.c 的对比文件,命令如下所示: + + ``` shell + # diff -up foo.c bar.c > foo.patch + ``` + + foo.patch 文件内容如下所示: + +
+ 点击展开 foo.patch +

+ + ``` diff + --- foo.c 2020-12-09 15:39:51.159632075 +0800 + +++ bar.c 2020-12-09 15:40:03.818632220 +0800 + @@ -1,10 +1,10 @@ + -// foo.c + +// bar.c + #include + #include + + void print_hello(void) + { + - printf("Hello world!\n"); + + printf("Hello world %s!\n", "being patched"); + } + + int main(void) + ``` + +

+
+ +2. 编写编译 foo.c 的 Makefile 文件,具体如下所示: + +
+ 点击展开 Makefile +

+ + ``` makefile + all: foo + + foo: foo.c + $(CC) -o $@ $< + + clean: + rm -f foo + + install: foo + mkdir $$DESTDIR || : + cp foo $$DESTDIR + ``` + +

+
+ +3. 编写好 Makefile 之后,直接调用 **libcare-patch-make** 即可。若 **libcare-patch-make** 询问选择哪个文件进行打补丁操作,输入原文件名即可,具体如下所示: + + ``` shell + # libcare-patch-make --clean -i 0001 foo.patch + rm -f foo + BUILDING ORIGINAL CODE + /usr/local/bin/libcare-cc -o foo foo.c + INSTALLING ORIGINAL OBJECTS INTO /libcareplus/test/lpmake + mkdir $DESTDIR || : + cp foo $DESTDIR + applying foo.patch... + can't find file to patch at input line 3 + Perhaps you used the wrong -p or --strip option? + The text leading up to this was: + -------------------------- + |--- foo.c 2020-12-10 09:43:04.445375845 +0800 + |+++ bar.c 2020-12-10 09:48:36.778379648 +0800 + -------------------------- + File to patch: foo.c + patching file foo.c + BUILDING PATCHED CODE + /usr/local/bin/libcare-cc -o foo foo.c + INSTALLING PATCHED OBJECTS INTO /libcareplus/test/.lpmaketmp/patched + mkdir $DESTDIR || : + cp foo $DESTDIR + MAKING PATCHES + Fixing up relocation printf@@GLIBC_2.2.5+fffffffffffffffc + Fixing up relocation print_hello+0 + patch for /libcareplus/test/lpmake/foo is in /libcareplus/test/patchroot/700297b7bc56a11e1d5a6fb564c2a5bc5b282082.kpatch + ``` + + 执行成功之后,输出显示:热补丁文件位于当前目录的 **patchroot** 目录下,可执行文件则在 **lpmake** 目录下。脚本生成的热补丁文件默认是采用 Build ID 作为热补丁文件的文件名。 + +## 应用 LibcarePlus 热补丁 + +本节以原文件 **foo.c** 和补丁文件 **bar.c** 为例,介绍 LibcarePlus 热补丁的应用指导。 + +### 前期准备 + +应用 LibcarePlus 热补丁之前,需要提前准备好原可执行程序 foo、以及热补丁文件 foo.kpatch。 + +### 加载热补丁 + +本节介绍应用 LibcarePlus 热补丁的具体流程。 + +1. 首先在第一个 shell 窗口运行需要打补丁的可执行程序,如下所示: + + ``` shell + # ./lpmake/foo + Hello world! + Hello world! + Hello world! + ``` + +2. 随后在第二个 shell 窗口运行 **libcare-ctl** 应用热补丁,命令如下所示: + + ``` shell + # libcare-ctl -v patch -p $(pidof foo) ./patchroot/BuildID.kpatch + ``` + + 若此时热补丁应用成功,第二个 shell 窗口会有如下输出: + + ``` shell + 1 patch hunk(s) have been successfully applied to PID '10999' + ``` + + 而第一个 shell 窗口内运行的目标进程则会出现如下输出: + + ``` shell + Hello world! + Hello world! + Hello world being patched! + Hello world being patched! + ``` + +### 查询补丁 + +本节介绍查询LibcarePlus热补丁的具体流程。 + +1. 在第二个shell窗口执行如下命令: + + ```shell + # libcare-ctl info -p $(pidof foo) + + ``` + + 此时若进程存在已经加载的热补丁,则第二个shell窗口会有如下输出: + + ```shell + Pid: 551763 + Target: foo + Build id: df05a25bdadd282812d3ee5f0a460e69038575de + Applied patch number: 1 + Patch id: 0001 + ``` + +### 卸载热补丁 + +本节介绍卸载 LibcarePlus 热补丁的具体流程。 + +1. 在第二个 shell 窗口执行如下命令: + + ``` shell + # libcare-ctl unpatch -p $(pidof foo) -i 0001 + ``` + + 此时若热补丁卸载成功,第二个 shell 窗口会有如下输出: + + ``` shell + 1 patch hunk(s) were successfully cancelled from PID '10999' + ``` + +2. 第一个 shell 窗口内运行的目标进程则会出现如下输出: + + ``` shell + Hello world being patched! + Hello world being patched! + Hello world! + Hello world! + ``` diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/managing_devices.md b/docs/zh/virtualization/virtualization_platform/virtualization/managing_devices.md new file mode 100644 index 00000000..b3512648 --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/managing_devices.md @@ -0,0 +1,877 @@ +# 管理设备 + +## 配置虚拟机PCIe控制器 + +### 概述 + +虚拟机内部的网卡、磁盘控制器、PCIe直通设备都需要挂接到PCIe Root Port下面,每个Root Port对应一个PCIe插槽。Root Port的下挂设备支持热插拔,但是Root Port本身不支持热插拔,因此需要用户考虑设备热插的需求,规划虚拟机需要预留的最大PCIe Root Port数量,在虚拟机启动之前完成Root Port的静态配置。 + +### 配置PCIe Root、PCIe Root Port和PCIe-PCI-Bridge + +虚拟机PCIe控制器通过XML文件进行配置,PCIe Root、PCIe Root Port和PCIe-PCI-Bridge对应XML中的model分别为pcie-root、pcie-root-port、pcie-to-pci-bridge。 + +- 简化配置方法 + + 在虚拟机的XML文件中写入以下内容,controller的其他属性由libvirt自动填充: + + ```conf + + + + + + + ``` + + 其中:由于pcie-root和pcie-to-pci-bridge分别占用1个index,因此最终的index等于需要的Root Port数量+1。 + +- 完整配置方法 + + 在虚拟机的XML文件中写入以下内容: + + ```conf + + + + +
+ + + +
+ + + + +
+ + + ``` + + 其中: + + - Root Port的chassis和port属性必须依次递增,由于中间插入一个PCIe-PCI-Bridge,chassis编号跳过2,但是port编号仍然连续。 + - Root Port的address function的取值范围为0x0\~0x7。 + - 每个slot下最多挂8个function,挂满之后需要递增slot编号。 + + 由于完整配置方法相对复杂,建议采用简化配置方法。 + +## 管理虚拟磁盘 + +### 概述 + +虚拟磁盘类型主要包含virtio-blk、virtio-scsi、vhost-scsi等。virtio-blk模拟的是一种block设备,virtio-scsi和vhost-scsi模拟的是一种scsi设备。 + +- virtio-blk:普通系统盘和数据盘可用,该种配置下虚拟磁盘在虚拟机内部呈现为vd\[a-z\]或vd\[a-z\]\[a-z\]。 +- virtio-scsi:普通系统盘和数据盘建议选用,该种配置下虚拟磁盘在虚拟机内部呈现为sd\[a-z\]或sd\[a-z\]\[a-z\]。 +- vhost-scsi:对性能要求高的虚拟磁盘建议选用,该种配置下虚拟磁盘在虚拟机内部呈现为sd\[a-z\]或sd\[a-z\]\[a-z\]。 + +### 操作步骤 + +虚拟磁盘的配置步骤,请参见“虚拟机配置 > 存储设备”。本节以virtio-scsi磁盘为例,介绍挂载和卸载虚拟磁盘的简单方法。 + +- 挂载virtio-scsi磁盘: + + 使用virsh attach-device命令挂载virtio-scsi虚拟磁盘: + + ```sh + $ virsh attach-device + ``` + + 上述命令可以为虚拟机在线挂载磁盘,其中磁盘信息由attach-device.xml文件指定。下面是一个attach-device.xml文件的例子: + + ```conf + ### attach-device.xml ### + + + + + +
+ + ``` + + 通过上述命令挂载的磁盘,在虚拟机关机重启后失效。如果需要为虚拟机持久化挂载虚拟磁盘,需要使用带--config参数的virsh attach-device命令。 + +- 卸载virtio-scsi磁盘: + + 通过在线挂载的磁盘,如果不需要再使用,可以通过virsh detach-device命令动态卸载: + + ```sh + $ virsh detach-device + ``` + + 其中,detach-device.xml指定了需要卸载的磁盘的XML信息,与动态挂载时的XML信息保持一致。 + +## 管理虚拟网卡 + +### 概述 + +虚拟网卡类型主要包含virtio-net、vhost-net、vhost-user等。用户在创建虚拟机后,可能会有挂载或者卸载虚拟网卡的需求。openEuler提供了网卡热插拔的功能,通过网卡热插拔,能够改变网络的吞吐量,提高系统的灵活性和扩展性。 + +### 操作步骤 + +虚拟网卡的配置步骤,请参见“虚拟机配置 > 网络设备”。本节以vhost-net网卡为例,介绍挂载和卸载虚拟网卡的简单方法。 + +- 挂载vhost-net网卡: + + 使用virsh attach-device命令挂载vhost-net虚拟网卡: + + ```sh + $ virsh attach-device + ``` + + 上述命令可以为虚拟机在线挂载vhost-net网卡,其中网卡信息由attach-device.xml文件指定。下面是一个attach-device.xml文件的例子: + + ```sh + ### attach-device.xml ### + + + + + + + + ``` + + 通过上述命令挂载的vhost-net网卡,在虚拟机关机重启后失效。如果需要为虚拟机持久化挂载虚拟网卡,需要使用带--config参数的virsh attach-device命令。 + +- 卸载vhost-net网卡: + + 通过在线挂载的网卡,如果不需要再使用,可以通过virsh detach-device命令动态卸载: + + ```sh + $ virsh detach-device + ``` + + 其中,detach-device.xml指定了需要卸载虚拟网卡的XML信息,与动态挂载时的XML信息保持一致。 + +## 配置虚拟串口 + +### 概述 + +在虚拟化环境下,由于管理和业务的需求,虚拟机与宿主机需要互相通信。但在云管理系统复杂的网络架构下,运行在管理平面的服务与运行在业务平面的虚拟机之间,不能简单的进行三层网络互相通信,导致服务部署和信息收集不够快速。因此需要提供虚拟串口,来达到虚拟机与宿主机之间互相通信的目的。 通过在虚拟机的XML配置文件中增加相应串口的配置项,可以实现虚拟机与宿主机之间的互相通信。 + +### 操作步骤 + +Linux虚拟机串口控制台,即虚拟机串口连接到宿主机的一个伪终端设备,通过宿主机的设备间接实现对虚拟机的交互式操作。在该场景下串口需配置为pty类型,本节介绍pty型串口的配置方法。 + +- 在虚拟机的XML配置文件中"devices"节点下添加如下所示的虚拟串口配置项: + + ```conf + + + + + + ``` + +- 使用virsh console命令连接到正在运行的虚拟机的pty串口。 + + ```sh + $ virsh console + ``` + +- 如果要确保没有遗漏任何串口消息,请在启动虚拟机时使用--console选项连接到串口。 + + ```sh + $ virsh start --console + ``` + +## 管理设备直通 + +设备直通技术是指将host上的物理设备直接呈现给一台虚拟机,虚拟机可以直接访问该设备资源的一种使用方式。使用设备直通的方式可以让虚拟机获得良好的I/O性能。 + +当前设备直通使用的是VFIO方式,按照直通的设备类型可以分为PCI直通和SR-IOV直通两种类型。 + +### PCI直通 + +PCI直通是指将host上的物理PCI设备直接呈现给一台虚拟机,供虚拟机直接访问的一种使用方式。PCI直通使用了vfio设备直通方式,为虚拟机配置PCI直通的xml配置如下: + +```conf + + + +
+ + +
+ +``` + +**表 1** PCI直通设备配置项 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数名

+

说明

+

取值

+

hostdev.source.address.domain

+

host OS上的PCI设备的domain号。

+

>=0

+

hostdev.source.address.bus

+

host OS上的PCI设备bus号。

+

>=1

+

hostdev.source.address.slot

+

host OS上的PCI设备的device号。

+

>=0

+

hostdev.source.address.function

+

host OS上的PCI设备的function号。

+

>=0

+

hostdev.driver.name

+

可选配置项,指定PCI直通的后端驱动。

+

vfio(默认配置项)

+

hostdev.rom

+

直通设备的ROM是否呈现给虚拟机。

+

可以配置为“on/off”,默认为“on”。

+
  • on:表示直通设备的ROM呈现给虚拟机,例如:直通网卡虚拟机需要从该网卡的PXE启动时,可以将该选项配置为“on”,HBA卡直通虚拟机需要从ROM中启动时可以将该选项配置为“on”。
  • off:表示直通设备的ROM不呈现给虚拟机。
+

hostdev.address type

+

PCI设备呈现的Guest内bdf号。

+

`[0x03-0x1e](./slot范围`)

+

说明:

+
  • domain为域信息,bus为总线号,slot为插槽号,function为功能。
  • 除了slot插槽号,这里其余均默认为0。
  • 第一个slot插槽号0x00被系统占用,第二个slot号0x01被IDE控制器和USB控制器占用,第三个slot号0x02被video占用。
  • 最后一个slot号0x1f被pvchannel占用。
+
+ +>[!NOTE]说明 +>VFIO直通方式的最小直通单位是iommu\_group,host根据硬件上的ACS位,来划分iommu\_group。同一个iommu\_group中的设备只允许直通给同一台虚拟机(一个PCI设备上的若干个function,如果属于同一个iommu\_group,只允许直通给一个虚拟机使用)。 + +### SR-IOV直通 + +#### 概述 + +SR-IOV(Single Root I/O Virtualizaiton)是一种基于硬件的虚拟化解决方案,通过SR-IOV技术可以将一个PF(Physical Function)虚拟成多个VF(Virtual Function),每个VF都可以单独被直通给一个虚拟机,极大地提升了硬件资源利用率和虚拟机的I/O性能。一种典型的应用场景就是网卡SR-IOV设备直通,利用SR-IOV技术可以将一个物理网卡(PF)虚拟成多个VF网卡,再把VF直通给虚拟机使用。 + +- SR-IOV需要物理硬件支持,使用SR-IOV前请确保要直通的硬件设备支持该能力,并且Host侧的设备驱动程序工作在SR-IOV模式下。 +- 查询网卡具体型号的办法如下: + 例如下述回显,第一列为网卡的PCI号,19e5:1822为网卡的厂商号设备号。 + + ```sh + # lspci | grep Ether + 05:00.0 Ethernet controller: Device 19e5:1822 (rev 45) + 07:00.0 Ethernet controller: Device 19e5:1822 (rev 45) + 09:00.0 Ethernet controller: Device 19e5:1822 (rev 45) + 0b:00.0 Ethernet controller: Device 19e5:1822 (rev 45) + 81:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01) + 81:00.1 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01) + ``` + +#### 操作方法 + +请使用root用户按照如下操作步骤配置SR-IOV直通网卡: + +1. 开启网卡的SR-IOV模式。 + 1. 请确保Guest OS有网卡供应商提供的VF驱动支持,否则Guest OS内VF无法正常工作。 + 2. 在host OS的BIOS中开启SMMU/IOMMU的支持。不同厂家服务器的开启方式可能不同,请参考各服务器的帮助文档。 + 3. HOST驱动配置,开启SR-IOV的VF模式。这里以Hi1822网卡为例,开启16个VF。 + + ```sh + echo 16 > /sys/class/net/ethX/device/sriov_numvfs + ``` + +2. 获取PF和VF的PCI BDF信息。 + 1. 获取当前单板上的网卡资源列表,参考命令如下: + + ```sh + # lspci | grep Eth + 03:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (4*25GE) (rev 45) + 04:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (4*25GE) (rev 45) + 05:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (4*25GE) (rev 45) + 06:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (4*25GE) (rev 45) + 7d:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Device a222 (rev 20) + 7d:00.1 Ethernet controller: Huawei Technologies Co., Ltd. Device a222 (rev 20) + 7d:00.2 Ethernet controller: Huawei Technologies Co., Ltd. Device a221 (rev 20) + 7d:00.3 Ethernet controller: Huawei Technologies Co., Ltd. Device a221 (rev 20) + ``` + + 2. 查看VF的PCI BDF信息,参考命令如下: + + ```sh + # lspci | grep "Virtual Function" + 03:00.1 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.2 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.3 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.4 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.5 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.6 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:00.7 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:01.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:01.1 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + 03:01.2 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family Virtual Function (rev 45) + ``` + + 3. 选择一个可用的VF,根据其BDF信息将其配置写入虚拟机的配置文件中。以03:00.1设备为例,对应的bus号是03,slot号是00,function号是1。 + +3. 识别和管理PF/VF对应关系。 + 1. 识别PF对应的VF关系,以PF 03.00.0为例: + + ```sh + # ls -l /sys/bus/pci/devices/0000\:03\:00.0/ + ``` + + 可显示如下的软链接信息,根据信息可以获得其对应的VF编号(virtfnX)和PCI BDF号。 + + 2. 识别VF对应的PF关系,以VF 03:00.1为例: + + ```sh + # ls -l /sys/bus/pci/devices/0000\:03\:00.1/ + ``` + + 可显示下述软链接信息,即可获得其对应PF的PCI BDF号。 + + ```sh + lrwxrwxrwx 1 root root 0 Mar 28 22:44 physfn -> ../0000:03:00.0 + ``` + + 3. 获知PF/VF对应的网卡设备名称,例如: + + ```sh + # ls /sys/bus/pci/devices/0000:03:00.0/net + eth0 + ``` + + 4. 设置VF的mac/vlan/qos信息,确保VF在直通之前处于UP状态。以VF 03:00.1为例,假设PF为eth0,VF编号为0。 + + ```sh + # ip link set eth0 vf 0 mac 90:E2:BA:21:XX:XX # 设置mac地址 + # ifconfig eth0 up + # ip link set eth0 vf 0 rate 100 # 设置VF出口速率,单位Mbps + # ip link show eth0 # 查看mac/vlan/qos信息,确认设置成功 + ``` + +4. 挂载SR-IOV网卡到虚拟机中。 + + 创建虚拟机时,在虚拟机配置文件中增加SR-IOV直通的配置项。 + + ```conf + + + +
+ + + + + + ``` + + **表 2** SR-IOV配置选项说明 + + + + + + + + + + + + + + + + + + + + + + + + +

参数名

+

说明

+

取值

+

hostdev.managed

+

libvirt处理PCI设备的两种模式。

+

no:默认配置,表示直通设备由用户自行管理。

+

yes:表示直通设备由libvirt管理。SR-IOV直通场景需要配置为yes。

+

hostdev.source.address.bus

+

host OS上的PCI设备bus号。

+

>=1

+

hostdev.source.address.slot

+

host OS上的PCI设备device号。

+

>=0

+

hostdev.source.address.function

+

host OS上的PCI设备function号。

+

>=0

+
+ +关闭SR-IOV功能。 +在虚拟机使用完毕后(虚拟机关机,所有的VF均没有在使用中的时候),若要关闭SR-IOV功能。执行操作如下: +这里以Hi1822网卡(eth0对应PF的网口名称)为例: + +```sh +echo 0 > /sys/class/net/eth0/device/sriov_numvfs + ``` + +#### HPRE加速器SR-IOV直通 + +加速器引擎是TaiShan 200服务器基于Kunpeng 920处理器提供的硬件加速解决方案。HPRE加速器用于加速SSL/TLS应用,可以显著降低处理器消耗,提高处理器效率。 +在鲲鹏服务器上,需要把主机Host上的HPRE加速器的VF直通给虚拟机,供虚拟机内部业务使用。 + +**表 3** HPRE加速器说明 + +| 项目 | 说明 | +|-------------|-----------------------------------------------------------------------------------------------------| +| 设备名称 | Hi1620 on-chip RSA/DH security algorithm accelerator (HPRE engine) | +| 功能 | 模幂运算、RSA密钥对运算、DH计算、部分大数辅助运算(模幂、模乘、取模、乘法、模逆、素数测试、互质测试) | +| VendorID | 0x19E5 | +| PF DeviceID | 0xA258 | +| VF DeviceID | 0xA259 | +| 最大VF数量 | 一个HPRE PF最多支持创建63个VF | + +当虚拟机正在使用VF设备时,不允许卸载Host上的驱动,加速器不支持热插拔。 +VF操作(VFNUMS为0表示关闭VF,hpre_num用来标识具体的加速器设备): + +```sh +echo $VFNUMS > /sys/class/uacce/hisi_hpre-$hpre_num/device/sriov_numvfs +``` + +### vDPA直通 + +#### 概述 + +vDPA直通是将host上的一个设备对接到vDPA框架,通过vhost-vdpa驱动对外呈现字符设备,并将该字符设备配置给虚拟机,供虚拟机使用的一种方式。 + +vDPA直通提供了与VFIO直通持平的IO性能,同时提供了virtio设备的灵活性,可以支持vDPA直通设备热迁移。 + +配合SR-IOV方案,vDPA直通可以实现一个物理网卡(PF)虚拟成多个VF网卡,再将VF网卡对接到vDPA框架后,提供给虚拟机使用。 + +#### 操作方法 + +请使用root用户按照如下操作步骤配置vDPA设备直通: + +1. 创建及配置VF设备,详细流程参考SR-IOV直通中的第1-3步,以下述virtio-net设备为例(08:00.6和08:00.7为PF,其余为创建的VF): + + ```shell + # lspci | grep -i Eth | grep Virtio + 08:00.6 Ethernet controller: Virtio: Virtio network device + 08:00.7 Ethernet controller: Virtio: Virtio network device + 08:01.1 Ethernet controller: Virtio: Virtio network device + 08:01.2 Ethernet controller: Virtio: Virtio network device + 08:01.3 Ethernet controller: Virtio: Virtio network device + 08:01.4 Ethernet controller: Virtio: Virtio network device + 08:01.5 Ethernet controller: Virtio: Virtio network device + 08:01.6 Ethernet controller: Virtio: Virtio network device + 08:01.7 Ethernet controller: Virtio: Virtio network device + 08:02.0 Ethernet controller: Virtio: Virtio network device + 08:02.1 Ethernet controller: Virtio: Virtio network device + 08:02.2 Ethernet controller: Virtio: Virtio network device + ``` + +2. 解绑VF驱动,并绑定对应硬件的厂商vdpa驱动。 + + ```shell + echo 0000:08:01.1 > /sys/bus/pci/devices/0000\:08\:01.1/driver/unbind + echo 0000:08:01.2 > /sys/bus/pci/devices/0000\:08\:01.2/driver/unbind + echo 0000:08:01.3 > /sys/bus/pci/devices/0000\:08\:01.3/driver/unbind + echo 0000:08:01.4 > /sys/bus/pci/devices/0000\:08\:01.4/driver/unbind + echo 0000:08:01.5 > /sys/bus/pci/devices/0000\:08\:01.5/driver/unbind + echo -n "1af4 1000" > /sys/bus/pci/drivers/vender_vdpa/new_id + ``` + +3. 绑定vDPA设备后,可以通过vdpa命令查询vdpa管理设备列表。 + + ```shell + # vdpa mgmtdev show + pci/0000:08:01.1: + supported_classes net + pci/0000:08:01.2: + supported_classes net + pci/0000:08:01.3: + supported_classes net + pci/0000:08:01.4: + supported_classes net + pci/0000:08:01.5: + supported_classes net + ``` + +4. 完成vdpa设备的创建后,创建vhost-vDPA设备。 + + ```shell + vdpa dev add name vdpa0 mgmtdev pci/0000:08:01.1 + vdpa dev add name vdpa1 mgmtdev pci/0000:08:01.2 + vdpa dev add name vdpa2 mgmtdev pci/0000:08:01.3 + vdpa dev add name vdpa3 mgmtdev pci/0000:08:01.4 + vdpa dev add name vdpa4 mgmtdev pci/0000:08:01.5 + ``` + +5. 完成vhost-vDPA的设备创建后,可以通过vdpa命令查询vdpa设备列表;也可以通过libvirt命令查询环境的vhost-vDPA设备信息。 + + ```shell + # vdpa dev show + vdpa0: type network mgmtdev pci/0000:08:01.1 vendor_id 6900 max_vqs 3 max_vq_size 256 + vdpa1: type network mgmtdev pci/0000:08:01.2 vendor_id 6900 max_vqs 3 max_vq_size 256 + vdpa2: type network mgmtdev pci/0000:08:01.3 vendor_id 6900 max_vqs 3 max_vq_size 256 + vdpa3: type network mgmtdev pci/0000:08:01.4 vendor_id 6900 max_vqs 3 max_vq_size 256 + vdpa4: type network mgmtdev pci/0000:08:01.5 vendor_id 6900 max_vqs 3 max_vq_size 256 + + # virsh nodedev-list vdpa + vdpa_vdpa0 + vdpa_vdpa1 + vdpa_vdpa2 + vdpa_vdpa3 + vdpa_vdpa4 + + # virsh nodedev-dumpxml vdpa_vdpa0 + + vdpa_vdpa0 + /sys/devices/pci0000:00/0000:00:0c.0/0000:08:01.1/vdpa0 + pci_0000_08_01_1 + + vhost_vdpa + + + /dev/vhost-vdpa-0 + + + ``` + +6. 挂载vDPA设备到虚拟机中。 + + 创建虚拟机时,在虚拟机配置文件中增加vDPA直通设备的配置项: + + ```xml + + + + + + ``` + + **表 4** vDPA配置选项说明 + + + + + + + + + + + + + + + + +
+

参数名

+
+

说明

+
+

取值

+
+

hostdev.source.dev

+
+

host上vhost-vdpa字符设备的路径。

+
+

/dev/vhost-vdpa-x

+
+ + >[!NOTE]说明 + >根据各硬件厂商的设计不同,创建/配置VF、绑定厂商vdpa驱动等流程如有差异,请以各厂商流程为准。 + +## 管理虚拟机USB + +为了方便在虚拟机内部使用USBkey设备、USB海量存储设备等USB设备,openEuler提供了USB设备直通的功能。用户可以通过USB直通和热插拔相关接口给虚拟机配置直通USB设备、或者在虚拟机处于运行的状态下热插/热拔USB设备。 + +### 配置USB控制器 + +#### 概述 + +USB控制器是为虚拟机上的USB设备提供具体USB功能的虚拟控制器设备,在虚拟机内部使用USB设备必须给虚拟机配置USB控制器。当前openEuler支持如下三种USB控制器: + +- UHCI(Universal Host Controller Interface):通用主机控制器接口,也称为USB 1.1主机控制器规范。 +- EHCI(Enhanced Host Controller Interface):增强主机控制器接口,也称为USB 2.0主机控制器规范。 +- xHCI(eXtensible Host Controller Interface):可扩展主机控制器接口,也称为USB 3.0主机控制器规范。 + +#### 注意事项 + +- 主机服务器上需存在支持USB 1.1、USB 2.0和USB 3.0标准的USB控制器硬件和模块。 +- 为虚拟机配置USB控制器时,请按照USB 1.1、USB 2.0到USB 3.0的顺序来配置。 +- 一个xHCI控制器有8个端口,最多可以挂载4个USB 3.0设备和4个USB 2.0设备。一个EHCI控制器有6个端口,最多可以挂载6个USB2.0设备。一个UHCI控制器有2个端口,最多可以挂载2个USB 1.1设备。 +- 每台虚拟机支持配置多种类型的USB控制器,且每种类型可配置多个。 +- 不支持热插拔USB控制器。 +- 若虚拟机没有安装USB 3.0的驱动,可能无法识别xHCI控制器,USB 3.0驱动下载和安装方法请参见对应OS发行商官方说明。 +- 为了不影响操作系统的兼容性,为虚拟机配置USB接口的tablet设备时,请指定USB控制器bus号为0(默认挂载到USB 1.1控制器上)。 + +#### 配置方法 + +这里介绍为虚拟机配置USB控制器的配置内容说明。建议同时配置USB 1.1、USB 2.0和USB 3.0,做到同时兼容三种设备。 + +USB 1.1控制器(UHCI)的XML配置项为: + +```conf + + +``` + +USB 2.0控制器(EHCI)的XML配置为: + +```conf + + +``` + +USB 3.0控制器(xHCI)的XML配置为: + +```conf + + +``` + +### 配置USB直通设备 + +#### 概述 + +当虚拟机配置好USB控制器后,就可以通过设备直通的方式将主机上的物理USB设备挂载到虚拟机内部供虚拟机使用。在虚拟化场景下,除了支持静态配置以外还同时支持USB设备的热插/拔操作,即在虚拟机处于运行状态的时候挂载/卸载USB设备。 + +#### 注意事项 + +- 一个USB设备只能直通给一台虚拟机使用 +- 配置了直通USB设备的虚拟机不支持热迁移 +- 虚拟机配置文件中直通的USB设备不存在时,虚拟机会创建失败 +- 对一个正在读写的USB存储设备进行强制热拔操作有可能会损坏USB设备内的文件 + +#### 配置说明 + +这里介绍为虚拟机配置USB设备的配置内容说明。 + +USB设备的XML描述: + +```conf + + +
+ +
+ +``` + +- \
,其中,m表示该USB设备在主机上的bus地址,n表示device ID编号。 +- \
表示该USB设备要挂载到虚拟机指定的USB控制器。其中x表示控制器ID,与虚拟机所配置的USB控制器index编号相对应,y表示port地址。用户配置直通USB设备的时候需要配置这个字段,确保设备挂载的控制器与预期相符。 + +#### 配置方法 + +配置USB直通的步骤如下: + +1. 为虚拟机配置USB控制器,配置方法请参见“虚拟机配置 > 配置USB控制器”。 +2. 查询主机上的USB设备信息。 + + 通过lsusb命令(需要安装usbutils软件包)查询主机上的USB设备信息,包含bus地址、device地址、设备厂商ID、设备ID和产品描述信息等。例如: + + ```sh + $ lsusb + ``` + + ```sh + Bus 008 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub + Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub + Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub + Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub + Bus 006 Device 002: ID 0bda:0411 Realtek Semiconductor Corp. + Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub + Bus 005 Device 003: ID 136b:0003 STEC + Bus 005 Device 002: ID 0bda:5411 Realtek Semiconductor Corp. + Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub + Bus 001 Device 003: ID 12d1:0003 Huawei Technologies Co., Ltd. + Bus 001 Device 002: ID 0bda:5411 Realtek Semiconductor Corp. + Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub + Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub + ``` + +3. 准备USB设备的XML描述文件,注意在设备热拔之前,请确保USB设备当前不在使用当中,否则可能造成数据丢失。 +4. 执行热插、热拔命令。 + + 假设虚拟机名称为openEulerVM,对应的配置文件为usb.xml。 + + - 热插USB设备,只对当前运行的虚拟机有效,虚拟机冷重启后需要重新配置。 + + ```sh + $ virsh attach-device openEulerVM usb.xml --live + ``` + + - 热插USB设备,持久化该配置,即该虚拟机重启后该设备会自动直通给该虚拟机使用。 + + ```sh + $ virsh attach-device openEulerVM usb.xml --config + ``` + + - 热拔USB设备,只对当前运行的虚拟机有效,持久化配置的USB设备在虚拟机重启后USB设备会自动直通给该虚拟机。 + + ```sh + $ virsh detach-device openEulerVM usb.xml --live + ``` + + - 热拔USB设备,持久化该配置。 + + ```sh + $ virsh detach-device openEulerVM usb.xml --config + ``` + +## 管理快照 + +### 概述 + +虚拟机在使用过程中可能由于病毒对系统的破坏、系统文件被误删除或误格式化等原因造成虚拟机系统损坏导致系统无法启动。为了使损坏的系统快速恢复,openEuler提供了存储快照功能。openEuler可以在用户不感知的情况下制作虚拟机在某一时刻的快照(制作通常只需要几秒钟),该快照能帮助用户将磁盘快速恢复到某一时刻的状态,例如系统损坏后能快速恢复系统,从而提升系统可靠性。 + +>[!NOTE]说明 +>当前存储快照只支持raw、qcow2格式镜像,不支持block块设备。 + +### 操作步骤 + +制作虚拟机存储快照的操作步骤如下: + +1. 登录主机,通过virsh domblklist命令查询虚拟机使用的磁盘。 + + ```sh + $ virsh domblklist openEulerVM + Target Source + --------------------------------------------- + vda /mnt/openEuler-image.qcow2 + ``` + +2. 创建虚拟机磁盘快照_openEuler-snapshot1.qcow2_,命令及回显如下: + + ```sh + $ virsh snapshot-create-as --domain openEulerVM --disk-only --diskspec vda,snapshot=external,file=/mnt/openEuler-snapshot1.qcow2 --atomic + Domain snapshot 1582605802 created + ``` + +3. 磁盘快照查询操作。 + + ```sh + $ virsh snapshot-list openEulerVM + Name Creation Time State + --------------------------------------------------------- + 1582605802 2020-02-25 12:43:22 +0800 disk-snapshot + ``` + +## 配置磁盘IO悬挂 + +### 总体介绍 + +#### 概述 + +存储故障(比如存储断链)场景下,物理磁盘的IO错误,通过虚拟化层传给虚拟机前端,虚拟机内部收到IO错误,可能导致虚拟机内部的用户文件系统变成read-only状态,需要重启虚拟机或者用户手动恢复,这会给用户带来额外的工作量。 + +这种情况下,虚拟化平台提供了一种磁盘IO悬挂的能力,即当存储故障时,虚拟机IO下发到主机侧时将IO悬挂住,在悬挂时间内不对虚拟机内部返回IO错误,这样虚拟机内部的文件系统就不会因为IO错误而变为只读状态,而是呈现为Hang住;同时虚拟机后端按指定的悬挂间隔对IO进行重试。如果存储故障在悬挂时间内恢复正常,悬挂住的IO即可恢复落盘,虚拟机内部文件系统自动恢复运行,不需要重启虚拟机;如果存储故障在悬挂时间内未能恢复正常,则上报错误给虚拟机内部,通知给用户。 + +#### 应用场景 + +使用可能会发生存储面链路断链的云盘作为虚拟磁盘后端的场景。 + +#### 注意事项和约束限制 + +- 磁盘IO悬挂仅支持virtio-blk或virtio-scsi类型的虚拟磁盘。 + +- 磁盘IO悬挂的虚拟磁盘后端一般为可能会发生存储面链路断链的云盘。 + +- 磁盘IO悬挂可对读写IO错误分别使能,同一磁盘的读写IO错误重试间隔和超时时间使用相同配置。 + +- 磁盘IO悬挂重试间隔不包含主机侧实际读写IO的开销,即两次IO重试操作实际间隔会大于配置的IO错误重试间隔。 + +- 磁盘IO悬挂无法区分IO错误的具体类型(如存储断链、扇区坏道、预留冲突等),只要硬件返回IO错误,就会进行悬挂处理。 + +- 磁盘IO悬挂时,虚拟机内部IO不会返回,fdisk等访问磁盘的系统命令会卡住,虚拟机内部依赖该命令返回的业务也会一直卡住。 + +- 磁盘IO悬挂时,IO无法正常落盘,可能会导致虚拟机无法优雅关机,需要强制关机。 + +- 磁盘IO悬挂时,无法读取磁盘数据,会造成虚拟机无法正常重启,需要先将虚拟机强制关机,等待存储故障恢复后再重新启动虚拟机。 + +- 存储故障发生后,虽然存在磁盘IO悬挂,依然解决不了以下问题: + + 1. 存储相关高级特性执行失败 + + 高级特性包括:虚拟磁盘热插、虚拟磁盘热拔、创建虚拟磁盘、虚拟机启动、虚拟机关机、虚拟机强制关机、虚拟机休眠、虚拟机唤醒、虚拟机存储热迁移、虚拟机存储热迁移取消、虚拟机创建存储快照、虚拟机存储快照合并、查询虚拟机磁盘容量、磁盘在线扩容、插入虚拟光驱、弹出虚拟机光驱。 + + 2. 虚拟机生命周期执行失败 + +- 配置了磁盘IO悬挂的虚拟机发起热迁移时,应该在目的端磁盘的XML配置中带上与源端相同的磁盘IO悬挂配置。 + +### 磁盘IO悬挂配置 + +#### Qemu命令行配置 + +磁盘IO悬挂功能通过在虚拟磁盘设备上指定`werror=retry` `rerror=retry`进行使能,使用`retry_interval`和`retry_timeout`进行重试策略的配置。`retry_interval`为IO错误重试的间隔,配置范围为0-MAX_LONG,单位为毫秒,未配置时使用默认值1000ms;`retry_timeout`为IO错误重试超时时间,配置范围为0-MAX_LONG,0值表示不会发生超时,单位为毫秒,未配置时使用默认值0。 + +virtio-blk磁盘的磁盘IO悬挂配置如下: + +```shell +-drive file=/path/to/your/storage,format=raw,if=none,id=drive-virtio-disk0,cache=none,aio=native \ +-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x6,\ +drive=drive-virtio-disk0,id=virtio-disk0,write-cache=on,\ +werror=retry,rerror=retry,retry_interval=2000,retry_timeout=10000 +``` + +virtio-scsi磁盘的磁盘IO悬挂配置如下: + +```shell +-drive file=/path/to/your/storage,format=raw,if=none,id=drive-scsi0-0-0-0,cache=none,aio=native \ +-device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,\ +device_id=drive-scsi0-0-0-0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,write-cache=on,\ +werror=retry,rerror=retry,retry_interval=2000,retry_timeout=10000 +``` + +#### xml配置方式 + +磁盘IO悬挂功能通过在磁盘xml配置中指定`error_policy='retry'` `rerror_policy='retry'`进行使能。主要是配置上`retry_interval`和`retry_timeout`的值。`retry_interval`为IO错误重试的间隔,配置范围为0-MAX_LONG,单位为毫秒,未配置时使用默认值1000ms;`retry_timeout`为IO错误重试超时时间,配置范围为0-MAX_LONG,0值表示不会发生超时,单位为毫秒,未配置时使用默认值0。 + +virtio-blk磁盘的磁盘IO悬挂xml配置如下: + +```xml + + + + + + +``` + +virtio-scsi磁盘的磁盘IO悬挂xml配置如下: + +```xml + + + + + +
+ +``` diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/managing_vms.md b/docs/zh/virtualization/virtualization_platform/virtualization/managing_vms.md new file mode 100644 index 00000000..ff83d081 --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/managing_vms.md @@ -0,0 +1,788 @@ +# 管理虚拟机 + +## 虚拟机生命周期 + +### 总体介绍 + +#### 概述 + +为了更好地利用硬件资源,降低成本,用户需要合理地管理虚拟机。本节介绍虚拟机生命周期过程中的基本操作,包括虚拟机创建、使用、删除等,指导用户更好地管理虚拟机。 + +#### 虚拟机状态 + +虚拟机主要有如下几种状态: + +- 未定义(undefined):虚拟机未定义或未创建,即libvirt认为该虚拟机不存在。 +- 关闭状态(shut off):虚拟机已经被定义但未运行,或者虚拟机被终止。 +- 运行中(running):虚拟机处于运行状态。 +- 暂停(paused):虚拟机运行被挂起,其运行状态被临时保存在内存中,可以恢复到运行状态。 +- 保存(saved):与暂停(paused)状态类似,其运行状态被保存在持久性存储介质中,可以恢复到运行状态。 +- 崩溃(crashed):通常是由于内部错误导致虚拟机崩溃,不可恢复到运行状态。 + +#### 状态转换 + +虚拟机不同状态之间可以相互转换,但必须满足一定规则。虚拟机不同状态之间的转换常用规则如[图1](#fig671014583483)所示。 + +**图 1*- 状态转换图 +![](./figures/status-transition-diagram.png) + +#### 虚拟机标识 + +在libvirt中,完成创建的虚拟机实例称作一个“domain”,其描述了虚拟机的CPU、内存、网络设备、存储设备等各种资源的配置信息。在同一个主机上,每个domain具有唯一标识,通过虚拟机名称Name、UUID、Id表示,对应含义请参见[表1](#table84397266483)。在虚拟机生命周期期间,可以通过虚拟机标识对特定虚拟机进行操作。 + +**表 1*- domain标识说明 + + + + + + + + + + + + + + + + +

标识

+

含义

+

Name

+

虚拟机名称

+

UUID

+

通用唯一识别码

+

Id

+

虚拟机运行标识

+
说明:

关闭状态的虚拟机无此标识。

+
+
+ +>[!NOTE]说明 +>可通过virsh命令查询虚拟机Id和UUID,操作方法请参见[查询虚拟机信息](#查询虚拟机信息)章节内容。 + +### 管理命令 + +#### 概述 + +用户可以使用virsh命令工具管理虚拟机生命周期。本节介绍生命周期相关的命令以指导用户使用。 + +#### 前提条件 + +- 执行虚拟机生命周期操作之前,需要查询虚拟机状态以确定可以执行对应操作。状态之间的基本转换关系请参见"总体介绍"中的"状态转换"的内容。 +- 具备管理员权限。 +- 准备好虚拟机XML配置文件。 + +#### 命令使用说明 + +用户可以使用virsh命令管理虚拟机生命周期,命令格式为: + +```sh +virsh +``` + +各参数含义如下: + +- _operate_:管理虚拟机生命周期对应操作,例如创建、销毁、启动等。 +- _obj_:命令操作对象,如指定需要操作的虚拟机。 +- _options_:命令选项,该参数可选。 + +虚拟机生命周期管理各命令如[表2](#table389518422611)所示。其中VMInstance为虚拟机名称、虚拟机ID或者虚拟机UUID,XMLFile是虚拟机XML配置文件,DumpFile为转储文件,请根据实际情况修改。 + +**表 2*- 虚拟机生命周期管理命令 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

命令

+

含义

+

virsh define <XMLFile>

+

定义持久化虚拟机,定义完成后虚拟机处于关闭状态,虚拟机被看作为一个domain实例

+

virsh create <XMLFile>

+

创建一个临时性虚拟机,创建完成后虚拟机处于运行状态

+

virsh start <VMInstance>

+

启动虚拟机

+

virsh shutdown <VMInstance>

+

关闭虚拟机。启动虚拟机关机流程,若关机失败可使用强制关闭

+

virsh destroy <VMInstance>

+

强制关闭虚拟机

+

virsh reboot <VMInstance>

+

重启虚拟机

+

virsh save <VMInstance> <DumpFile>

+

将虚拟机的运行状态转储到文件中

+

virsh restore <DumpFile>

+

从虚拟机状态转储文件恢复虚拟机

+

virsh suspend <VMInstance>

+

暂停虚拟机的运行,使虚拟机处于paused状态

+

virsh resume <VMInstance>

+

唤醒虚拟机,将处于paused状态的虚拟机恢复到运行状态

+

virsh undefine <VMInstance>

+

销毁持久性虚拟机,虚拟机生命周期完结,不能继续对该虚拟机继续操作

+
+ +### 示例 + +本节给出虚拟机生命周期管理相关命令的示例。 + +- 创建虚拟机 + + 虚拟机XML配置文件为openEulerVM.xml,命令和回显如下: + + ```sh + # virsh define openEulerVM.xml + Domain openEulerVM defined from openEulerVM.xml + ``` + +- 启动虚拟机 + + 启动名称为openEulerVM的虚拟机,命令和回显如下: + + ```sh + # virsh start openEulerVM + Domain openEulerVM started + ``` + +- 重启虚拟机 + + 重启名称为openEulerVM的虚拟机,命令和回显如下: + + ```sh + # virsh reboot openEulerVM + Domain openEulerVM is being rebooted + ``` + +- 关闭虚拟机 + + 关闭名称为openEulerVM的虚拟机,命令和回显如下: + + ```sh + # virsh shutdown openEulerVM + Domain openEulerVM is being shutdown + ``` + +- 销毁虚拟机 + - 若虚拟机启动时未使用nvram文件,销毁虚拟机命令如下: + + ```sh + # virsh undefine + ``` + + - 若虚拟机启动时使用了nvram文件,销毁该虚拟机需要指定nvram的处理策略,命令如下: + + ```sh + # virsh undefine + ``` + + 其中\为销毁虚拟机的策略,可取值: + + nvram:销毁虚拟机的同时删除其对应的nvram文件。 + + keep-nvram:销毁虚拟机,但保留其对应的nvram文件。 + + 例如,删除虚拟机openEulerVM及其nvram文件,命令和回显如下: + + ```sh + # virsh undefine openEulerVM --nvram + Domain openEulerVM has been undefined + ``` + +## 在线修改虚拟机配置 + +### 概述 + +虚拟机创建之后用户可以修改虚拟机的配置信息,称为在线修改虚拟机配置。在线修改配置以后,新的虚拟机配置文件会被持久化,并在虚拟机关闭、重新启动后生效。 + +修改虚拟机配置命令格式如下: + +```sh +virsh edit +``` + +virsh edit命令通过编辑“domain”对应的XML配置文件,完成对虚拟机配置的更新。virsh edit使用vi程序作为默认的编辑器,可以通过修改环境变量“EDITOR”或“VISUAL”指定编辑器类型。virsh edit默认优先使用“VISUAL”环境变量指定的文本编辑器。 + +### 操作步骤 + +1. (可选)设置virsh edit命令的编辑器为vim。 + + ```sh + # export VISUAL=vim + ``` + +2. 使用virsh edit打开虚拟机名称为openEulerVM对应的XML配置文件。 + + ```sh + # virsh edit openEulerVM + ``` + +3. 修改虚拟机配置文件。 +4. 保存虚拟机配置文件并退出。 +5. 关闭虚拟机。 + + ```sh + # virsh shutdown openEulerVM + ``` + +6. 启动虚拟机使配置修改生效。 + + ```sh + # virsh start openEulerVM + ``` + +## 查询虚拟机信息 + +### 概述 + +管理员在管理虚拟机的过程中经常需要知道一些虚拟机信息,libvirt提供了一套命令行工具用于查询虚拟机的相关信息。本章介绍相关命令的使用方法,便于管理员来获取虚拟机的各种信息。 + +#### 前提条件 + +查询虚拟机信息需要: + +- libvirtd服务处于运行状态。 + +- 命令行操作需要拥有管理员权限。 + +### 查询主机上的虚拟机信息 + +- 查询主机上处于运行和暂停状态的虚拟机列表。 + + ```sh + # virsh list + ``` + + 例如,下述回显说明当前主机上存在3台虚拟机,其中openEulerVM01、openEulerVM02处于运行状态,openEulerVM03处于暂停状态。 + + ```text + Id Name State + ---------------------------------------------------- + 39 openEulerVM01 running + 40 openEulerVM02 running + 69 openEulerVM03 paused + ``` + +- 查询主机上已经定义的所有虚拟机信息列表。 + + ```sh + # virsh list --all + ``` + + 例如,下述回显说明当前主机上定义了4台虚拟机,其中虚拟机openEulerVM01处于运行状态,openEulerVM02处于暂停状态,openEulerVM03和openEulerVM04处于关机状态。 + + ```text + Id Name State + ---------------------------------------------------- + 39 openEulerVM01 running + 69 openEulerVM02 paused + - openEulerVM03 shut off + - openEulerVM04 shut off + ``` + +#### 查询虚拟机基本信息 + +Libvirt组件提供了一组查询虚拟机状态信息的命令,包括虚拟机运行状态、设备信息或者调度属性等,使用方法请参见表3。 + +**表 3*- 查询虚拟机基本信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

查询的信息内容

+

命令行

+

说明

+

基本信息

+

virsh dominfo <VMInstance>

+

包括虚拟机ID、UUID,虚拟机规格等信息。

+

当前状态

+

virsh domstate <VMInstance>

+

可以使用--reason选项查询虚拟机变为当前状态的原因。

+

调度信息

+

virsh schedinfo <VMInstance>

+

包括vCPU份额信息。

+

vCPU数目

+

virsh vcpucount <VMInstance>

+

查询虚拟机vCPU的个数。

+

虚拟块设备状态

+

virsh domblkstat <VMInstance>

+

查询块设备名称可以使用virsh domblklist命令。

+

虚拟网卡状态

+

virsh domifstat <VMInstance> <interface>

+

查询网卡名称可以使用virsh domiflist命令。

+

I/O线程

+

virsh iothreadinfo <VMInstance>

+

查询虚拟机I/O线程及其CPU亲和性信息

+
+ +#### 示例 + +- 使用virsh dominfo查询一个创建好的虚拟机的基本信息,从查询结果可知,虚拟机ID为5,UUID为ab472210-db8c-4018-9b3e-fc5319a769f7,内存大小为8GiB,vCPU数目为4个等。 + + ```sh + # virsh dominfo openEulerVM + Id: 5 + Name: openEulerVM + UUID: ab472210-db8c-4018-9b3e-fc5319a769f7 + OS Type: hvm + State: running + CPU(s): 4 + CPU time: 6.8s + Max memory: 8388608 KiB + Used memory: 8388608 KiB + Persistent: no + Autostart: disable + Managed save: no + Security model: none + Security DOI: 0 + ``` + +- 使用virsh domstate查询虚拟机的当前状态,从查询结果可知,虚拟机openEulerVM当前处于运行状态。 + + ```sh + # virsh domstate openEulerVM + running + ``` + +- 使用virsh schedinfo查询虚拟机的调度信息,从查询结果可知,虚拟机CPU预留份额为1024。 + + ```sh + # virsh schedinfo openEulerVM + Scheduler : posix + cpu_shares : 1024 + vcpu_period : 100000 + vcpu_quota : -1 + emulator_period: 100000 + emulator_quota : -1 + global_period : 100000 + global_quota : -1 + iothread_period: 100000 + iothread_quota : -1 + ``` + +- 使用virsh vcpucount查询虚拟机的vCPU数目,从查询结果可知,虚拟机有4个CPU。 + + ```sh + # virsh vcpucount openEulerVM + maximum live 4 + current live 4 + ``` + +- 使用virsh domblklist查询虚拟机磁盘设备信息,从查询结果可知,虚拟机有2个磁盘,sda是qcow2格式的虚拟磁盘,sdb是一个cdrom设备。 + + ```sh + # virsh domblklist openEulerVM + Target Source + --------------------------------------------------------------------- + sda /home/openeuler/vm/openEuler_aarch64.qcow2 + sdb /home/openeuler/vm/openEuler-22.03-LTS-SP4-aarch64-dvd.iso + ``` + +- 使用virsh domiflist查询虚拟机网卡信息,从查询结果可知,虚拟机有1张网卡,对应的后端是vnet0在主机br0网桥上,MAC地址为00:05:fe:d4:f1:cc。 + + ```sh + # virsh domiflist openEulerVM + Interface Type Source Model MAC + ------------------------------------------------------- + vnet0 bridge br0 virtio 00:05:fe:d4:f1:cc + ``` + +- 使用virsh iothreadinfo查询虚拟机I/O线程信息,从查询结果可知虚拟机有5个I/O线程,在物理CPU7-10上进行调度。 + + ```sh + # virsh iothreadinfo openEulerVM + IOThread ID CPU Affinity + --------------------------------------------------- + 3 7-10 + 4 7-10 + 5 7-10 + 1 7-10 + 2 7-10 + ``` + +## 登录虚拟机 + +本章介绍使用VNC登录虚拟机的方法。 + +### 使用VNC密码登录 + +#### 概述 + +当虚拟机操作系统安装部署完成之后,用户可以通过VNC协议远程登录虚拟机,从而对虚拟机进行管理操作。 + +#### 前提条件 + +使用RealVNC、TightVNC等客户端登录虚拟机,在登录虚拟机之前需要获取如下信息: + +- 虚拟机所在主机的IP地址。 +- 确保客户端所在的环境可以访问到主机的网络。 +- 虚拟机的VNC侦听端口,该端口一般在客户机启动时自动分配,一般为5900 + x(x为正整数,按照虚拟机启动的顺序递增,且5900对用户不可见)。 +- 如果VNC设置了密码,还需要获取虚拟机的VNC密码。 + + >[!NOTE]说明 + >为虚拟机VNC配置密码,需要编辑虚拟机XML配置文件,即为graphics元素新增一个passwd属性,属性的值为要配置的密码。例如,将虚拟机的VNC密码配置为n8VfjbFK的XML配置参考如下: + > + >```conf + > + > + > + >``` + +#### 操作步骤 + +1. 查询虚拟机使用的VNC端口号。例如名称为openEulerVM的虚拟机,命令如下: + + ```sh + # virsh vncdisplay openEulerVM + :3 + ``` + + >[!NOTE]说明 + >登录 VNC 需要配置防火墙规则,允许 VNC 端口的连接。参考命令如下,其中X为数值“5900 + 端口号” ,例如本例中为5903。 + > + >```sh + >firewall-cmd --zone=public --add-port=X/tcp + >``` + +2. 打开VncViewer软件,输入主机IP和端口号。格式为“主机IP:端口号”,例如:“10.133.205.53:3”。 +3. 单击“确定”输入VNC密码(可选),登录到虚拟机VNC进行操作。 + +### 配置VNC-TLS登录 + +#### 概述 + +VNC服务端和客户端默认采用明文方式进行数据传输,因此通信内容可能被第三方截获。为了提升安全性,openEuler支持VNC服务端配置TLS模式进行加密认证。TLS(Transport Layer Security)即传输层安全,可以实现VNC服务端和客户端之间加密通信,从而防止通信内容被第三方截获。 + +>[!NOTE]说明 +> +>- 使用TLS加密认证模式需要VNC客户端支持TLS模式(例如TigerVNC),否则无法连接到VNC客户端。 +>- TLS加密认证模式配置粒度为主机服务器级别,开启该特性后,主机上正在运行的所有虚拟机对应的VNC客户端都将开启TLS加密认证模式。 + +#### 操作步骤 + +VNC开启TLS加密认证模式的操作步骤如下: + +1. 登录VNC服务端所在主机,开启或修改服务端配置文件/etc/libvirt/qemu.conf中对应的配置项。相关配置内容如下所示: + + ```conf + vnc_listen = "x.x.x.x" # "x.x.x.x"为VNC的侦听地址,请用户根据实际配置,VNC服务端只允许该地址或地址段范围内的客户端连接请求 + vnc_tls = 1 # 配置为1,表示开启VNC TLS支持 + vnc_tls_x509_cert_dir = "/etc/pki/libvirt-vnc" #指定证书存放的路径为/etc/pki/libvirt-vnc + vnc_tls_x509_verify = 1 #配置为1,表示TLS认证使用X509证书 + ``` + +2. 为VNC创建证书和私钥文件。此处以GNU TLS为例进行说明。 + + >[!NOTE]说明 + >使用GNU TLS,请提前安装好gnu-utils软件包。 + + 1. 制作证书颁发机构CA(Certificate Authority)的证书文件。 + + ```sh + # certtool --generate-privkey > ca-key.pem + ``` + + 2. 制作自签名的CA证书公私钥。其中Your organization name为机构名,由用户指定。 + + ```sh + # cat > ca.info< server.info< server-key.pem + # certtool --generate-certificate \ + --load-ca-certificate ca-cert.pem \ + --load-ca-privkey ca-key.pem \ + --load-privkey server-key.pem \ + --template server.info \ + --outfile server-cert.pem + ``` + + 上述生成文件,server-key.pem是VNC服务端的私钥,server-cert.pem是VNC服务端的公钥。 + + 4. 为VNC客户端颁发证书。 + + ```sh + # cat > client.info< client-key.pem + # certtool --generate-certificate \ + --load-ca-certificate ca-cert.pem \ + --load-ca-privkey ca-key.pem \ + --load-privkey client-key.pem \ + --template client.info \ + --outfile client-cert.pem + ``` + + 上述生成文件,client-key.pem是VNC客户端的私钥,client-cert.pem是VNC客户端的公钥,生成的公私钥对需要拷贝到VNC客户端。 + +3. 关闭需要被登录的虚拟机,重启VNC服务端所在主机的libvirtd服务。 + + ```sh + # systemctl restart libvirtd + ``` + +4. 将生成的服务端证书放置到VNC服务端指定目录并将证书的权限改为只允许当前用户读写。 + + ```sh + # sudo mkdir -m 750 /etc/pki/libvirt-vnc + # cp ca-cert.pem /etc/pki/libvirt-vnc/ca-cert.pem + # cp server-cert.pem /etc/pki/libvirt-vnc/server-cert.pem + # cp server-key.pem /etc/pki/libvirt-vnc/server-key.pem + # chmod 0600 /etc/pki/libvirt-vnc/* + ``` + +5. 将生成的客户端证书ca-cert.pem,client-cert.pem和client-key.pem拷贝到VNC客户端。配置VNC客户端的TLS证书后即可使用VNC TLS登录。 + + >[!NOTE]说明 + >- VNC客户端证书的配置请参见各客户端对应的使用说明,由用户自行配置。 + >- 登录虚拟机的方式请参见“使用VNC密码登录”。 + +## 虚拟机安全启动 + +### 总体介绍 + +#### 概述 + +安全启动(Secure Boot)就是利用公私钥对启动部件进行签名和验证。启动过程中,前一个部件验证后一个部件的数字签名,验证通过后,运行后一个部件,验证不通过则启动失败。安全启动的作用是检测设备启动阶段固件(Firmware)以及软件是否被篡改,防止恶意软件侵入和修改。通过安全启动可以保证系统启动过程中各个部件的完整性,防止没有经过认证的部件被加载运行,从而防止对系统及用户数据产生安全威胁。安全启动是在UEFI启动方式上实现的,Legacy启动方式不支持安全启动。根据UEFI规定,主板出厂的时候可以内置一些可靠的公钥。任何想要在这块主板上加载的操作系统或者硬件驱动程序,都必须通过这些公钥的认证。物理机上的安全启动由物理BIOS完成,虚拟机的安全启动通过软件模拟。虚拟机安全启动流程与host安全启动流程一致,都遵循开源UEFI规范。虚拟化平台上的UEFI由edk组件提供,虚拟机启动时qemu将UEFI镜像映射到内存中,为虚拟机模拟固件启动流程,安全启动正是虚拟机启动过程中edk提供的一个安全保护能力,用来保护虚拟机OS内核不被篡改。安全启动验签顺序:UEFI BIOS->shim->grub->vmlinuz(依次验签通过并加载)。 + +| 中文 | 英文 | 缩略语 | 中文定义/描述 | +| :-----| :----- | :----- | :----- | +| 安全启动 | Secure boot | Secure boot | 安全启动就是启动过程中,前一个部件验证后一个部件的数字签名,验证通过后,运行后一个部件,验证不通过就停下来。通过安全启动可以保证系统启动过程中各个部件的完整性。 | +| 平台密钥 | Platform key | PK | OEM厂商所有,必须为 RSA 2048 或更强,PK为平台拥有者和平台固件之间建立可信关系。平台拥有者将PK的公钥部分PKpub注册到平台固件中,平台拥有者可以使用PK的私有部分PKpriv来改变平台的拥有权或者注册KEK密钥。 | +| 密钥交换密钥 | Key exchange key | KEK | KEK为平台固件和OS之间创建可信关系。每一个操作系统和与平台固件通信的第三方应用在平台固件中注册KEK密钥的公共部分KEKpub。 | +| 签名数据库 | Database white list | DB | 存储验证shim、grub、vmlinuz等组件的密钥。 | +| 签名吊销数据库 | Database black list | DBx | 存储吊销的密钥。 | + +#### 功能说明 + +本次实现的虚拟机安全启动特性基于edk开源项目。非安全启动模式下,Linux基本流程如下: + +**图 1*- 系统启动流程图 + +![](./figures/OSBootFlow.png) + +安全启动模式下UEFI BIOS启动后加载的首个组件是系统镜像中的shim,shim与UEFI BIOS进行交互获取存储在UEFI BIOS变量db里面的密钥对grub进行验证,加载grub后同样调用密钥和认证接口对kernel进行验证。Linux启动流程如下: + +**图 2*- 安全启动流程图 + +![](./figures/SecureBootFlow.png) + +从整体处理流程上来看,安全启动特性包含多个关键场景,根据场景分析和系统分解,安全启动特性涉及以下几个子系统:UEFI BIOS校验shim,shim校验grub,grub校验kernel。UEFI BIOS对shim进行验证,验证通过则启动shim,不通过则提示错误,无法启动。shim需要在镜像编译制作过程中使用私钥进行签名,公钥证书导入UEFI BIOS变量区DB中。shim启动后验证启动grub,验证通过则启动grub,不通过则提示错误,无法启动。grub需要在镜像编译制作过程中进行签名,使用和shim一样的公私钥对。grub启动后检查调用shim注册在UEFI BIOS的认证接口和密钥对kernel进行验证,通过则启动内核,不通过则提示错误,grub需要在镜像编译制作过程中进行签名,使用和shim一样的公私钥对。 + +#### 约束限制 + +- 在不支持安全启动的UEFI BIOS上运行,对现有功能没有影响,业务无感知。 +- 安全启动特性依赖UEFI BIOS,必须在UEFI支持此功能的条件下才能发挥作用。 +- 在UEFI BIOS开启安全启动的情况下,如果相关部件没有签名或签名不正确,则无法正常启动系统。 +- 在UEFI BIOS关闭安全启动的情况下,启动过程的验证功能都会被关闭。 +- 安全启动验证链后半段,即shim->grub->kernel引导内核启动这部分的验证链由操作系统镜像实现,若操作系统不支持引导内核安全启动过程,则虚拟机安全启动失败。 +- 当前不提供x86架构使用nvram文件配置虚拟机安全启动。 + +### 安全启动实践 + +虚拟机安全启动依赖于UEFI BIOS的实现,UEFI BIOS镜像通过edk rpm包安装,本节以AArch64为例对虚拟机安全启动进行配置。 + +#### 虚拟机配置 + +edk rpm包中的组件安装于/usr/share/edk2/aarch64目录下,包括`QEMU_EFI-pflash.raw`和`vars-template-pflash.raw`。虚拟机启动UEFI BIOS部分xml配置如下: + +```conf + + hvm + /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw + /path/to/QEMU-VARS.fd + +``` + +其中/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw为UEFI BIOS镜像路径。/usr/share/edk2/aarch64/vars-template-pflash.raw为nvram镜像模板路径,/path/to/QEMU-VARS.fd为当前虚拟机nvram镜像文件路径,用于保存UEFI BIOS系统中的环境变量。 + +#### 证书导入 + +虚拟机安全启动时的证书从BIOS界面导入,在证书导入前需要将证书文件导入到虚拟机中。可以通过挂载磁盘的方式将证书文件所在目录挂载到虚拟机中,例如制作包含证书的镜像,并在虚拟机的配置文件xml中配置挂载该镜像: + +制作证书文件镜像 + +```sh +dd of='/path/to/data.img' if='/dev/zero' bs=1M count=64 +mkfs.vfat -I /path/to/data.img +mkdir /path/to/mnt +mount path/to/data.img /path/to/mnt/ +cp -a /path/to/certificates/- /path/to/mnt/ +umount /path/to/mnt/ +``` + +其中,/path/to/certificates/为证书文件所在路径,/path/to/data.img为证书文件镜像所在路径,/path/to/mnt/为镜像挂载路径。 + +在虚拟机xml文件中配置挂载该镜像 + +```conf + + + + + + + + + +``` + +启动虚拟机,导入PK证书,流程如下(KEK证书,DB证书导入方式相同): + +虚拟机启动后,点击F2进入bios界面 + +**图 1*- 进入bios界面 + +![](./figures/CertEnrollP1.png) + +**图 2*- 进入Device Manager + +![](./figures/CertEnrollP2.png) + +**图 3*- 进入Custom Secure Boot Options + +![](./figures/CertEnrollP3.png) + +**图 4*- 进入PK Options + +![](./figures/CertEnrollP4.png) + +**图 5*- Enroll PK + +![](./figures/CertEnrollP5.png) + +在File Explorer界面可以看到很多磁盘目录,其中包括我们通过磁盘挂载的证书文件目录 + +**图 6*- File Explorer + +![](./figures/CertEnrollP6.png) + +在磁盘目录中选择要导入的PK证书 + +**图 7*- 进入证书所在磁盘 + +![](./figures/CertEnrollP7.png) + +**图 8*- 选择Commit Changes and Exit保存导入证书 + +![](./figures/CertEnrollP8.png) + +导入证书后,UEFI BIOS将证书信息以及安全启动属性写入nvram配置文件/path/to/QEMU-VARS.fd中,虚拟机下一次启动时会从/path/to/QEMU-VARS.fd文件中读取相关配置并初始化证书信息以及安全启动属性,自动导入证书并开启安全启动。同样,我们可以将/path/to/QEMU-VARS.fd作为其他相同配置虚拟机的UEFI BIOS启动配置模板文件,通过修改nvram template字段使其他虚拟机启动时自动导入证书并开启安全启动选项,虚拟机xml配置修改如下: + +```conf + + hvm + /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw + + +``` + +#### 安全启动观测 + +正确配置虚拟机并导入PK、KEK、DB证书后,虚拟机将以安全启动的方式运行。可以通过在虚拟机配置文件xml中配置串口日志文件观测虚拟机是否为安全启动,串口日志文件的配置方式如下: + +```conf + + + +``` + +虚拟机加载系统镜像成功后,当串口日志文件中出现"UEFI Secure Boot is enabled"信息时,表明虚拟机当前为安全启动。 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/skylark.md b/docs/zh/virtualization/virtualization_platform/virtualization/skylark.md new file mode 100644 index 00000000..a5272e25 --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/skylark.md @@ -0,0 +1,192 @@ +# Skylark + + + +## Skylark概述 + +### 问题背景 + +随着云计算市场规模的快速增长,各云厂商基础设施投入也不断增加。资源利用率低是行业普遍存在的问题,在上述背景下,提升资源利用率已经成为了一个重要的技术课题。本文档介绍 openEuler Skylark 组件,并给出安装方法及使用指导。 + +### 总体介绍 + +将业务区分优先级混合部署(下文简称混部)是典型有效的资源利用率提升手段。业务可根据时延敏感性分为高优先级业务和低优先级业务。当高优先级业务和低优先级业务发生资源竞争时,需优先保障高优先级业务的资源供给。因此,业务混部的核心技术是资源隔离控制,主要涉及内核态基础资源隔离技术及用户态 QoS 控制技术。 + +本文描述的对象为用户态 QoS 控制技术,由 openEuler Skylark 组件承载,首发于 openEuler 22.09 版本。在 Skylark 视角下,优先级粒度为虚拟机级别,即给虚拟机新增高低优先级属性,以虚拟机为粒度进行资源的隔离和控制。Skylark 是一种混部场景下的 QoS 感知的资源调度器,在保障高优先级虚拟机 QoS 前提下提升物理机资源利用率。 + +在实际应用场景中如何更好地利用 Skylark 的高低优先级特性,请参考[最佳实践](#最佳实践)章节。 + +## 架构及特性 + +### 总体实现框架 + +Skylark 核心类为`QoSManager`,类成员包括数据收集类实例、QoS 分析类实例、QoS 控制类实例、以及任务调度类实例: + +- `DataCollector`:数据收集类,有`HostInfo`和`GuestInfo`两个成员,分别用于收集主机信息和虚拟机信息。 +- `PowerAnalyzer`:功耗分析类,用于分析功耗干扰以及需要限制的低优先级虚拟机。 +- `CpuController`:CPU 带宽控制类,用于限制低优先级虚拟机的 CPU 带宽。 +- `CacheMBWController`:LLC 及内存带宽控制类,用于限制低优先级虚拟机的 LLC 和内存带宽。 +- `BackgroundScheduler`:任务调度类,用于周期性驱动以上模块,持续进行 QoS 管理。 + +Skylark 检查主机环境后,创建守护进程。守护进程有两种线程:主调度线程和 Job 线程: + +- 主调度线程是唯一的,首先连接 Libvirt,然后创建并初始化`QosManager`类实例,最后开始驱动 Job 线程。 +- Job 线程可能不止一个,每个 Job 线程负责周期性执行某个 QoS 管理任务。 + +### 功耗干扰控制 + +相比非混部情况,混部后主机利用率更高,高利用率意味着高功耗,服务器功耗在超过 TDP 时会触发 CPU 降频。Skylark 支持当功耗超过预设的 TDP 阈值(即出现 TDP 热点)时,通过对低优先级虚拟机的 CPU 带宽进行限制,以此达到降低整机功耗的同时保障高优先级虚拟机 QoS。 + +Skylark 初始化时,根据[配置Skylark](#配置skylark)中相关配置值,设置功耗干扰控制属性。在每个控制周期,综合分析主机信息和控制属性,判断是否出现 TDP 热点。如果出现热点,进一步根据虚拟机信息分析出需要对哪些低优先级虚拟机进行 CPU 带宽的限制。 + +### LLC/MB干扰控制 + +Skylark 支持对低优先级虚拟机的 LLC 和内存带宽进行限制,当前仅支持静态分配。Skylark 通过操作系统提供的`/sys/fs/resctrl`接口来限制低优先级虚拟机的 LLC 和内存带宽。 + +1. Skylark 在`/sys/fs/resctrl`目录下建立`low_prio_machine`文件夹,并将低优先级虚拟机的 pid 写入`/sys/fs/resctrl/low_prio_machine/tasks`文件中。 +2. Skylark 根据[配置Skylark](#配置skylark)章节中 LLC/MB 相关配置项对低优先级虚拟机的 LLC ways 和内存带宽进行分配,配置项写入`/sys/fs/resctrl/low_prio_machine/schemata`文件中。 + +### CPU干扰控制 + +混部场景下,低优先级虚拟机会对高优先级虚拟机产生 CPU 时间片干扰和 SMT(硬件超线程)干扰。 + +- 当高低优先级虚拟机相关线程在同一个最小 CPU 拓扑单元(core 或 SMT)上同时处于可运行状态时,会竞争 CPU 时间片。 +- 当高低优先级虚拟机相关线程在同一个 CPU core 的不同 SMT 上同时处于可运行状态时,会竞争 SMT 共享的 core 内资源。 + +CPU 干扰控制分为 CPU 时间片干扰控制及 SMT 干扰控制,分别基于内核提供的 `QOS_SCHED` 及 `SMT_EXPELLER` 特性实现。 + +- `QOS_SCHED` 特性实现了单个 CPU core 或 SMT 上高优先级虚拟机对低优先级虚拟机的绝对压制,解决了 CPU 时间片干扰问题。 +- `SMT_EXPELLER` 特性实现了同一个 CPU core 的不同 SMT 上高优先级虚拟机对低优先级虚拟机的绝对压制,解决了 SMT 干扰问题。 + +Skylark 初始化时,会把 Cgroup CPU 子控制器下低优先级虚拟机对应 slice 层级的`cpu.qos_level`字段设置为 -1,以使能上述内核特性,后续就由内核实现对 CPU 相关干扰的控制,Skylark 无需介入。 + +## 安装Skylark + +### 硬件要求 + +处理器架构:仅支持 AArch64 和 Intel x86_64 处理器架构。 + +- Intel 处理器需支持 RDT 功能。 +- AArch64 当前仅支持 Kunpeng920,且需将 BIOS 升级到 1.79 及以上以支持 MPAM 功能。 + +### 软件要求 + +- 依赖 python3、python3-APScheduler、python3-libvirt 等 python 组件。 +- 依赖 systemd 组件,版本 >= 249-32。 +- 依赖 libvirt 组件,版本 >= 1.0.5。 +- 依赖 openEuler 内核,版本 >= 5.10.0。 + +### 安装方法 + +推荐使用 yum 安装 Skylark 组件,因为 yum 会自动处理上述软件依赖: + +```shell +# yum install -y skylark +``` + +检查 Skylark 是否安装成功,若安装成功则会显示 skylarkd 后台服务状态: + +```shell +# systemctl status skylarkd +``` + +设置 Skylark 服务开机自启动(可选): + +```shell +# systemctl enable skylarkd +``` + +## 配置Skylark + +安装好 Skylark 组件后,若默认配置不满足需求,可修改配置文件。Skylark 的配置文件路径为`/etc/sysconfig/skylarkd`,下面对该配置文件包含的配置项作详细说明。 + +### 日志 + +- `LOG_LEVEL`用于设置最小日志级别,类型为字符串。所有可设置的日志级别及其关系为`critical > error > warning > info > debug`。级别小于`LOG_LEVEL`的日志将不会输出到日志文件。日志文件路径为`/var/log/skylark.log`。Skylark 会每 7 天备份一次日志,最多备份 4 次(当次数超限时,会删除最旧的日志)。备份的日志路径为`/var/log/skylark.log.%Y-%m-%d`。 + +### 功耗干扰控制 + +- `POWER_QOS_MANAGEMENT`用于控制是否打开功耗 QoS 管理功能,类型为布尔。当前仅 x86 支持该功能。如果主机上虚拟机的 CPU 利用率能被很好地限制,该功能可选。 + +- `TDP_THRESHOLD`用于控制虚拟机可达到的最大功耗。当主机功耗超过`TDP * TDP_THRESHOLD`时,将判断为出现 TDP 热点,触发功耗控制操作。类型为 float,可接受的输入范围为 0.8-1,默认值为 0.98。 + +- `FREQ_THRESHOLD`用于控制当主机出现 TDP 热点时,CPU 运行的最低频率。类型为 float,可接受的输入范围为 0.9-1,默认值为 0.98。 + 1. 当存在某些 CPU 的频率低于`max_freq * FREQ_THRESHOLD`时,Skylark 会限制在这些 CPU 上运行的低优先级虚拟机的 CPU 带宽。 + 2. 当找不到这样的 CPU,则 Skylark 也会根据低优先级虚拟机的 CPU 利用率情况,选择性限制某些低优先级虚拟机的 CPU 带宽。 + +- `QUOTA_THRESHOLD`用于控制低优先级虚拟机被限制后所能获得的 CPU 带宽(限制前的 CPU 带宽 * `QUOTA_THRESHOLD`)。类型为 float,可接受的输入范围为 0.8-1,默认值为 0.9。 + +- `ABNORMAL_THRESHOLD`用于控制低优先级虚拟机被限制的周期。类型为 int,可接受的输入范围为 1-5,默认值为 3。 + 1. 在每个功耗控制周期内,如果某个低优先级虚拟机被限制,其剩余被限制周期刷新为`ABNORMAL_THRESHOLD`,否则其剩余被限制周期减 1。 + 2. 当虚拟机的剩余被限制周期等于 0 时,其 CPU 带宽恢复为被限制前的值。 + +### LLC/MB干扰控制 + +Skylark 对 LLC/MB 的干扰控制依赖于硬件使能 RDT/MPAM 功能,Intel x86_64 架构处理器需在内核 cmdline 配置`rdt=cmt,mbmtotal,mbmlocal,l3cat,mba`,Kunpeng920 处理器需在内核 cmdline 配置`mpam=acpi`。 + +- `MIN_LLC_WAYS_LOW_VMS`用于控制低优先级虚拟机可访问的 LLC ways。类型为 int,可接受的输入范围为 1-3,默认值为 2。Skylark 会在初始化时,限制低优先级虚拟机的 LLC ways 为该值。 + +- `MIN_MBW_LOW_VMS`用于控制低优先级虚拟机可访问的内存带宽比例。类型为 float,可接受的输入范围为 0.1~0.2,默认值为 0.1。Skylark 会在初始化时,限制低优先级虚拟机的内存带宽为该值。 + +## 使用Skylark + +### 启动服务 + +初次启动: + +```shell +# systemctl start skylarkd +``` + +重新启动(修改配置文件后需重启): + +```shell +# systemctl restart skylarkd +``` + +### 创建虚拟机 + +Skylark 借助虚拟机 XML 配置文件的`partition`标签标识虚拟机优先级属性。 + +创建低优先级虚拟机,其 XML 需做如下配置: + +```xml + + ... + + /low_prio_machine + + ... + +``` + +创建高优先级虚拟机,其 XML 需做如下配置: + +```xml + + ... + + /high_prio_machine + + ... + +``` + +后续创建虚拟机流程和一般流程无异。 + +### 虚拟机运行 + +Skylark 能感知到虚拟机创建事件,纳管所有高、低优先级虚拟机,并围绕 CPU、功耗、LLC/MB 等资源做自动化 QoS 管理。 + +## 最佳实践 + +### 虚拟机业务推荐 + +- 高优先级虚拟机业务推荐:时延敏感类业务,如 web 服务、高性能数据库、实时渲染、机器学习推理等。 +- 低优先级虚拟机业务推荐:非时延敏感类业务,如视频编码、大数据处理、离线渲染、机器学习训练等。 + +### 虚拟机绑核配置 + +为了让高优先级虚拟机达到最佳性能,推荐高优先级虚拟机 vCPU 与物理 CPU 一对一绑核。为了让低优先级虚拟机充分利用空闲物理资源,推荐低优先级虚拟机 vCPU 范围绑核,且绑核范围覆盖高优先级虚拟机绑核范围。 + +同时为了防止出现因高优先级虚拟机长时间占满 CPU 导致低优先级虚拟机无法被调度的情况,需要预留少量低优先级虚拟机专用的 CPU,该部分 CPU 不可让高优先级虚拟机绑定,且要求让低优先级虚拟机绑定。 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/system_resource_management.md b/docs/zh/virtualization/virtualization_platform/virtualization/system_resource_management.md new file mode 100644 index 00000000..7aa8b35e --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/system_resource_management.md @@ -0,0 +1,454 @@ +# 管理系统资源 + +## 总体说明 + +openEuler 虚拟化使用libvirt命令来管理虚拟机的系统资源,如vCPU、虚拟内存资源等。 + +在开始前: + +- 确保主机上运行了libvirtd守护进程。 +- 用virsh list --all命令确认虚拟机已经被定义。 + +## 管理虚拟CPU + +### CPU份额 + +#### 概述 + +虚拟化环境下,同一主机上的多个虚拟机竞争使用物理CPU。为了防止某些虚拟机占用过多的物理CPU资源,影响相同主机上其他虚拟机的性能,需要平衡虚拟机vCPU的调度,避免物理CPU的过度竞争。 + +CPU份额表示一个虚拟机竞争物理CPU计算资源的能力大小总和。用户通过调整cpu\_shares值能够设置虚拟机抢占物理CPU资源的能力。cpu\_shares值无单位,是一个相对值。虚拟机获得的CPU计算资源,是与其他虚拟机的CPU份额,按相对比例,瓜分物理CPU除预留外可用计算资源。通过调整CPU份额来保证虚拟机CPU计算资源服务质量。 + +#### 操作步骤 + +通过修改分配给虚拟机的运行时间的cpu\_shares值,来平衡vCPU之间的调度。 + +- 查看虚拟机的当前CPU份额: + + ```sh + $ virsh schedinfo + Scheduler : posix + cpu_shares : 1024 + vcpu_period : 100000 + vcpu_quota : -1 + emulator_period: 100000 + emulator_quota : -1 + global_period : 100000 + global_quota : -1 + iothread_period: 100000 + iothread_quota : -1 + ``` + +- 在线修改:修改处于running状态的虚拟机的当前CPU份额,使用带 **--live** 参数的virsh schedinfo命令: + + ```sh + $ virsh schedinfo --live cpu_shares= + ``` + + 比如将正在运行的虚拟机openEulerVM的CPU份额从1024改为2048: + + ```sh + $ virsh schedinfo openEulerVM --live cpu_shares=2048 + Scheduler : posix + cpu_shares : 2048 + vcpu_period : 100000 + vcpu_quota : -1 + emulator_period: 100000 + emulator_quota : -1 + global_period : 100000 + global_quota : -1 + iothread_period: 100000 + iothread_quota : -1 + ``` + + 对cpu\_shares值的修改立即生效,虚拟机openEulerVM能得到的运行时间将是原来的2倍。但是这一修改将在虚拟机关机并重新启动后失效。 + +- 持久化修改:在libvirt内部配置中修改虚拟机的CPU份额,使用带 **--config** 参数的virsh schedinfo命令: + + ```sh + $ virsh schedinfo --config cpu_shares= + ``` + + 比如将虚拟机openEulerVM的CPU份额从1024改为2048: + + ```sh + $ virsh schedinfo openEulerVM --config cpu_shares=2048 + Scheduler : posix + cpu_shares : 2048 + vcpu_period : 0 + vcpu_quota : 0 + emulator_period: 0 + emulator_quota : 0 + global_period : 0 + global_quota : 0 + iothread_period: 0 + iothread_quota : 0 + ``` + + 对cpu\_shares值的修改不会立即生效,在虚拟机openEulerVM下一次启动后才生效,并持久生效。虚拟机openEulerVM能得到的运行时间将是原来的2倍。 + +### 绑定QEMU进程至物理CPU + +#### 概述 + +QEMU主进程绑定特性是将QEMU主进程绑定到特定的物理CPU范围内,从而保证了运行不同业务的虚拟机不会干扰到邻位虚拟机。例如在一个典型的云计算场景中,一台物理机上会运行多台虚拟机,而每台虚拟机的业务不同,造成了不同程度的资源占用,为了避免存储IO密集的虚拟机对邻位虚拟机的干扰,需要将不同虚拟机处理IO的存储进程完全隔离,由于QEMU主进程是处理前后端的主要服务进程,故需要实现隔离。 + +#### 操作步骤 + +通过virsh emulatorpin命令可以绑定QEMU主进程到物理CPU。 + +- 查看QEMU进程当前绑定的物理CPU范围: + + ```sh + $ virsh emulatorpin openEulerVM + emulator: CPU Affinity + ---------------------------------- + *: 0-63 + ``` + + 这说明虚拟机openEulerVM对应的QEMU主进程可以在主机的所有物理CPU上调度。 + +- 在线绑定:修改处于running状态的虚拟机对应的QEMU进程的绑定关系,使用带 **--live** 参数的virsh emulatorpin命令: + + ```sh + $ virsh emulatorpin openEulerVM --live 2-3 + + $ virsh emulatorpin openEulerVM + emulator: CPU Affinity + ---------------------------------- + *: 2-3 + ``` + + 以上命令把虚拟机openEulerVM对应的QEMU进程绑定到物理CPU2、3上,即限制了QEMU进程只在这两个物理CPU上调度。这一绑定关系的调整立即生效,但在虚拟机关机并重新启动后失效。 + +- 持久化绑定:在libvirt内部配置中修改虚拟机对应的QEMU进程的绑定关系,使用带 **--config** 参数的virsh emulatorpin命令: + + ```sh + $ virsh emulatorpin openEulerVM --config 0-3,^1 + + $ virsh emulatorpin openEulerVM --config + emulator: CPU Affinity + ---------------------------------- + *: 0,2-3 + ``` + + 以上命令把虚拟机openEulerVM对应的QEMU进程绑定到物理CPU0、2、3上,即限制了QEMU进程只在这三个物理CPU上调度。**这一绑定关系的调整不会立即生效,在虚拟机下一次启动后才生效,并持久生效**。 + +### 调整虚拟CPU绑定关系 + +#### 概述 + +把虚拟机的vCPU绑定在物理CPU上,即vCPU只在绑定的物理CPU上调度,在特定场景下达到提升虚拟机性能的目的。比如在NUMA系统中,把vCPU绑定在同一个NUMA节点上,可以避免vCPU跨节点访问内存,避免影响虚拟机运行性能。如果未绑定,默认vCPU可在任何物理CPU上调度。具体的绑定策略由用户来决定。 + +#### 操作步骤 + +通过virsh vcpupin命令可以调整vCPU和物理CPU的绑定关系。 + +- 查看虚拟机的当前vCPU绑定信息: + + ```sh + $ virsh vcpupin openEulerVM + VCPU CPU Affinity + ---------------------- + 0 0-63 + 1 0-63 + 2 0-63 + 3 0-63 + ``` + + 这说明虚拟机openEulerVM的所有vCPU可以在主机的所有物理CPU上调度。 + +- 在线调整:修改处于running状态的虚拟机的当前vCPU绑定关系,使用带 **--live** 参数的virsh vcpupin命令: + + ```sh + $ virsh vcpupin openEulerVM --live 0 2-3 + + $ virsh vcpupin openEulerVM + VCPU CPU Affinity + ---------------------- + 0 2-3 + 1 0-63 + 2 0-63 + 3 0-63 + ``` + + 以上命令把虚拟机openEulerVM的vCPU0绑定到CPU2、3上,即限制了vCPU0只在这两个物理CPU上调度。这一绑定关系的调整立即生效,但在虚拟机关机并重新启动后失效。 + +- 持久化调整:在libvirt内部配置中修改虚拟机的vCPU绑定关系,使用带 **--config** 参数的virsh vcpupin命令: + + ```sh + $ virsh vcpupin openEulerVM --config 0 0-3,^1 + + $ virsh vcpupin openEulerVM --config + VCPU CPU Affinity + ---------------------- + 0 0,2-3 + 1 0-63 + 2 0-63 + 3 0-63 + ``` + + 以上命令把虚拟机openEulerVM的vCPU0绑定到物理CPU0、2、3上,即限制了vCPU0只在这三个物理CPU上调度。**这一绑定关系的调整不会立即生效,在虚拟机下一次启动后才生效,并持久生效**。 + +### CPU热插 + +#### 概述 + +在线增加(热插)虚拟机CPU是指在虚拟机处于运行状态下,为虚拟机热插CPU而不影响虚拟机正常运行的方案。当虚拟机内部业务压力不断增大,会出现所有CPU均处于较高负载的情形。为了不影响虚拟机内的正常业务运行,可以使用CPU热插功能(在不关闭虚拟机情况下增加虚拟机的CPU数目),提升虚拟机的计算能力。 + +#### 约束限制 + +- 如果处理器为AArch64架构,创建虚拟机时指定的虚拟机芯片组类型\(machine\)需为virt-4.1或virt更高版本。如果处理器为x86\_64架构,创建虚拟机时指定的虚拟机芯片组类型\(machine\)需为pc-i440fx-1.5或pc更高版本。 +- 在配置Guest NUMA的场景中,必须把属于同一个socket的vcpu配置在同一vNode中,否则热插CPU后可能导致虚拟机softlockup,进而可能导致虚拟机panic。 +- 虚拟机在迁移、休眠唤醒、快照过程中均不支持CPU热插。 +- 虚拟机CPU热插是否自动上线取决于虚拟机操作系统自身逻辑,虚拟化层不保证热插CPU自动上线。 +- CPU热插同时受限于Hypervisor和GuestOS支持的最大CPU数目。 +- 虚拟机启动、关闭、重启过程中可能出现热插CPU失效的情况,但再次重启会生效。 +- 热插虚拟机CPU的时候,如果新增CPU数目不是虚拟机CPU拓扑配置项中Cores的整数倍,可能会导致虚拟机内部看到的CPU拓扑是混乱的,建议每次新增的CPU数目为Cores的整数倍。 +- 若需要热插CPU在线生效且在虚拟机重启后仍有效,virsh setvcpus接口中需要同时传入--config和--live选项, 将热插CPU动作持久化。 + +#### 操作步骤 + +**一、配置虚拟机XML** + +1. 使用CPU热插功能,需要在创建虚拟机时配置虚拟机当前的CPU数目、虚拟机所支持的最大CPU数目,以及虚拟机芯片组类型(对于AArch64架构,需为virt-4.1及以上版本。对于x86\_64架构,需为pc-i440fx-1.5及以上版本)。这里以AArch64架构虚拟机为例,配置模板如下: + + ```conf + + ... + n + + hvm + + ... + + ``` + + >[!NOTE]说明 + >- placement的值必须是static。 + >- m为虚拟机当前CPU数目,即虚拟机启动后默认的CPU数目。n为虚拟机支持热插到的最大CPU数目,该值不能超过Hypervisor支持的虚拟机最大CPU规格及GuestOS支持的最大CPU规格。n大于或等于m。 + + 例如,配一个虚拟机当前CPU数目为4,最大支持的热插CPU上限为64的XML配置为: + + ```conf + + …… + 64 + + hvm + + …… + ``` + +**二、热插并上线CPU** + +1. 如果热插CPU后需要自动上线热插的CPU,可以使用root权限在虚拟机内部创建udev rules文件/etc/udev/rules.d/99-hotplug-cpu.rules,并在其中定义udev规则,内容参考如下: + + ```sh + # automatically online hot-plugged cpu + ACTION=="add", SUBSYSTEM=="cpu", ATTR{online}="1" + ``` + + >[!NOTE]说明 + >如果没有使用udev rules自动上线热插CPU,可以在热插CPU后,使用root权限,参考如下命令手动上线: + > + >```sh + >for i in `grep -l 0 /sys/devices/system/cpu/cpu*/online` + >do + > echo 1 > $i + >done + >``` + +2. 利用virsh工具进行虚拟机CPU热插操作。例如给虚拟机openEulerVM热插CPU到6,且在线生效的参考命令如下: + + ```sh + virsh setvcpus openEulerVM 6 --live + ``` + + >[!NOTE]说明 + >virsh setvcpus 进行虚拟机CPU热插操作的格式如下: + > + >```sh + >virsh setvcpus [--config] [--live] + > + >```sh + >- domain: 参数,必填。指定虚拟机名称。 + >- count: 参数,必填。指定目标CPU数目,即热插后虚拟机CPU数目。 + >- --config: 选项,选填。虚拟机下次启动时仍有效。 + >- --live: 选项,选填。在线生效。 + +## 管理虚拟内存 + +### NUMA简介 + +传统的多核运算使用SMP(Symmetric Multi-Processor)模式:将多个处理器与一个集中的存储器和I/O总线相连。所有处理器只能访问同一个物理存储器,因此SMP系统也被称为一致存储器访问(UMA)系统。一致性指无论在什么时候,处理器只能为内存的每个数据保持或共享唯一一个数值。很显然,SMP的缺点是可伸缩性有限,因为在存储器和I/O接口达到饱和的时候,增加处理器并不能获得更高的性能。 + +NUMA(Non Uniform Memory Access Architecture) 模式是一种分布式存储器访问方式,处理器可以同时访问不同的存储器地址,大幅度提高并行性。 NUMA模式下,处理器被划分成多个“节点”(NODE), 每个节点分配一块本地存储器空间。所有节点中的处理器都可以访问全部的物理存储器,但是访问本节点内的存储器所需要的时间,比访问某些远程节点内的存储器所花的时间要少得多。 + +### 配置Host-NUMA + +为提升虚拟机性能,在虚拟机启动前,用户可以通过虚拟机XML配置文件为虚拟机指定主机的NUMA节点,使虚拟机内存分配在指定的NUMA节点上。本特性一般与vCPU绑定一起使用,从而避免vCPU远端访问内存。 + +#### 操作步骤 + +- 查看host的NUMA拓扑结构: + + ```sh + $ numactl -H + available: 4 nodes (0-3) + node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + node 0 size: 31571 MB + node 0 free: 17095 MB + node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + node 1 size: 32190 MB + node 1 free: 28057 MB + node 2 cpus: 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 + node 2 size: 32190 MB + node 2 free: 10562 MB + node 3 cpus: 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 + node 3 size: 32188 MB + node 3 free: 272 MB + node distances: + node 0 1 2 3 + 0: 10 15 20 20 + 1: 15 10 20 20 + 2: 20 20 10 15 + 3: 20 20 15 10 + ``` + +- 在虚拟机XML配置文件中添加numatune字段,创建并启动虚拟机。例如使用主机上的NUMA node 0给虚拟机分配内存,配置参数如下: + + ```conf + + + + ``` + + 假设虚拟机的vCPU也绑定在NODE0的物理CPU上,就可以避免由于vCPU访问远端内存带来的性能下降。 + + >[!NOTE]说明 + >- 分配给虚拟机的内存不要超过该NUMA节点剩余的可用内存,否则可能导致虚拟机启动失败。 + >- 建议虚拟机内存和vCPU都绑定在同一NUMA节点,避免vCPU访问远端内存造成性能下降。例如将上例中vCPU也绑定在NUMA node 0上。 + +### 配置Guest-NUMA + +虚拟机中运行的很多业务软件都针对NUMA架构进行了性能优化,尤其是对于大规格虚拟机,这种优化的作用更明显。openEuler提供了Guest NUMA特性,在虚拟机内部呈现出NUMA拓扑结构。用户可以通过识别这个结构,对业务软件的性能进行优化,从而保证业务更好的运行。 + +配置Guest NUMA时可以指定vNode的内存在HOST上的分配位置,实现内存的分块绑定,同时配合vCPU绑定,使vNode上的vCPU和内存在同一个物理NUMA node上。 + +#### 操作步骤 + +在虚拟机的XML配置文件中,配置了Guest NUMA后,就可以在虚拟机内部查看NUMA拓扑结构。项是Guest NUMA的必配项。 + +```conf + + + + + + + + + + + [...] + + + + + + +``` + +- 项提供虚拟机内部呈现NUMA拓扑功能,“cell id”表示vNode编号,“cpus”表示vCPU编号,“memory”表示对应vNode上的内存大小。 +- 如果希望通过Guest NUMA提供更好的性能,则需要配置,使vCPU和对应的内存分布在同一个物理NUMA NODE上。 + - 中的“cellid”和中的“cell id”是对应的;“mode”可以配置为“strict”(严格从指定node上申请内存,内存不够则失败)、“preferred”(优先从某一node上申请内存,如果不够则从其他node上申请)、“interleave”(从指定的node上交叉申请内存);“nodeset”表示指定物理NUMA NODE。 + - 中需要将同一cell id中的vCPU绑定到与memnode相同的物理NUMA NODE上。 + +### 内存热插 + +#### 概述 + +在虚拟化场景下,虚拟机的内存、CPU、外部设备都是软件模拟呈现的,因此可以在虚拟化底层为虚拟机提供内存在线调整的能力。当前openEuler版本支持在线给虚拟机添加内存,当虚拟机出现物理内存不足又无法关闭虚拟机的时候,可以使用此特性增加虚拟机的物理内存资源。 + +#### 约束限制 + +- 创建虚拟机的时候,AArch64平台上指定的主板类型(machine)需为virt-4.1或更高virt以上,x86平台上指定的主板类型需要为pc-i440fx-1.5以上版本。 +- 内存热插特性依赖于Guest NUMA,虚拟机必须配置Guest NUMA,否则无法完成内存热插流程。 +- 热插内存时候必须指定新增内存所属的Gust NUMA node编号,否则内存热插失败。 +- 虚拟机内核必须支持内存热插能力,否则虚拟机无法识别新增内存或者无法上线内存。 +- 配置使用大页的虚拟机,热插内存的容量必须是系统hugepagesz的整数倍,否则会导致热插失败。 +- 热插内存的大小必须为Guest物理内存块大小block_size_bytes的整数倍,否则无法正常上线。在Guest内部执行lsmem可以获取block_size_bytes大小。 +- 配置n个virtio-net网卡后,最大可热插次数取值为min{max_slot, 64 - n},因为要给网卡预留slot。 +- vhost-user设备和内存热插特性互斥。配置了vhost-user设备的虚拟机不支持内存热插;内存热插后,不支持虚拟机热插vhost-user设备。 +- 如果虚拟机操作系统为Linux系列,请确保初始内存大于等于4GB。 +- 如果虚拟机操作系统为Windows类型,第一次热插内存必须指定到Guest NUMA node0上,否则热插内存无法被虚拟机识别。 +- 在直通场景下,由于需要预先分配内存,因此启动和热插内存都比普通虚拟机要慢(尤其是大规格虚拟机),属于正常现象。 +- 建议虚拟机可用内存与热插内存的比例至少为1:32,即热插32G内存虚拟机至少需要有1G可用内存,如果低于该比例可能会导致虚拟机卡死。 +- 热插内存是否自动上线取决于虚拟机操作系统自身逻辑,可以手动上线或者配置udev规则自动上线。 + +#### 操作步骤 + +**一、配置虚拟机XML** + +1. 使用内存热插功能,需要在创建虚拟机时配置可热插内存的最大范围、预留槽位号,并配置Guest NUMA拓扑结构。 + + 例如,为虚拟机配置32GiB初始内存,预留256个槽位号,最大支持1TiB内存上限,2个NUMA node的配置为: + + ```conf + + 32 + 1024 + + + + + + + + .... + ``` + +>[!NOTE]说明 +>其中: +>maxMemory字段中slots号表示预留的内存插槽,最大取值为256。 +>maxMemory表示虚拟机支持的最大物理内存上限。 +>Guest NUMA配置请参见“配置Guest NUMA”相关章节。 + +**二、热插并上线内存** + +1. 如果热插内存后需要自动上线热插的内存,可以使用root权限在虚拟机内部创建udev rules文件/etc/udev/rules.d/99-hotplug-memory.rules,并在其中定义udev规则,内容参考如下: + + ```sh + # automatically online hot-plugged memory + ACTION=="add", SUBSYSTEM=="memory", ATTR{state}="online" + ``` + +2. 根据需要热插的内存大小和虚拟机Guest NUMA Node创建内存描述xml文件。 + + 例如,热插1GiB内存到NUMA node0上: + + ```conf + + + 1024 + 0 + + + ``` + +3. 使用virsh attach-device命令为虚拟机热插内存。其中openEulerVM为虚拟机名称,memory.xml为热插内存的描述文件,--live表示热插内存在线生效,也可以使用--config 将热插内存持久化到虚拟机xml文件中。 + + ```conf + # virsh attach-device openEulerVM memory.xml --live + ``` + + >[!NOTE]说明 + >如果没有使用udev rules自动上线热插内存,也可以使用root权限,参考如下命令手动上线: + > + >```sh + >for i in `grep -l offline /sys/devices/system/memory/memory*/state` + >do + > echo online > $i + >done + >``` diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/tool_guide.md b/docs/zh/virtualization/virtualization_platform/virtualization/tool_guide.md new file mode 100644 index 00000000..1260d88f --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/tool_guide.md @@ -0,0 +1,3 @@ +# 工具使用指南 + +为了方便用户更好地使用虚拟化,openEuler 提供了一系列工具,包括 vmtop、LibcarePlus 等。本章介绍这些工具的安装和使用指导。 diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/virtualization.md b/docs/zh/virtualization/virtualization_platform/virtualization/virtualization.md new file mode 100644 index 00000000..2199541c --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/virtualization.md @@ -0,0 +1,3 @@ +# 虚拟化用户指南 + +本文档给出虚拟化介绍,并给出基于openEuler的虚拟化安装方法、如何使用虚拟化的教程,进而让用户了解虚拟化,并指导管理员及普通用户安装和使用虚拟化。 \ No newline at end of file diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/virtualization_installation.md b/docs/zh/virtualization/virtualization_platform/virtualization/virtualization_installation.md new file mode 100644 index 00000000..488c89d1 --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/virtualization_installation.md @@ -0,0 +1,137 @@ +# 安装虚拟化组件 + +本章介绍在openEuler中安装虚拟化组件的方法。 + +## 最低硬件要求 + +在openEuler系统中安装虚拟化组件,最低硬件要求: + +- AArch64处理器架构:ARMv8以上并且支持虚拟化扩展 +- x86\_64处理器架构:支持VT-x +- 2核CPU +- 4GB的内存 +- 16GB可用磁盘空间 + +## 安装虚拟化核心组件 + +### 安装方法 + +#### 前提条件 + +- 已经配置yum源。配置方式请参见《openEuler 22.03 LTS SP4 管理员指南》。 +- 安装操作需要root用户权限。 + +#### 安装步骤 + +1. 安装QEMU组件。 + + ``` shell + # yum install -y qemu + ``` + +2. 安装libvirt组件。 + + ``` shell + # yum install -y libvirt + ``` + +3. 启动libvirtd服务。 + + ``` shell + # systemctl start libvirtd + ``` + +>[!NOTE]说明 +>KVM模块已经集成在openEuler内核中,因此不需要单独安装。 + +### 验证安装是否成功 + +1. 查看内核是否支持KVM虚拟化,即查看/dev/kvm和/sys/module/kvm文件是否存在,命令和回显如下: + + ```shell + $ ls /dev/kvm + /dev/kvm + ``` + + ```shell + $ ls /sys/module/kvm + parameters uevent + ``` + + 若上述文件存在,说明内核支持KVM虚拟化。若上述文件不存在,则说明系统内核编译时未开启KVM虚拟化,需要更换支持KVM虚拟化的Linux内核。 + +2. 确认QEMU是否安装成功。若安装成功则可以看到QEMU软件包信息,命令和回显如下: + + ``` shell + $ rpm -qi qemu + Name : qemu + Epoch : 10 + Version : 6.2.0 + Release : 76.oe2203SP4 + Architecture: aarch64 + Install Date: Tue 15 Aug 2023 09:04:47 PM CST + Group : Unspecified + Size : 26733299 + License : GPLv2 and BSD and MIT and CC-BY-SA-4.0 + Signature : RSA/SHA256, Tue 01 Aug 2023 09:28:19 PM CST, Key ID 007fb747fb37bc6f + Source RPM : qemu-6.2.0-76.oe2203SP4.src.rpm + Build Date : Tue 01 Aug 2023 09:24:00 PM CST + Build Host : localhost + Relocations : (not relocatable) + URL : http://www.qemu.org + Summary : QEMU is a generic and open source machine emulator and virtualizer + Description : + QEMU is a generic and open source processor emulator which achieves a good + emulation speed by using dynamic translation. QEMU has two operating modes: + + * Full system emulation. In this mode, QEMU emulates a full system (for + example a PC), including a processor and various peripherals. It can be + used to launch different Operating Systems without rebooting the PC or + to debug system code. + * User mode emulation. In this mode, QEMU can launch Linux processes compiled + for one CPU on another CPU. + + As QEMU requires no host kernel patches to run, it is safe and easy to use. + ``` + +3. 确认libvirt是否安装成功。若安装成功则可以看到libvirt软件包信息,命令和回显如下: + + ``` shell + $ rpm -qi libvirt + Name : libvirt + Version : 6.2.0 + Release : 57.oe2203SP4 + Architecture: aarch64 + Install Date: Tue 30 Jul 2023 04:56:21 PM CST + Group : Unspecified + Size : 0 + License : LGPLv2+ + Signature : RSA/SHA256, Tue 01 Aug 2023 09:28:19 PM CST, Key ID 007fb747fb37bc6f + Source RPM : libvirt-6.2.0-57.oe2203SP4.src.rpm + Build Date : Tue 01 Aug 2023 09:24:00 PM CST + Build Host : 71e8c1ce149f + Relocations : (not relocatable) + URL : https://libvirt.org/ + Summary : Library providing a simple virtualization API + Description : + Libvirt is a C toolkit to interact with the virtualization capabilities + of recent versions of Linux (and other OSes). The main package includes + the libvirtd server exporting the virtualization support. + ``` + +4. 查看libvirt服务是否启动成功。若服务处于“active”状态,说明服务启动成功,可以正常使用libvirt提供的virsh命令行工具,命令和回显如下: + + ``` shell + $ systemctl status libvirtd + ● libvirtd.service - Virtualization daemon + Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled) + Active: active (running) since Tue 2019-08-06 09:36:01 CST; 5h 12min ago + Docs: man:libvirtd(8) + https://libvirt.org + Main PID: 40754 (libvirtd) + Tasks: 20 (limit: 32768) + Memory: 198.6M + CGroup: /system.slice/libvirtd.service + ─40754 /usr/sbin/libvirtd + + ``` diff --git a/docs/zh/virtualization/virtualization_platform/virtualization/vm_configuration.md b/docs/zh/virtualization/virtualization_platform/virtualization/vm_configuration.md new file mode 100644 index 00000000..171ca404 --- /dev/null +++ b/docs/zh/virtualization/virtualization_platform/virtualization/vm_configuration.md @@ -0,0 +1,904 @@ +# 虚拟机配置 + +## 总体介绍 + +### 概述 + +Libvirt工具采用XML格式的文件描述一个虚拟机特征,包括虚拟机名称、CPU、内存、磁盘、网卡、鼠标、键盘等信息。用户可以通过修改配置文件,对虚拟机进行管理。本章介绍XML配置文件各个元素的含义,指导用户完成虚拟机配置。 + +### 基本格式 + +虚拟机XML配置文件以domain为根元素,domain根元素中包含多个其他元素。XML配置文件中的部分元素可以包含对应属性和属性值,用以详细地描述虚拟机信息,同一元素的不同属性使用空格分开。 + +XML配置文件的基本格式如下,其中label代表具体标签名,attribute代表属性,value代表属性值,需要根据实际情况修改。 + +```xml + + VMName + 8 + 4 + + + + + +``` + +### 配置流程 + +1. 创建一个根元素为domain的XML配置文件。 +2. 使用标签name,根据命名规则指定唯一的虚拟机名称。 +3. 配置虚拟CPU和虚拟内存等系统资源。 +4. 配置虚拟设备。 + 1. 配置存储设备。 + 2. 配置网络设备。 + 3. 配置外部总线结构。 + 4. 配置鼠标等外部设备。 + +5. 保存XML配置文件。 + +## 虚拟机描述 + +### 概述 + +本节介绍虚拟机domain根元素和虚拟机名称的配置。 + +### 元素介绍 + +- domain:虚拟机XML配置文件的根元素,用于配置运行此虚拟机的hypervisor的类型。 + + 属性type:虚拟化中domain的类型。openEuler虚拟化中属性值为kvm。 + +- name:虚拟机名称。 + + 虚拟机名称为一个字符串,同一个主机上的虚拟机名称不能重复,虚拟机名称必须由数字、字母、“\_”、“-”、“:”组成,但不支持全数字的字符串,且虚拟机名称不超过64个字符。 + +### 配置示例 + +例如,虚拟机名称为openEuler的配置如下: + +```xml + + openEuler + ... + +``` + +## 虚拟CPU和虚拟内存 + +### 概述 + +本节介绍虚拟CPU和虚拟内存的常用配置。 + +### 元素介绍 + +- vcpu:虚拟处理器的个数。 +- memory:虚拟内存的大小。 + + 属性unit:指定内存单位,属性值支持KiB(210 字节),MiB(220 字节),GiB(230 字节),TiB(240 字节)等。 + +- cpu:虚拟处理器模式。 + + 属性mode:表示虚拟CPU的模式。 + + - host-passthrough:表示虚拟CPU的架构和特性与主机保持一致。 + + - custom:表示虚拟CPU的架构和特性由此cpu元素控制。 + + 子元素topology:元素cpu的子元素,用于描述虚拟CPU模式的拓扑结构。 + + - 子元素topology的属性socket、cores、threads分别描述了虚拟机具有多少个cpu socket,每个cpu socket中包含多少个处理核心(core),每个处理器核心具有多少个超线程(threads),属性值为正整数且三者的乘积等于虚拟CPU的个数。 + - ARM架构支持虚拟超线程, 虚拟CPU热插与虚拟超线程功能互斥。 + + 子元素model:元素cpu的子元素,当mode为custom时用于描述CPU的模型。 + + 子元素feature:元素cpu的子元素,当mode为custom时用于描述某一特性的使能情况。其中,属性name表示特性的名称,属性policy表示这一特性的使能控制策略: + + - force:表示强制使能该特性,无论主机CPU是否支持该特性。 + + - require:表示使能该特性,当主机CPU不支持该特性并且hypervisor不支持模拟该特性时,创建虚拟机失败。 + + - optional:表示该特性的使能情况与主机上该特性的使能情况保持一致。 + + - disable:禁用该特性。 + + - forbid:禁用该特性,当主机支持该特性时创建虚拟机失败。 + + 子元素cacheinfo:元素cpu的子元素,用于指定cache的大小。 + + - 属性cache:指定缓存的层级和类型,可取值有“l1d”、“l1i”、“l1”、“l2”、“l3”。如l1缓存为指令-数据分离结构,应配置“l1d”和“l1i”,否则配置“l1”。 + + - 属性size:指定缓存的大小,单位为byte。 + +### 配置示例 + +例如,虚拟CPU个数为4,处理模式为host-passthrough,虚拟内存为8GiB,4个CPU分布在两个CPU socket中,且不支持超线程的配置如下: + +```xml + + ... + 4 + 8 + + + +... + +``` + +虚拟内存为8GiB,虚拟CPU个数为4,处理模式为custom,model为Kunpeng-920,且禁用pmull特性的配置如下: + +```xml + + ... + 4 + 8 + + Kunpeng-920 + + + ... + +``` + +虚拟CPU个数为4,处理模式为host-passthrough,虚拟内存为8GiB,l1d、l1i缓存大小为32KiB,l2缓存大小为1MiB,l3缓存大小为48MiB的配置如下: + +```xml + + ... + 4 + 8 + + + + + + + ... + +``` + +## 配置虚拟设备 + +虚拟机XML配置文件使用devices元素配置虚拟设备,包括存储设备、网络设备、总线、鼠标等,本节介绍常用的虚拟设备如何配置。 + +### 存储设备 + +#### 概述 + +XML配置文件可以配置虚拟存储设备信息,包括软盘、磁盘、光盘等存储介质及其存储类型等信息,本节介绍存储设备的配置方法。 + +#### 元素介绍 + +XML配置文件使用disk元素配置存储设备,disk常见的属性如[表1](#table14200183410353)所示,常见子元素及子元素属性如[表2](#table4866134925114)所示。 + +**表 1** 元素disk的常用属性 + + + + + + + + + + + + + + + + + + +

元素

+

属性

+

含义

+

属性值及其含义

+

disk

+

type

+

指定后端存储介质类型

+

block:块设备

+

file:文件设备

+

dir:目录路径

+

network:网络磁盘

+

device

+

指定呈现给虚拟机的存储介质

+

disk:磁盘(默认)

+

floppy:软盘

+

cdrom:光盘

+
+ +**表 2** 元素disk的常用子元素及属性说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

子元素

+

子元素含义

+

属性说明

+

source

+

指定后端存储介质,与disk元素的属性“type”指定类型相对应

+

· file:对应file类型,值为对应文件的完全限定路径。

+

· dev:对应block类型,值为对应主机设备的完全限定路径。

+

· dir:对应dir类型,值为用作磁盘目录的完全限定路径。

+

· protocol:使用的协议。

+

· name:rbd磁盘名称,格式为:$pool/$volume。

+

· host name:mon地址。

+

· port:mon地址的端口。

+ +

driver

+

指定后端驱动的详细信息

+

· type:磁盘格式的类型,常用的有“raw”和“qcow2”,需要与source的格式一致。

+

· io:磁盘IO模式,支持“native”和“threads”选项。

+

· cache:磁盘的cache模式,可选项有“none”、“writethrough”、“writeback”、“directsync”等。

+

· iothread:指定为磁盘分配的IO线程。

+

· error_policy:IO写错误发生时的处理策略,可选项有“stop”、“report”、“ignore”、“enospace"、"retry"等。

+

· rerror_policy:IO读错误发生时的处理策略,可选项有“stop”、“report”、“ignore”、“enospac”、“retry"等。

+

· retry_interval:IO错误重试间隔,范围为0-MAX_INT,单位为毫秒,仅error_policy=“retry”或rerror_policy=“retry”时可配置。

+

· retry_timeout:IO错误重试超时时间,范围为0-MAX_INT,单位为毫秒,仅error_policy=“retry”或rerror_policy=“retry”时可配置。

+

target

+

指磁盘呈现给虚拟机的总线和设备

+

· dev:指定磁盘的逻辑设备名称,如SCSI、SATA、USB类型总线常用命令习惯为sd[a-p],IDE类型设备磁盘常用命名习惯为hd[a-d]。

+

· bus:指定磁盘设备的类型,常见的有“scsi”、“usb”、“sata”、“virtio”等类型。

+

boot

+

表示此磁盘可以作为启动盘使用

+

· order:指定磁盘的启动顺序。

+

readonly

+

表示磁盘具有只读属性,磁盘内容不可以被虚拟机修改,通常与光驱结合使用

+

-

+
+ +#### 配置示例 + +按照“准备虚拟机镜像”操作完成虚拟机镜像准备后,可以使用如下XML配置文件示例,为虚拟机配置虚拟磁盘。 + +例如,该示例为虚拟机配置了两个IO线程,一个块磁盘设备,一个光盘设备和一个rbd磁盘,第一个IO线程分配给块磁盘设备使用。该块磁盘设备的后端介质为qcow2格式,且被作为优先启动盘。 +在使用rbd磁盘前请确保已经安装qemu-block-rbd驱动,如未安装,请在root下使用如下命令进行安装: + +```bash +# yum install qemu-block-rbd +``` + +配置实例: + +```xml + + ... + 2 + + + + + + + + + + + + + + + + + + + + + + ... + + +``` + +### 网络设备 + +#### 概述 + +XML配置文件可以配置虚拟网络设备,包括ethernet模式、bridge模式、vhostuser模式等,本节介绍虚拟网卡设备的配置方法。 + +#### 元素介绍 + +XML配置文件中使用元素“interface”,其属性“type”表示虚拟网卡的模式,可选的值有“ethernet”、“bridge”、“vhostuser”等,下面以“bridge”模式虚拟网卡为例介绍其子元素以及对应的属性。 + +**表 3** bridge模式虚拟网卡常用子元素 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

子元素

+

子元素含义

+

属性及含义

+

mac

+

虚拟网卡的mac地址

+

address:指定mac地址,若不配置,会自动生成。

+

target

+

后端虚拟网卡名

+

dev:创建的后端tap设备的名称。

+

source

+

指定虚拟网卡后端

+

bridge:与bridge模式联合使用,值为网桥名称。

+

boot

+

表示此网卡可以作为远程启动

+

order:指定网卡的启动顺序。

+

model

+

表示虚拟网卡的类型

+

type:bridge模式网卡通常使用virtio。

+

virtualport

+

端口类型

+

type:若使用OVS网桥,需要配置为openvswitch。

+

driver

+

后端驱动类型

+

name:驱动名称,通常取值为vhost。

+

queues:网卡设备队列数。

+
+ +#### 配置示例 + +- 按照“准备虚拟机网络”创建了Linux网桥br0后,配置一个桥接在br0网桥上的virtio类型的虚拟网卡设备,对应的XML配置如下: + + ```xml + + ... + + + + + + ... + + + ``` + +- 按照“准备虚拟机网络”创建了OVS网桥后,配置一个后端使用vhost驱动,且具有四个队列的virtio虚拟网卡设备。 + + ```xml + + ... + + + + + + + + ... + + + ``` + +### 总线配置 + +#### 概述 + +总线是计算机各个部件之间进行信息通信的通道。外部设备需要挂载到对应的总线上,每个设备都会被分配一个唯一地址(由子元素address指定),通过总线网络完成与其他设备或中央处理器的信息交换。常见的设备总线有ISA总线、PCI总线、USB总线、SCSI总线、PCIe总线。 + +PCIe总线是一种典型的树结构,具有比较好的扩展性,总线之间通过控制器关联,这里以PCIe总线为例介绍如何为虚拟机配置总线拓扑。 + +>[!NOTE]说明 +>总线的配置相对比较繁琐,若不需要精确控制设备拓扑结构,可以使用libvirt自动生成的缺省总线配置。 + +#### 元素介绍 + +在libvirt的XML配置中,每个控制器元素(使用controller元素表示)可以表示一个总线,根据虚拟机架构的不同,一个控制器上通常可以挂载一个或多个控制器或设备。这里介绍常用属性和子元素。 + +controller:控制器元素,表示一个总线。 + +- 属性type:控制器必选属性,表示总线类型。常用取值有“pci”、“usb”、“scsi”、“virtio-serial”、“fdc”、“ccid”。 +- 属性index:控制器必选属性,表示控制器的总线“bus”编号(编号从0开始),可以在地址元素“address”元素中使用。 +- 属性model:控制器必选属性,表示控制器的具体型号,其可选择的值与控制器类型“type”的值相关,对应关系及含义请参见[表4](#table191911761111)。 +- 子元素address:为设备或控制器指定其在总线网络中的挂载位置。 + - 属性type:设备地址类型。常用取值有“pci”、“usb”、“drive”。address的type类型不同, 对应的属性也不同,常用type属性值及其该取值下address的属性请参见[表5](#table1200165711314)。 + +- 子元素model:控制器具体型号的名称。 + - 属性name:指定控制器具体型号的名称,和父元素controller中的属性model对应。 + +**表 4** controller属性type常用取值和model取值对应关系 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

type属性值

+

model属性值

+

简介

+

pci

+

pcie-root

+

PCIe根节点,可挂载PCIe设备或控制器

+

pcie-root-port

+

只有一个slot,可以挂载PCIe设备或控制器

+

pcie-to-pci-bridge

+

PCIe转PCI桥控制器,可挂载PCI设备

+

usb

+

ehci

+

USB 2.0控制器,可挂载USB 2.0设备

+

nec-xhci

+

USB 3.0控制器,可挂载USB 3.0设备

+

scsi

+

virtio-scsi

+

virtio类型SCSI控制器,可以挂载块设备,如磁盘,光盘等

+

virtio-serial

+

virtio-serial

+

virtio类型串口控制器,可挂载串口设备,如pty串口

+
+ +**表 5** address元素不同设备类型下的属性说明 + + + + + + + + + + + + + + + + + + + + +

类型type属性值

+

含义

+

对应地址属性

+

pci

+

地址类型为PCI地址,表示该设备在PCI总线网络中的挂载位置。

+

domain:PCI设备的域号

+

bus:PCI设备的bus号

+

slot:PCI设备的device号

+

function:PCI设备的function号

+

multifunction:controller元素可选,是否开启multifunction功能

+

usb

+

地址类型为USB地址,表示该设备在USB总线中的位置。

+

bus:USB设备的bus号

+

port:USB设备的port号

+

drive

+

地址类型存储设备地址,表示所属的磁盘控制器,及其在总线中的位置。

+

controller:指定所属控制器号

+

bus:设备输出的channel号

+

target:存储设备target号

+

unit:存储设备lun号

+
+ +#### 配置示例 + +该示例给出一个PCIe总线的拓扑结构。PCIe根节点(BUS 0)下挂载了三个PCIe-Root-Port控制器。第一个PCIe-Root-Port控制器(BUS 1)开启了multifunction功能,并在其下挂载一个PCIe-to-PCI-bridge控制器,形成了一个PCI总线(BUS 3),该PCI总线上挂载了一个virtio-serial设备和一个USB 2.0控制器。第二个PCIe-Root-Port控制器(BUS 2)下挂载了一个SCSI控制器。第三个PCIe-Root-Port控制器(BUS 0)下无挂载设备。配置内容如下: + +```xml + + ... + + + +
+ + +
+ + + +
+ + +
+ + +
+ + +
+ + +
+ + ... + + +``` + +### 其他常用设备 + +#### 概述 + +除存储设备、网络设备外,XML配置文件中还需要指定一些其他外部设备,本节介绍这些元素的配置方法。 + +#### 元素介绍 + +- serial:串口设备 + + 属性type:用于指定串口类型。常用属性值为pty、tcp、pipe、file。 + +- video:媒体设备 + + 属性type:媒体设备类型。AArch64架构常用属性值为virtio,x86\_64架构通常使用属性值为vga或cirrus。 + + 子元素model:video的子元素,用于指定媒体设备类型。 + + 在model元素中,type属性为vga表示配置VGA类型显卡,vram属性代表显存大小,单位默认为KB。 + + 例如,给x86\_64架构虚拟机配置16MB的VGA类型的显卡,XML示例如下,其中vram属性代表显存大小,单位默认为KB。 + + ```conf + + ``` + +- input:输入设备 + + 属性type:指定输入设备类型。常用属性值为tablet、keyboard,分别表示输入设备为写字板、键盘。 + + 属性bus:指定挂载的总线。常用属性值为USB。 + +- emulator:模拟器应用路径。 +- graphics:图形设备。 + + 属性type:指定图形设备类型。常用属性值为vnc。 + + 属性listen:指定侦听的IP地址。 + +#### 配置示例 + +例如,在下面的示例中,配置了虚拟机的模拟器路径,pty串口、virtio媒体设备、USB写字板、USB键盘以及VNC图形设备。 + +>[!NOTE]说明 +>graphics的type配置为VNC时,建议配置属性passwd,即使用VNC登录时的密码。 + +```xml + + ... + + /usr/libexec/qemu-kvm + + + + + + ... + + +``` + +## 体系架构相关配置 + +### 概述 + +XML中还有一部分体系架构相关的配置,这部分配置包括主板,CPU,一些与体系架构相关的feature,本章节主要介绍它们的配置和含义。 + +### 元素介绍 + +- os:定义虚拟机启动参数。 + + 子元素type:指定虚拟机类型,属性arch表示架构类型,如aarch64,属性machine表示虚拟机的芯片组类型,虚拟机支持的芯片组可以通过 **qemu-kvm -machine ?** 命令查询,如AArch64结构使用“virt”类型。 + + 子元素loader:指定加载固件 ,如配置EDK提供的UEFI文件,属性readonly表示是否是只读文件,值为“yes”或“no”,属性type表示loader的类型,常用的值有“rom”、“pflash”。 + + 子元素nvram:指定nvram文件路径,用于存储UEFI启动配置。 + +- features:hypervisor支持控制一些虚拟机CPU/machine的特性,如高级电源管理接口“acpi”,ARM处理器指定GICv3中断控制器等。 + +### AArch64架构配置示例 + +虚拟机的类型为AArch64结构,使用virt芯片组,利用UEFI启动的虚拟机配置如下: + +```xml + + ... + + hvm + /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw + /var/lib/libvirt/qemu/nvram/openEulerVM.fd + + ... + +``` + +为虚拟机配置ACPI和GIC V3中断控制器特性。 + +```xml + + + + +``` + +### x86\_64架构配置示例 + +x86\_64架构支持BIOS和UEFI两种启动方式,如果不配置loader,则使用默认启动方式BIOS。这里给出启动方式为UEFI、芯片组为q35的配置参考。 + +```xml + + ... + + hvm + /usr/share/edk2/ovmf/OVMF.fd + + ... + +``` + +## 其他常见配置项 + +### 概述 + +除系统资源和虚拟设备外,XML配置文件还需要配置一些其他元素,本节介绍这些元素的配置方法。 + +### 元素介绍 + +- iothreads:指定iothread数量,可以用于加速存储设备性能。 + +- on\_poweroff:虚拟机关闭时采取的动作。 +- on\_reboot:虚拟机重启时采取的动作。 +- on\_crash:虚拟机崩溃时采取的动作。 +- clock:采用的时钟类型。 + + 属性offset:设置虚拟机时钟的同步类型,可选的值有“localtime”、“utc”、“timezone”、“variable”等。 + +### 配置示例 + +为虚拟机配置两个iothread,用于加速存储设备性能。 + +```xml +2 +``` + +虚拟机关闭时,销毁虚拟机。 + +```xml +destroy +``` + +虚拟机重启时,重新启动虚拟机。 + +```xml +restart +``` + +虚拟机崩溃时,重新启动虚拟机。 + +```xml +restart +``` + +时钟采用“utc”的同步方式。 + +```xml + +``` + +## XML配置文件示例 + +### 概述 + +本节给出一个基本的AArch64虚拟机和一个x86\_64虚拟机的XML配置文件示例,供用户参考。 + +### 示例一 + +一个包含基本元素的AArch64架构虚拟机的XML配置文件,其内容示例如下: + +```xml + + openEulerVM + 8 + 4 + + hvm + /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw + /var/lib/libvirt/qemu/nvram/openEulerVM.fd + + + + + + + + + 1 + + destroy + restart + restart + + /usr/libexec/qemu-kvm + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +### 示例二 + +一个包含基本元素及总线元素x86\_64架构虚拟机的XML配置文件,其配置示例如下: + +```xml + + openEulerVM + 8388608 + 8388608 + 4 + 1 + + hvm + + + + + + + + + destroy + restart + restart + + /usr/libexec/qemu-kvm + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + + + +