OpenStack是 一个IAAS(基础设施即服务)因此免不了会与硬件打交道。下面我介绍下与CPU强关联的一些知识点。1 什么是超配 2 CPU的个数是怎么统计的 3 vCPU的隔离、绑定
1、超配
在kvm虚拟化的环境中,一个vCPU本质上是一个kvm的一个线程,如果一台虚拟机有4个vCPU,对应的就是4个线程。
-
1.1 假设VM1 有两个2vCPU, VM2 也有两个vCPU,而物理机上总共只有2个CPU,则这4个线程是在两个物理CPU上调度的。这也就说明即虚机的 VCPU 总数可以超过物理 CPU 数量,这个叫CPU overcommit(超配); KVM 允许 overcommit,这个特性使得虚机能够充分利用宿主机的 CPU 资源但前提是在同一时刻,不是所有的虚机都满负荷运行。
-
1.2 在实际的生产中经验,在x86架构中我们建议的通用型配置是1:3的超配比,而在ARM架构中该比例为1:2。(注:该配置仅仅为建议配置,实际生产中要根据自己的业务和CPU的型号不同,在充分测试下才能给出合理的超分比例。)
-
1.3 那在OpenStack的环境中我们如何查看和设置超配比例?
配置文件的方式
cpu_allocation_ratio=3 #cpu 超分比
disk_allocation_ratio=1.0 #磁盘 超分比
ram_allocation_ratio=1.0 #内存 超分比
命令行方式
查看计算节点id
nova hypervisor-list
设置 cpu 超分比2.0
nova hypervisor-set-ratio --cpu 2.0 a1266c51-e693-4bf9-84dc-37b3d15322e7
查看 超分比
2、CPU统计
物理机CPU的统计用一个简单的公式就能算出每台物理机拥有的CPU总数。
系统可用的CPU总数(逻辑处理器) = Socket数(CPU个数)x Core数(内核)x Thread数(超线程)
Socket数 :就是我们常说的几路CPU ,如两路CPU 就会有两个Socket
Core数 : 物理核心的数量。
Thread数 :系统层上的多线程技术。超线程即是可在同一时间里,应用程序可以使用芯片的不同部分。虽然单线程芯片每秒钟能够处理成千上万条指令,但是在任一时刻只能够对一条指令进行操作。而超线程技术可以使芯片同时进行多线程处理,使芯片性能得到提升。
总的来说就是一台物理机上有N路CPU ,而每个CPU有M个核心数,每个核心上还可以支持超线程。
下面我们用实际生产中CPU来举例
X86
ARM
3、CPU独占、绑定
3.1 CPU隔离实战
为什么我们需要CPU独占?
1、在公有云中我们在购买云主机时,会发现云主机有如下两类,一类是共享型云主机,一类是独享型云主机,这两种云主机有什么区别了?
其实他们的本质区别就是线程占用CPU是否是独占的,前面我们说过,KVM虚拟化环境中每一个vCPU在物理机上都只是一个线程,如果他对物理CPU是独占的就是独享型云主机,独享型不会出现资源争夺线现象,计算性能更加稳定。
共享型云主机,每个vCPU会被随机分配到任何空闲CPU超线程上,不同实例vCPU会争抢物理CPU资源。
这样我们提一个有争议的话题,那独享型云主机的VCPU的个数是否和物理机的CPU数是1 : 1 的关系了?
2、在超融合环境中(OpenStack的管理节点和计算节点和网络节点都在同一台物理机上)如何将租户使用的CPU和管理侧的CPU进行隔离?
3、DPDK是一种用户空间的网络框架,旨在通过绕过操作系统内核的网络栈,直接访问网络设备,从而提高网络处理性能。通过将特定的CPU核心隔离出来并专门用于运行DPDK应用程序,可以避免其他进程或内核线程对这些CPU核心的竞争,减少上下文切换和干扰,从而提高DPDK应用程序的性能。
上述环境中都免不了要使用CPU独占技术,在KVM虚拟机的环境中,在Linux内核启动的命令行中加上“isolcpus=参数
,可以实现CPU的隔离,使得在系统启动后普通进程默认都不会被调度到被隔离的CPU上执行。
(*注意上述方式的隔离仅针对用户空间隔离,内核空间是无法隔离的。)
例如,隔离cpu6和cpu7的内核启动命令行如下:
vi /etc/sysconfig/grub
GRUB_CMDLINE_LINUX="spectre_v2=retpoline rhgb quiet net.ifnames=0 biosdevname=0 intel_iommu=on isolcpus=6,7"
grub2-mkconfig -o /boot/grub2/grub.cfg
#LEGACY启动模式的文件是这个,/boot/grub2/grub.cfg
#UEFI启动模式的文件是这个,/boot/efi/EFI/centos/grub.cfg
接下来系统重启reboot后我们来验证下是否生效
cat /proc/cmdline
- vcpu亲和性的绑定
CPU的亲和性也就是cpu affinity机制,指的是进程要在指定的 CPU 上尽量长时间地运行而不被迁移到其他处理器, 通过处理器关联可以将虚拟处理器映射到一个物理处理器上 ,也就是说把一个程序绑定到一个物理CPU上。
在大部分文章中都使用taskset
来绑定指定的线程号
在指定的CPU编号上。但是这种方式存在问题,虚拟机是需要关机和迁移的需求的,每次重启后,线程的编号会变化,还需要一个单独的程序来进行重新绑定。
这里我们使用virsh 的亲和性命令来绑定VCPU和物理CPU的关系。
virsh vcpupint ${vm_name}
将虚拟机的vCPU绑定到特定的物理CPU上
virsh emulatorpin ${vm_name}
用于将虚拟机的emulator进程(即QEMU进程)绑定到特定的物理CPU上。
virsh vcpupin test 0 7
#将名为test的虚拟机vcpu 0 绑定在物理机CPU 7 上
#virsh vcpuinfo 来检查
[root@192-168-48-11 ~]# virsh vcpuinfo test
VCPU: 0
CPU: 7
State: running
CPU time: 35.2s
CPU Affinity: -------y
virsh emulatorpin test 7
#将虚拟机test qemu进程绑定物理CPU 7上。
实验:
在环境中,我隔离出6-7号物理cpu编号,分别绑定 test虚拟机的 0,1 cpu 上,
下面我们用htop
命令来进行验证
test运行在CPU 8和7上,(此时的显示的CPU 是从1开始,则对应6,7号cpu)
下一期我们将开始介绍存储和网络组件的虚拟化。