KVM虚拟化:(七)CPU设置简介

admin 2022年10月31日 1,345次浏览

在 QEMU/KVM 中,QEMU 提供对 CPU 的模拟,展现给客户机一定的 CPU 数目和 CPU 的特性。在 KVM 打开的情况下,客户机中 CPU 指令的执行由硬件处理器的虚拟化功能(如 Intel VT-x 和 AMD AMD-V)来辅助执行,具有非常高的执行效率

1、vCPU的概念

QEMU/KVM 为客户机提供一套完整的硬件系统环境,在客户机看来,其所拥有的 CPU 即是 vCPU。在 KVM 环境中,每个客户机都是一个标准的 Linux 进程(QEMU 进程),而每一个 vCPU 在宿主机中是 QEMU 进程派生的一个普通线程

在普通的 Linux 系统中,进程一般有两种执行模式:内核模式和用户模式。而在 KVM 环境中,增加了第3种模式:客户模式。vCPU 在3种执行模式下的不同分工如下

  • 用户模式(User Mode)

    主要处理 I/O 的模拟和管理,由 QEMU 的代码实现

  • 内核模式(Kernel Mode)

    主要处理特别需要高性能和安全相关的指令,如处理客户模式到内核模式的转换,处理客户模式下的 I/O 指令或其他特权指令引起的退出(VM-Exit),处理影子内存管理(shadow MMU)

  • 客户模式(Guest Mode)

    主要执行 Guest 中的大部分指令,I/O 和一些特权指令除外

KVM 中的一个客户机是作为一个用户空间进程(qemu)运行的,它和其他普通的用户空间进程一样由内核来调度,使其运行在物理 CPU 上,不过它由 kvm 模块的控制,可以在前面介绍的3种执行模式下运行。多个客户机就是宿主机中的多个 QEMU 进程,而一个客户机的多个 vCPU 就是一个 QEMU 进程中的多个线程

2、SMP的支持

2.1、SMP概述

SMP(对称多处理器)系统,在 SMP 系统中,多个程序(进程)可以真正做到并行执行,而且单个进程的多个线程也可以得到并行执行,这极大地提高了计算机系统并行处理能力和整体性能。随着多核技术、超线程技术的出现,SMP 系统使用多处理器、多核、超线程等技术中的一个或多个技术

在Linux中,下面的 Bash 脚本可以根据 /proc/cpuinfo 文件来检查当前系统中的 CPU 数量、多核及超线程的使用情况

#!/bin/bash
# file_name:CPU_info.sh
# 查看逻辑CPU个数
echo -n "逻辑CPU总数: "
cat /proc/cpuinfo | grep "processor" | wc -l
# 如果没有多核也没有打开超线程,就直接退出脚本
cat /proc/cpuinfo | grep -qi "core id"
if [ $? -ne 0 ]; then
echo "非多核处理器或未开启超线程"
exit 0;
fi

# 查看物理CPU个数
echo -n "物理CPU数量: "
cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l
echo -n "物理CPU中的核心数量: "
#每个物理CPU上core的个数(未计入超线程)
core_per_phy_cpu=$(cat /proc/cpuinfo | grep "core id" | sort | uniq | wc -l)
echo $core_per_phy_cpu

# 查看物理CPU中的逻辑CPU号
echo -n "物理CPU中的逻辑CPU数量: "
## 每个物理CPU中逻辑CPU的个数
logical_cpu_per_phy_cpu=$(cat /proc/cpuinfo | grep "siblings" | sort | uniq | awk -F: '{print $2}')
echo $logical_cpu_per_phy_cpu
## 查看是否打开超线程,以及每个core上的超线程数目
## 如果在同一个物理CPU上的两个逻辑CPU具有相同的”core id”,那么超线程是打开的
## 此处根据前面计算的core_per_phy_cpu和logical_core_per_phy_cpu的比较来查看超线程
if [ $logical_cpu_per_phy_cpu -gt $core_per_phy_cpu ]; then
echo "超线程已启用。每个内核都有 $(expr $logical_cpu_per_phy_cpu / $core_per_phy_cpu ) 个线程."
elif [ $logical_cpu_per_phy_cpu -eq $core_per_phy_cpu ]; then
echo "超线程未启用."
else
echo "运行出错!"
fi

由于 SMP 广泛被使用,而 QEMU 在给客户机模拟 CPU 时,也可以提供对 SMP 架构的模拟,让客户机运行在SMP 系统中,充分利用物理硬件的 SMP 并行处理优势。由于每个 vCPU 在宿主机中都是一个线程,并且宿主机 Linux 系统是支持多任务处理的,因此可以通过两种操作来实现客户机的 SMP,一是将不同的 vCPU 的进程交换执行,二是将在物理 SMP 硬件系统上同时执行多个 vCPU 的进程

在 qemu 命令行中,-smp 参数即是配置客户机的 SMP 系统,其具体参数如下:

