3、KVM架构解析:内核模块、用户态组件与协作流程
KVM 这东西,说白了就是 Linux 内核里的一个“虚拟化开关”。我刚开始接触那会儿,总觉得它很神秘,后来拆开一看,其实没那么复杂。今天咱们就把 KVM 的里里外外捋一遍。
3.1 KVM 内核模块:虚拟化的“发动机”
KVM 本身不是一个完整的 Hypervisor,它只是 Linux 内核的一个模块。它的核心工作就三件:CPU 虚拟化、内存虚拟化、中断虚拟化。
我习惯把 KVM 模块比作“硬件加速器”。没有它,QEMU 纯软件模拟虚拟机,慢得让人抓狂。有了它,虚拟机可以直接在物理 CPU 上跑,性能接近原生。
KVM 模块加载命令:
# 检查 CPU 是否支持硬件虚拟化
egrep -c '(vmx|svm)' /proc/cpuinfo
# 加载 KVM 模块
modprobe kvm
modprobe kvm_intel # Intel 处理器
# modprobe kvm_amd # AMD 处理器
# 验证模块是否加载
lsmod | grep kvm
加载成功后,/dev/kvm 这个字符设备就会出现。它就是用户态和内核态通信的“门”。
| KVM 模块 | 职责 | 关键接口 |
|---|---|---|
| kvm.ko | 核心框架,管理 VM 生命周期 | ioctl 调用、内存映射 |
| kvm_intel.ko | Intel VT-x 硬件加速 | VMX 根/非根模式切换 |
| kvm_amd.ko | AMD SVM 硬件加速 | VMRUN/VMLOAD 指令 |
我的经验: 曾经在一台老服务器上死活加载不了 kvm_intel,折腾半天发现 BIOS 里 VT-x 没开。嗯,这坑我踩过,你们别重蹈覆辙。
3.2 QEMU 用户态组件:虚拟设备的“模拟器”
KVM 只管 CPU 和内存,那硬盘、网卡、显卡谁来管?答案是 QEMU。QEMU 跑在用户态,负责模拟各种 I/O 设备。
你想想看,虚拟机里要读写硬盘,数据怎么走?流程是这样的:
- 虚拟机里的驱动发起 I/O 请求
- KVM 捕获这个请求,退出到 QEMU
- QEMU 模拟设备行为,操作宿主机上的真实文件或设备
- 结果返回给虚拟机
这个过程叫“陷阱-模拟”。每次 I/O 都要上下文切换,性能损耗不小。所以后来才有了 virtio。
QEMU 启动虚拟机示例:
qemu-system-x86_64 \
-enable-kvm \
-m 4G \
-smp 4 \
-drive file=/var/lib/libvirt/images/ubuntu.qcow2,if=virtio \
-netdev user,id=net0 \
-device virtio-net,netdev=net0
注意 -enable-kvm 这个参数,它告诉 QEMU:“别自己模拟 CPU 了,用 KVM 的硬件加速!”
3.3 KVM 与 QEMU 协作流程:一张图说清楚
下面这张 SVG 图,我画的是 KVM 和 QEMU 怎么配合工作的。你看一眼就明白了。
流程其实很简单:
- QEMU 通过
/dev/kvm发 ioctl 告诉 KVM:“我要创建一个虚拟机” - KVM 在内核态分配 VMCS(虚拟机控制结构),配置 CPU 进入 VMX 非根模式
- 虚拟机 直接在物理 CPU 上跑,直到遇到敏感指令或中断,触发 VM-Exit
- KVM 处理 VM-Exit,如果是 I/O 请求,就交给 QEMU 模拟
注意: VM-Exit 是性能杀手。每次退出都要保存上下文、切换到根模式、再切回来。我曾经优化过一个数据库虚拟机,发现 VM-Exit 频率高达每秒 10 万次,后来通过调整中断合并和 virtio 参数,降到了 2 万次,性能提升明显。
3.4 virtio 半虚拟化驱动:告别“慢速模拟”
前面说了,纯模拟 I/O 设备性能差。virtio 就是来解决这个问题的。
virtio 的思路很简单:让虚拟机知道自己是个虚拟机。Guest 里装一个特殊的 virtio 驱动,它不模拟真实硬件,而是直接和 QEMU 通过共享内存通信。
| 对比项 | 全虚拟化(模拟) | 半虚拟化(virtio) |
|---|---|---|
| 驱动类型 | 模拟真实硬件(如 e1000 网卡) | 专用 virtio 驱动 |
| 通信方式 | 陷阱-模拟,每次 I/O 都 VM-Exit | 共享内存环形队列,减少 VM-Exit |
| 性能 | 较差,CPU 开销大 | 接近原生,吞吐量高 |
| 兼容性 | 无需额外驱动,开箱即用 | 需要 Guest 安装 virtio 驱动 |
我个人的习惯是:所有生产环境的虚拟机,一律用 virtio。除非遇到特别老的系统(比如 Windows 2003),才考虑用模拟设备。
virtio 设备类型:
virtio-blk:块设备(硬盘)virtio-net:网络设备virtio-scsi:SCSI 控制器virtio-balloon:内存气球(动态内存调整)virtio-console:控制台
virtio 的核心是 vring(虚拟环形队列)。Guest 和 Host 共享一段内存,Guest 把 I/O 请求放到队列里,QEMU 从队列里取出来处理,处理完再放回去。整个过程不需要频繁的 VM-Exit,效率高得多。
避坑指南: 我曾经在 CentOS 6 上装 virtio 驱动,结果系统启动时直接 kernel panic。后来发现是内核版本太老,不支持 virtio 1.0 规范。解决办法:要么升级内核,要么在 QEMU 命令行里指定 disable-modern=true 回退到 virtio 0.9。
总结一下这一节的核心:
- KVM 是内核模块,提供 CPU/内存/中断的硬件加速
- QEMU 是用户态进程,负责设备模拟和虚拟机管理
- 两者通过
/dev/kvm和 ioctl 通信 - virtio 是半虚拟化驱动,大幅提升 I/O 性能