[云计算]HCIE-Cloud 云计算运营 - KVM虚拟化技术
目录参考:
https://www.cnblogs.com/qiaoyanlin/p/6888408.html深入浅出 kvm qemu libvirt的说明
KVM发展背景
KVM发展史
- KVM(Kernel-based Virtual Machine)
-
开源全虚拟化方案——KVM
- 支持体系结构:
- X86、IA64、PowerPC、S390
- 依赖x86硬件支持:Intel VT-X / AMD-V
- 内核模块,使得Linux内核成为Hypervisor
- 支持体系结构:
-
KVM历史
- 2006年10月——以色列公司qumranet发布KVM
- 2006年12月——KVM合入内核(Linux 2.6.2orc)
- 2007年2月——Linux2.6.20正式版发布
- 2008年9月——红帽收购KVM
- 2009年9月——RHEL5.4开始支持KVM(同时支持Xen)
- 2010年11月——RHEL6.0仅支持KVM
-
云平台对KVM支持
- OpenStack、Eucalyptus、AbiCloud等同时支持KVM和Xen
-
虚拟化本质
- 分区:
- 可在单一物理服务器上同时运行多个虚拟机。
- 隔离:
- 虚拟机之间相互隔离,单个虚拟机之间的故障不会影响其他虚拟机。
- 封装:
- 整个虚拟机保存在文件中,可通过移动和复制这些文件的形式来移动和复制虚拟机。
- 相对于硬件独立:
- 无需修改既可以在任何服务器上运行虚拟机。
KVM功能简介
Xen架构
组件 | 功能 |
---|---|
Xen Hypervisor | 虚拟化监视层 |
Domain U | 运行在非特权级别的用户虚拟机 |
Domain 0 | 运行在特权级别的用户虚拟机 1. 最先启动的虚拟机 2. 管理着其他的用户虚拟机 3. 实现IO虚拟化,控制IO资源(安装了设备驱动) |
KVM架构
组件 | 功能 |
---|---|
kvm.ko | 安装在Linux内核的模块,可实现CPU和内存虚拟化 |
qemu-kvm | 基于开源的qemu改进,可实现IO虚拟化 |
libvirt | 向下对接不同的Hypervisor,向上提供统一的接口,实现对不同虚拟化平台的纳管 |
virt-manager | 提供KVM的图形化管理界面 |
virt-viewer | 通过控制台的方式连接虚拟机 |
virsh | kvm管理的命令集 |
KVM/Qemu/Libvirt的关系
三者关系
-
在所谓的kvm技术中,应用到的其实有2个东西:Qemu+KVM
- KVM负责cpu虚拟化+内存虚拟化,实现了cpu和内存的虚拟化,但KVM不能模拟其他设备;
- Qemu是模拟IO设备(网卡,磁盘),KVM加上Qemu之后就能实现真正意义上服务器虚拟化。
- 因为用到了上面两个东西,所以一般都称之为Qemu-KVM。
-
Libvirt则是调用KVM虚拟化技术的接口用于管理的,用Libvirt管理方便,直接用Qemu-KVM的接口太繁琐。
KVM
- KVM是Linux内核的模块,它需要CPU的支持,采用硬件辅助虚拟化技术(Intel-VT/AMD-V),内存相关的如EPT和AMD的RVI技术,Guest OS的CPU指令不再经过Qemu转译,而是直接运行,大大提高了速度,KVM通过/dev/kvm暴露接口,用户态程序可以通过ioctl函数来访问这个接口。
Qemu
- Qemu是一个主机上的VMM,通过动态二进制转换来模拟CPU,并提供一系列的硬件模型,使得Guest OS认为自己和硬件直接打交道,其实是和Qemu模拟出的硬件在打交道,Qemu再将这些指令翻译给真正的硬件进行操作。
Qemu-KVM
- Qemu将KVM整合进来,通过ioctl调用/dev/kvm接口,将有关CPU指令的部分交由内核模块来做,KVM负责CPU和内存虚拟化,但是KVM无法模拟其他设备。Qemu模拟IO设备(网卡、磁盘等),KVM加上Qemu之后才能真正意义上实现服务器虚拟化,整套解决方案就叫做Qemu-KVM。
- Qemu模拟其他的硬件会影响这些设备的性能,因此就产生了pass through半虚拟化设备,直接将物理设备透传给虚拟机用,提高设备性能。
Libvirt
- Libvirt是用于管理虚拟化平台的开源的API,后台程序和管理工具。
- Libvirt是提供了一个方便的方式来管理虚拟机和其他虚拟化功能的软件的集合,如存储和网络接口管理。
- 这些软件包括了一个API库,一个守护进程(Libvirtd),和一个命令行实用程序(virsh)
- 可用于纳管KVM、Xen、VMware ESXi、Qemu等虚拟化技术。
KVM - CPU虚拟化
Native操作系统对CPU的认识与管理达成以下两点共识:
- CPU资源永远就绪。
- OS对CPU具有最高权限。
引入虚拟化之后出现的问题:
- 如何让多个VM之间共享CPU资源?
- 解决:VM使用vCPU,Hypervisor将vCPU调度到pCPU上运行,实现物理CPU资源的分时复用(时间片)。
- 如何模拟CPU指令(所有敏感指令)?
- 解决:硬件辅助虚拟化技术(root-nonroot间切换)
敏感指令:可以读写系统关键资源的指令,绝大多数的敏感指令是属于特权指令,也就是说存在极少数的敏感-非特权指令(CPU虚拟化漏洞)。
经典的虚拟化主要使用以下方式:
特权-解除:将Guest OS运行在非特权级,将VMM运行在高特权级(控制系统资源)
陷入-模拟:解除了Guest OS的特权后,Guest OS的大部分指令仍然可直接在硬件上运行,只有当执行到特权指令时,才会陷入VMM模拟执行。
硬件辅助虚拟化(Root与Non-Root之间切换):
- 以Intel-VT为例,在Ring0~Ring3的基础上,增加了VMX模式,其包含VMXroot和VMXnon-root模式,VMXroot模式是提供给VMM使用的,在该模式下可以调用VMX指令集,VMM用以创建和管理虚拟机。而VMXnon-root模式就是虚拟机运行的模式,这种模式不支持VMX指令集。
参考:https://www.cnblogs.com/Bozh/p/5757274.html
KVM CPU虚拟化三种运行模式:
-
用户态模式
-
内核态模式
-
客户模式
VMM完成vCPU和内存的初始化后,通过ioctl调用KVM的接口,完成虚拟机的创建,并创建一个线程来运行VM,由于VM在前期初始化的时候会设置各种寄存器来帮助KVM查找到需要加载的指令的入口(main函数)。所以线程在调用了KVM接口后,物理CPU的控制权就交给了VM。VM运行在VMX non-root模式(Intel-VT或AMD-V提供的一种特殊的CPU执行模式)。然后当VM执行了特殊指令的时候,将执行权切换到VMM。VMM获取VM返回,并作处理。如果是IO请求,VMM可以直接读取VM并将IO操作模拟出来,在VM看来,IO操作的指令是被CPU执行的。
虚拟化层的开销:
- VMM处理开销
- Root与Non-Root切换开销
KVM - 内存虚拟化
Native操作系统对内存的认识与管理达成以下两点共识:
- 内存都是从物理地址0开始的
- 内存都是连续的
引入虚拟化后出现的问题:
- 从物理地址0开始的:物理地址0只有一个,无法同时满足所有客户机从0开始的需求。
- 地址连续:虽然可以分配连续的物理地址,但是内存使用效率不高,缺乏灵活性。
VMM需要处理以下两个问题:
- 维护客户机物理地址到宿主机物理地址之间的映射关系。
- 截获虚拟机对客户机物理地址的访问,并根据映射关系转换为宿主机物理地址。
相关技术:
- 内存管理单元 MMU(Memory Management Unit)
- 页表转换缓冲 TLB(Translation Lookaside Buffer)
MMU虚拟化
相关概念:
GVA:Guest Virtual Address,通过MMU技术所抽象的客户虚拟地址。
GPA:Guest Physical Address,分配给虚拟机的物理地址。
HVA:Host Virtual Address,通过MMU技术所抽象的主机虚拟地址,可以是内存,也可以是硬盘。
HPA:Host Physical Address:主机物理地址。
- 虚拟机内存分配:
- Guest的物理内存在Qemu-KVM进程虚拟地址空间中
- Guest的物理内存页由Host按需分配
- MMU虚拟化(两种):
- 软件:Shadow Page Table(影子页表)
- 硬件:EPT(Intel)
影子页表
- Guest Page Table设为写保护,以保持Guest Pages Table与影子页表之间的一致性;
- 如果Guest PTE的Dirty位未设置,则删除影子PTE的可写位。
EPT/NPT
- 减少了VM exits次数
- 性能比影子页表好
- 将GPA转换为HPA
KVM - I/O虚拟化
I/O虚拟化需要解决两个问题:
-
设备发现:
- 需要控制各虚拟机能够访问的设备
-
访问截获:
- 通过I/O端口或者MMIO对设备的访问
- 设备通过DMA与内存进行数据交换
全模拟
- 用软件完全模拟一个特定的设备
- 保持一样的软件接口,如:PIO、MMIO、DMA、中断等
- 可以模拟出跟系统中的物理设备不一样的虚拟设备
- 每次I/O操作需要多次上下文切换
- VM < --- > Hypervisor
- Qemu < --- > Hypervisor
- 软件模拟的设备对不影响虚拟机中的软件栈
- 原生驱动
virtio
- 虚拟出特殊的设备
- 特殊的设备,包括VM中的Front-end驱动和主机上的Back-end驱动
- Front-end和Back-end驱动之间的高效通信
- 减少VM和主机的数据传输开销
- 高效的标准化PV Driver
- 兼容PCI:设备发现,配置
- 支持多种虚拟化平台
- 设备种类:
- Virtio-blk, virtio-net, virtio-balloon, virtio-console、virtio-scsi、virtio-9p
vhost
- vhost-block、vhost-net、vhost-scsi
- 从VM来的io请求会被直接map成host上的bio,可以有效减少虚拟机中的I/O的执行,性能更好,前端完全兼容vhost
vhost-net
- virtio网络后端移到内核中
- 更高效率
KVM特性功能
QoS
-
Cgroups是Control Groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组(Process Groups)所使用的物理资源的机制。
-
Cgroups(Control Groups)
-
Linux内核对进程进行资源控制
- 设置资源配额,建立分组
- 将进程加入资源配额分组
-
价值:虚拟机QoS资源配额分组
-
资源控制类型:
- CPU资源(用于控制Cgroup中所有进程可以使用的CPU时间片)
- 内存资源(可以设定Cgroup中任务使用的内存限制)
- 磁盘IO带宽(基于权重和速度控制磁盘IO)
- 网络带宽(控制带宽速度)
-
THP
- THP(Transparent Hugepage)
- 页大小2MB
- 提高tlb命中率(tlb每一项访问范围4k→2M)
- 减少访问时间(tlb不命中时 访存次数4次→3次)
- 申请大内存区,效率更高
- 访问大内存区,减少页表项大小(提高cpu cache效率)
- 透明
- 对使用者完全透明,不依赖任何库
- 兼容ksm,swap
- 兼容EPT/NPT,兼容影子页表
- 页大小2MB
KSM
- KSM(Kernel Samepages Merging)
- 扫描内存页面,相同内容页面只读共享
- 支持普通进程(非虚拟机)
- 对于2M大内存页
- Windows零页内存
- 价值:节省内存,提高虚拟机密度
- Tradeoff:CPU vs Memory space
- 扫描内存消耗CPU
- 与不启用KSM相比:访存稍慢
- 扫描内存页面,相同内容页面只读共享
Vhost over SR-IOV
本地存储热迁移
- 本地存储与vm热迁移
-
虚拟化平台大多支持VM热迁移
- 但要求共享存储支持
-
SAN等共享存储价格昂贵
-
许多中小企业没有共享存储环境
-
- Block migration
- 2009年11月 kvm-qemu 0.12 由IBM加入特性
- 虚拟机镜像从源主机迁移到目的主机
- 迁移时间较长
- 需要同时迁移内存状态和磁盘镜像
- 存储空间一般比内存大
- 价值:扩展了虚拟机热迁移的范围
- 共享存储不再是必要条件