-smp [cpus=]N[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]
  • N(或cpus=N):用于设置客户机中使用的逻辑CPU数量(默认值是1)
  • maxcpus:用于设置客户机中最大可能被使用的CPU数量
  • cores:用于设置每个CPU的core数量(默认值是1)。
  • threads:用于设置每个core上的线程数(默认值是1)。
  • sockets:用于设置客户机中看到的总的CPU 插槽数量

在 RHEL9 中,默认已经不提供 qemu-system-x86_64 命令,可以使用 virt-install 在创建虚拟机时指定

--vcpus N[,maxvcpus=N][,sockets=sockets][,cores=cores][,threads=threads]

2.2、配置示例

  • 不配置SMP

    [root@kvm ~]# qemu-system-x86_64 -m 4G centos7.qocw2
    
  • 直接分配4个vCPU给客户机(不启用超线程)

    [root@kvm ~]# qemu-system-x86_64 -smp 4 -m 4G centos7.qocw2
    
  • 分配4个vCPU给客户机(启用超线程)

    [root@kvm ~]# qemu-system-x86_64 -m 4G -smp 4,sockets=1,cores=2,threads=2 centos7.qocw2
    
  • RHEL9配置示例

    [root@kvm ~]# virt-install \
    --name test \
    --disk /data/vmhost/rocky9-test,size=50 \
    --memory 4096 \
    --vcpus 2,maxvcpus=4 \
    --os-variant rocky9.0 \
    --location /iso/Rocky-9.1-x86_64-dvd.iso
    

    –name:虚拟机名称
    –disk:硬盘存储位置及大小(GB)
    –memory:内存大小
    –vcpus:CPU数量
    –os-variant:要安装到客户机中的操作系统,可只用 --osinfo list 查看
    –location:ISO文件路径或URL路径

3、CPU过载使用

KVM 允许客户机过载使用(over-commit)物理资源,即允许为客户机分配的 CPU 和内存数量多于物理上实际存在的资源。CPU 的过载使用是让一个或多个客户机使用 vCPU 的总数量超过实际拥有的物理 CPU数量,QEMU 会启动更多的线程来为客户机提供服务,这些线程也被 Linux 内核调度运行在物理 CPU 硬件上

关于 CPU 的过载使用,推荐的做法是对多个单 CPU 的客户机使用 over-commit,比如,在拥有4个逻辑CPU的宿主机中,同时运行多于4个客户机,其中每个客户机都分配一个 vCPU;最不推荐的做法是让某一个客户机的 vCPU 数量超过物理系统上存在的 CPU 数量,比如在拥有4个逻辑 CPU 的宿主机中,同时运行一个或多个客户机,其中每个客户机的 vCPU 数量多于4个

虽然 KVM 允许 CPU 的过载使用,但是并不推荐在实际的生产环境中过载使用 CPU

4、CPU模型

QEMU/KVM 在默认情况下会向客户机提供一个名为 qemu64 或 qemu32 的基本 CPU 模型。QEMU/KVM 的这种策略会带来一些好处,例如可以对 CPU 特性提供一些高级的过滤功能,还可以将物理平台根据提供的基本 CPU 模型进行分组,从而使客户机在同一组硬件平台上的动态迁移更加平滑和安全。可以使用 qemu-system-x86_64 -cpu ? 命令或者通过 /usr/share/libvirt/cpu_map 文件查看当前 QEMU 支持的所有CPU模型

在 x86-64 平台上编译和运行的 QEMU,在不加 -cpu 参数启动时,采用 qemu64 作为默认的 CPU 模型,如 qemu-system-x86_64 centos7.qocw2

在qemu命令行中,可以用 -cpu cpu_model 来指定在客户机中的 CPU 模型

qemu-system-x86_64 centos7.qocw2 -cpu Broadwell -smp 4 -m 4G -enable-kvm

# RHEL9
[root@kvm ~]# virt-install \
--name test \
--disk /data/vmhost/rhel6-test,size=50 \
--memory 4096 \
--vcpus 2,maxvcpus=4 \
--cpu model=core2duo \
--os-variant rhel6.5 \
--location /iso/rhel-server-6.5-x86_64-dvd/rhel-server-6.5-x86_64-dvd.iso

5、进程的处理器亲和性和vCPU的绑定

进程的处理器亲和性(Processor Affinity)即 CPU 的绑定设置,是指将进程绑定到特定的一个或多个 CPU 上去执行,而不允许将进程调度到其他的 CPU 上

设置进程的处理器亲和性带来的好处是可以减少进程在多个 CPU 之间交换运行带来的缓存命中失效(cache missing),从该进程运行的角度来看,可能带来一定程度上的性能提升。换个角度来看,对进程亲和性的设置也可能带来一定的问题,如破坏了原有 SMP 系统中各个 CPU 的负载均衡,这可能会导致整个系统的进程调度变得低效,特别是在使用多处理器、多核、多线程技术的情况下