目录

CPU mode

1)custom模式

2)host-model模式

3)host-passthrough模式

CPU topology

VCPU映射CPU

CPU热插拔 

CPU Nested技术


Libvirt是KVM/QEMU hypervisor driver,在/usr/share/libvirt/cpu_map.xml定义了CPU的模型,目前仅支持x86和ppc64架构。
https://libvirt.org/drvqemu.html

<cpus>
<arch name='x86'>
  <!-- vendor definitions -->
<vendor name='Intel' string='GenuineIntel'/>
  <vendor name='AMD' string='AuthenticAMD'/>
<!-- standard features, EDX -->
<feature name='fpu'>
<cpuid eax_in='0x01' edx='0x00000001'/>
</feature>
……
<model name='xxx_model'>
      <signature family='23' model='1'/>
      <vendor name='厂商'/>
<feature name='xxx_instruction'/>
</model>
……
</arch>
<arch name='ppc64'>
  <!-- vendor definitions -->
  <vendor name='IBM'/>
  <vendor name='Freescale'/>
<!-- IBM-based CPU models -->
<model name='POWER6'>
<vendor name='IBM'/>
<pvr value='0x003e0000' mask='0xffff0000'/>
</model>
……
  </arch>
</cpus>

CPU mode

1)custom模式

三种mode的性能排序是:host-passthrough > host-model > custom
三种mode的热迁移通用性是: custom > host-model > host-passthrough

本模式下虚拟机 CPU 指令集数最少,故性能相对最差,但是它在热迁移时跨不同型号 CPU 的能力最强。此外,custom 模式下支持用户添加额外的指令集。deployment.xml/libvirt.xml中配置如下:

<cpu mode='custom' match='exact' check='partial'>
     <model fallback='allow'>Westmere-IBRS</model>
</cpu>

启动参数如下:
-cpu Westmere-IBRS

2)host-model模式

libvirt 根据当前宿主机 CPU 指令集从配置文件 /usr/share/libvirt/cpu_map.xml 选择一种最相配的 CPU 型号。在这种 mode 下,虚拟机的指令集往往比宿主机少,性能相对 host-passthrough 要差一点,但是热迁移时,它允许目的节点 CPU 和源节点的存在一定的差异。

xml配置文件如下:

  <cpu mode='host-model' check='partial'>
     <model fallback='allow'/>
  </cpu>

等效于(仅对于某种场景下):

<cpu mode='custom' match='exact' check='partial'>
     <model fallback='allow'>Westmere-IBRS</model>
        <feature policy='require' name='vme'/>
        <feature policy='require' name='ss'/>
        <feature policy='require' name='ht'/>
        <feature policy='require' name='osxsave'/>
        <feature policy='require' name='f16c'/>
        <feature policy='require' name='rdrand'/>
        <feature policy='require' name='hypervisor'/>
        <feature policy='require' name='arat'/>
        <feature policy='require' name='stibp'/>
        <feature policy='require' name='pdpe1gb'/>
        <feature policy='disable' name='tsc-deadline'/>
        <feature policy='disable' name='bmi1'/>
        <feature policy='disable' name='hle'/>
        <feature policy='disable' name='avx2'/>
        <feature policy='disable' name='bmi2'/>
        <feature policy='disable' name='invpcid'/>
        <feature policy='disable' name='rtm'/>
        <feature policy='disable' name='rdseed'/>
        <feature policy='disable' name='adx'/>
        <feature policy='disable' name='smap'/>
</cpu>

启动参数如下(在Broadwell-IBRS的指令集基础上,增加和删除部分):

-cpu Broadwell-IBRS,+vme,+ss,+ht,+vmx,+osxsave,+f16c,+rdrand,+hypervisor,+arat,+stibp,+pdpe1gb,-tsc-deadline,-bmi1,-hle,-avx2,-bmi2,-invpcid,-rtm,-rdseed,-adx,-smap

Host-model type

Libvirt对CPU提炼出标准的几种类型,在/usr/share/libvirt/cpu_map.xml中可以查到。

cat /usr/share/libvirt/cpu_map.xml |grep 'model name'
<model name='486'>
……
<model name='Westmere-IBRS'>
……
<model name='POWERPC_e6500'>

3)host-passthrough模式

libvirt 令 KVM 把宿主机的 CPU 指令集全部透传给虚拟机。因此虚拟机能够最大限度的使用宿主机 CPU 指令集,故性能是最好的。但是在热迁移时,它要求目的节点的 CPU 和源节点的一致。xml配置文件如下:

  <cpu mode='host-passthrough' check='none'>
    <topology sockets='4' cores='1' threads='1'/>
  </cpu>

启动参数如下:

-cpu host

 

1)需要将物理CPU的一些特性传给虚拟机使用,比如使用虚拟机嵌套的nested技术的时候

2)需要在虚拟机里面看到和物理CPU一模一样的CPU品牌型号,这个在公有云很有意义,用户体验比较好

注意:使用CPU host-passthrough技术需要注意,不同型号的CPU宿主机之间虚拟机不能迁移

 

CPU topology

不配置CPU topology 默认是1 socket à 1 cores à 1 thread;也就是配置n个vcpu,则在虚拟机中就有n个physical cpu,每个物理cpu1个core。例如:

<vcpu placement='static'>4</vcpu>
<cpu>
<topology sockets='4' cores='1' threads='1'/>
</cpu>

Vcpu = sockets*cores*threads

socket

A CPU socket or a CPU package refers to a physical unit of CPU which is plugged into a system board.For example, a 4-way system or a 4-socket system can contain up to four CPUpackages Core。

翻译过来就是:socket就是主板上插cpu的槽的数目,也即管理员说的“路”。socket是指主板上能够放置的处理器芯片的个数,是一个物理的概念,一个socket上的处理器可能包含多个CPU core。

