LabHub
学习 学习路径 课程

虚拟化与 QEMU/KVM

KVM 为什么接近原生

在 LabHub 中继续学习

一句话总结

虚拟化性能由**访客退出内核模式的次数(VM Exit)**决定。硬件支持和virtio都是减少次数的技术。

概念图: 访客退出内核模式的次数(VM Exit) · 非特权模式下运行也不会引起例外,而是安静地返回其他值 · 全虚拟化(Full virtualization) · 半虚拟化(Paravirtualization)

为什么需要这个?

x86本来就是一个不适合虚拟化的体系结构。因为其中一些特权命令即使在非特权模式下运行也不会引起例外,而是安静地返回其他值(所谓的“无法虚拟化的命令”)。所以早期的虚拟化分为两大类。

随着英特尔VT-x/AMD-V的出现,局面发生了变化。增加了CPU上访客专用运行模式

怎么行动

硬件支持虚拟化

VT-x 在CPU上创建两个新模式。VMX root(虚拟机管理程序)和VMX non-root(客人)。客人从自己的环0上保持原样运行,但如果虚拟机管理程序确定的特定事件发生,就会自动进入root模式。这就是VM Exit

内存也由硬件提供帮助。EPT(Intel) / NPT(AMD)将访客物理地址→主机物理地址转换处理为硬件页表。没有这个时期,虚拟机管理程序必须将影子页表作为软件维护,这占用了很大一部分性能。

KVM的位置

KVM不是单独的虚拟机管理程序,而是Linux内核模块。加载的瞬间,Linux内核本身就成为虚拟机管理程序。所以KVM处于类型1(裸机)和类型2(主机型)的边缘——虽然在主机OS上运行,但那个主机OS就是虚拟机管理程序。

执行流程是这样的。

QEMU (유저 공간)
  ├─ ioctl(KVM_RUN)
  ↓
KVM 모듈 (커널)
  ├─ VMLAUNCH / VMRESUME
  ↓
게스트 (VMX non-root)
  ├─ VM Exit 발생
  ↓
KVM 이 처리 가능하면 여기서 끝 (빠름)
KVM 이 못 하면 QEMU 로 반환 (느림)

KVM在内核中直接处理:大多数MSR访问、简单的I/O端口、EPT违反、外部中断。 甚至可以升级到QEMU:复杂的设备I/O、MMIO、部分CPUID。

所以性能调优的方向就确定了。减少到QEMU的Exit。

QEMU的作用

QEMU是设备模型。将客人看到的虚拟NIC、磁盘控制器、计时器制成软件。如果没有KVM,只使用QEMU的话,连CPU命令都全部用软件翻译,那个引擎是TCG(Tiny Code Generator)

TCG将客机命令切割成基本块单位,转换为TCG IR,然后再翻译为主机命令并缓存(Translation Block)。多亏了缓存和链路,虽然比纯解释器快得多,但与KVM相比仍然慢10~100倍。

项目 原生 QEMU+KVM QEMU(TCG)
CPU计算 100% 约98% 约25%
磁盘I/O (virtio) 100% 约90% 约30%
网络(vhost-net) 100% 约95% 约25%

**在这个实习环境中/dev/kvm没有。**因为没有把那个装置放进容器里。所以QEMU是-accel tcg运行慢。启动慢不是因为环境问题,而是设置错误。

virtio — 虚拟化回归

模拟的e1000 NIC每次客人触摸注册表都会引发VM Exit。virtio让客人和主机通过共享内存缓冲区进行沟通,极大地减少了Exit。客人需要virtio驱动程序,但最近Linux是默认安装的。

装置 对比性能
virtio-net 比e1000多10倍以上
virtio-blk 比IDE模拟快2~5倍
virtio-scsi 适合多盘驱动器连接
vhost-net 在内核中处理环缓冲区 → 进一步增强

**如果因为性能问题收到举报,首先要问的是“是否在使用virtio”。**意外地有很多VM在错误地选择模板后转到IDE。

在现场相遇的样子

**叠加虚拟化的陷阱。**要在云VM中再次使用KVM,必须打开叠加虚拟化。如果关闭了,就会安静地恢复到TCG,然后问“为什么这么慢”。/dev/kvm存在与否qemu-system-x86_64 -accel help通过输出确认。

**如果CPU模型没有用host-passthrough,性能就不会发挥出来。**基本CPU模型为了兼容性隐藏了最新的命令扩展。如果是使用AVX的工作负载的话,会有很大的差异。相反,会破坏实时迁移兼容性,所以这是一个权衡。

在下次确认中看到的东西

在接下来的测验中,KVM加速、TCG复位、virtio设备、CPU模型的性能和移植性 先区分条件。确认了那个判断后,从下一个模块开始,qcow2备份文件和 练习快照、QEMU序列控制台、显示器插孔。