core

core就是我们平时说的“核”,即双核,4核等,这个core其实可以是指物理的实际的core,也可以是虚拟的core。

thread

thread就是每个core的硬件线程数,即超线程。

Hyper threading

Hyper threading allows a single physical processor core to behave like two logical processors.The processor can run two independent applications at the same time. A processor core may have multiple logical processors that share computer resources of the core。

SMP,对称多处理器(Symmetric Multi-Processors,简称SMP)

有些比较老的操作系统支持的CPU个数(插槽数)比较少(比如:Windows Server 2003标准版支持最多4个processor),所以通过<topology sockets='<=4' cores='>1' threads='>1'/>令2003可以使用更多vcpu数量。

windows server 2008 r2

支持sockets

标准版

4

企业版

8

数据中心

64

 

如果限制sockets为4,使得参数为sockets=4,cores=2,threads=1,则guest OS能看到全部8个core。

Openstack上flavor默认是cores=1,threads=1,上面这种情况需要更改flavor的元数据

$ openstack flavor set --property hw:cpu_max_cores='4' win10.c4m2d20
$ openstack flavor show win10.c4m2d20

hw:cpu_max_cores='4', hw:cpu_max_sockets='2', hw:cpu_max_threads='2'

https://docs.openstack.org/nova/pike/admin/cpu-topologies.html

 

VCPU映射CPU

不配置,默认vcpu在host的所有cpu之间进行调度。其原理是libvirt通过Cgroup来实现的。
CPU Affinity:   yyyyyyyyyyyyyyyyyyyyyyyy
设置CPU调度范围

cat /proc/cpuinfo |grep cores |wc -l
24
<cputune>
  <emulatorpin cpuset=’20-24’/>
</cputune>

CPU Affinity:   --------------------yyyyyy
强制vCPU和CPU一一对应

<cputune>
  <vcpupin vcpu=’0’ cpuset=’20’/>
  <vcpupin vcpu=’0’ cpuset=’21’/>
  <vcpupin vcpu=’0’ cpuset=’22’/>
  <vcpupin vcpu=’0’ cpuset=’23’/>
</cputune>
# virsh vcpuinfo 3
……
CPU Affinity:   --------------------y---
CPU Affinity:   ---------------------y--
CPU Affinity:   ----------------------y-
CPU Affinity:   -----------------------y

通过stress CPU压测工具压测:

stress -c 4 --timeout 60s

在宿主机上使用top查看只有20-23 四颗CPU利用率是100%,其他CPU都是空闲状态。

CPU热插拔 

类似KVM 内存管理,可以使用virsh命令给正在运行的VM添加或删除vCPU。不过,这个工作是需要预先配置KVM虚拟机的最大vCPU参数才能使用。

<vcpu placement='static' current='6'>8</vcpu>

给KVM虚拟机设置最大vCPU数量8,并不会对资源有所消耗,因为虚拟机只会使用current指定的vCPU。

<vcpu placement='static' current="4">6</vcpu>
  <cputune>
    <shares>8192</shares>
    <vcpupin vcpu='0' cpuset='17'/>
    <vcpupin vcpu='1' cpuset='18'/>
    <vcpupin vcpu='2' cpuset='19'/>
    <vcpupin vcpu='3' cpuset='20'/>
    <vcpupin vcpu='4' cpuset='21'/>
    <vcpupin vcpu='5' cpuset='22'/>
  </cputune>

如上,vcpu最大6核,并且也绑定了6颗CPU,但是虚机只是用4颗,按照顺序为0-3。

## 增加到 6核

virsh setvcpus LDAP05 6 --live

## 减少到2核

virsh setvcpus LDAP05 2 --live

error: unsupported configuration: failed to find appropriate hotpluggable vcpus to reach the desired target vcpu count

减少内核,并不支持。但是可以曲线救国:

1、在guest上安装qemu-guest-agent;

2、在guest xml配置文件中追加:

<devices>
……
<channel type='unix'>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
</channel>
</devices>

3、Guest需要重新启动,不是reboot;先关闭虚机,重新使用virsh start LDAP05启动;

        virsh qemu-agent-command LDAP05 --cmd '{"execute":"guest-info"}'

     可以获取到虚机相关信息,包含了可以执行的command,例如:

        virsh qemu-agent-command LDAP05 --cmd '{"execute":"guest-get-osinfo"}'

                                                                  

 

此时,即可执行减少CPU的命令了:

virsh setvcpus LDAP05 2 --live --guest

通过virsh vcpuinfo LDAP05 查看还是4个核心

Guest中执行lscpu也是4个核心,不过禁用了2个:

CPU(s):                4

On-line CPU(s) list:   0,3

Off-line CPU(s) list:  1,2

Thread(s) per core:    1

Core(s) per socket:    1

Socket(s):             2

Guest通过top查看确实是2个核心在工作了。Guest重启失效,如果要想永久生效,则需要执行:

virsh setvcpus --config LDAP05 2

其实就是写xml将current的值改为2。

 

当然,如果可以关闭虚拟机修改配置,那就啥也不是事。直接virsh edit即可。

CPU Nested技术

生产环境不建议使用!

Vmware第一层是用的 硬件虚拟化技术,第二层就是软件全虚拟化。

KVM通过CPU Passthrough技术将物理CPU特性全部传递给虚拟机,所以理论上可以嵌套N层,但事实是跑第二层就很慢了。

CentOS 7官方宣称不正式支持Nested技术,所以要想玩嵌套,最好使用Fedora。

               --- 来自于《深度实践KVM》

本人在搭建OpenStack环境时,当时的计算节点是一台Vmware虚拟机,然后嵌套了一台KVM实例。感官上,其性能只有第一层的50%左右。

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