1. KVM不是软件,是Linux内核的"虚拟机引擎"
最近后台私信里关于KVM虚拟化的提问突然变多了,有人问怎么"用KVM给服务器做系统",有人报错说WSL2无法启动、提示没启用虚拟化,还有人折腾VMware Workstation时看到"模块hv启动失败"。这些热搜词背后反映的是同一个问题:大家把KVM当成一个能双击安装的应用,但真实的KVM其实藏在Linux内核里,它更像是一台虚拟机运行所依赖的引擎,而不是一个独立软件。
1.1 KVM、QEMU、libvirt到底怎么分工
入门KVM最容易被绕晕的就是这组名词。KVM(Kernel-based Virtual Machine)从Linux 2.6.20开始就合入了内核主线,它本身不是一个应用程序,而是内核模块。加载之后,内核里就多了一个/dev/kvm设备。你可以执行ls -l /dev/kvm看看,只要宿主机CPU支持虚拟化并且模块正常加载,这个设备就一定存在。
QEMU负责的是设备模拟,比如给虚拟机提供一块虚拟网卡、一块虚拟磁盘、一个显示输出。KVM负责的是CPU虚拟化,让虚拟机里的指令能直接跑在物理CPU上。两者合作才能跑起一台完整虚拟机。
libvirt则是管理框架,它把QEMU/KVM的复杂参数封装成标准的XML定义文件,并提供virsh、virt-manager这类管理工具。你可以这样理解:KVM是发动机,QEMU是车身和电气系统,libvirt是方向盘和仪表盘。光有发动机车不走,光有车身也跑不了,方向盘则让你能正常驾驶它。
这三个角色搞清楚之后,再去看热搜里那些命令,比如ubuntu 2204 libvirt kvm virt-manager,你就明白这不是四个并列的东西,而是一条完整的技术栈:Ubuntu提供操作系统,内核里有KVM,QEMU做模拟,libvirt和virt-manager做管理。
1.2 为什么没有VT-x/AMD-V就用不了KVM
这是很多人在BIOS里翻来翻去找"虚拟化"选项的原因。现代CPU的虚拟化扩展,Intel叫VT-x,AMD叫AMD-V,它们的作用是给KVM提供硬件加速。没有这个扩展,KVM模块可以加载,但虚拟机只能退回QEMU的纯软件模拟模式(TCG),运行速度慢到几乎没法用。
我做一次简单类比:一台虚拟机里的CPU指令,普通指令可以在物理CPU上直接执行,但特权指令必须经过虚拟机监视器(VMM)转发。没有硬件虚拟化扩展,VMM只能靠二进制翻译,也就是把虚拟机里的敏感指令翻译成安全指令再执行;有了VT-x/AMD-V,CPU本身提供了一套VMX non-root模式,虚拟机的大部分指令直接跑,只有少数需要截获的指令会触发VM exit,交给KVM处理。这中间的差别就是"软件模拟"和"硬件加速"的差别,性能差一个数量级。
所以你在BIOS里看到Intel Virtualization Technology或SVM Mode,别犹豫,生产环境必须打开。很多人在装KVM之前忽略了这一步,装完发现虚拟机能创建但启动极慢或者直接报错,回头检查才发现BIOS里的开关关着。
1.3 服务器虚拟化主战场为什么是KVM
热搜词里有"服务器虚拟化技术"和"linux内核虚拟化",这两个词其实都指向同一个趋势:在x86服务器虚拟化市场,KVM已经成为事实上的Linux标准虚拟化底座。
对比VMware ESXi和Microsoft Hyper-V,KVM的最大优势在于它就在Linux内核里。虚拟机调度直接复用内核的调度器,内存管理直接复用内核的内存管理子系统,这意味着它的性能损耗更低,也能直接利用Linux生态里所有成熟工具。加上OpenStack、Proxmox VE、oVirt这些开源平台全部围绕KVM/libvirt构建,生产环境里有大量现成方案可以直接抄。
超融合、桌面云、边缘计算这些场景里,很多商用平台的后端就是KVM定制而来。这也是为什么很多企业招聘JD上写"熟悉KVM虚拟化"——你学会了KVM,等于掌握了半个私有云的基础。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Ubuntu 22.04上从零搭KVM:装包、开桥、创建虚拟机
下面进入实操。我以Ubuntu 22.04 LTS为例,因为这套组合是目前最省心的KVM学习环境,也是热搜词里被问得最多的ubuntu 2204 libvirt kvm virt-manager组合。
2.1 先检查CPU和BIOS,这一步能省掉后续一半麻烦
动手安装前,先确认硬件虚拟化到底开没开。在Linux终端里执行:
bash复制egrep -c '(vmx|svm)' /proc/cpuinfo
如果输出大于0,说明CPU的虚拟化扩展可用;如果输出是0,那大概率是BIOS里没开。检查一下自己的主板型号,在开机时按Del或F2进BIOS,Intel平台找"Intel Virtualization Technology"(VT-x),AMD平台找"SVM Mode"。
MSI的B760M这类新板子,一般在Settings→Advanced→CPU Configuration里能找到开关;微星B550(AMD平台)则在OC或Advanced菜单下叫SVM Mode。不同主板命名有差异,但关键词基本都是Virtualization、VT-x、SVM,开了以后保存重启再跑一次上面的命令,看到数字就OK。
如果你再想确认KVM模块本身是否就绪,执行:
bash复制sudo apt install -y cpu-checker
sudo kvm-ok
输出KVM acceleration can be used就表示万事俱备。
2.2 安装libvirt全家桶并配置用户权限
Ubuntu上安装KVM组件非常直接,一条命令搞定:
bash复制sudo apt update
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager ovmf
简单解释一下这几个包的作用:qemu-kvm是QEMU的KVM加速版本,libvirt-daemon-system负责提供libvirtd守护进程,libvirt-clients提供virsh等命令行工具,virt-manager是图形化管理界面,ovmf用于支持UEFI引导虚拟机。有的人会漏装bridge-utils,后面配置桥接网络时就发现没有brctl命令,所以一步到位最好。
装完之后,libvirtd通常会自动启动,执行:
bash复制sudo systemctl is-active libvirtd
看到active就说明服务正常。接下来把当前用户加入kvm和libvirt组,这样你日常操作virsh时不用加sudo:
bash复制sudo usermod -aG kvm,libvirt $USER
注销重新登录一次,用id命令确认组已经生效。
2.3 网络方案:NAT够用,生产环境得上桥接
安装完成后默认会有一个虚拟网桥virbr0,采用的是NAT模式。虚拟机通过它可以访问外网,但外部无法主动访问虚拟机,适合本地测试。如果你只是学习,用默认的NAT网络就够了。
但你要是给服务器做系统,或者虚拟机要提供服务给外部访问,那必须换成桥接网络。桥接的意思是虚拟机的网卡直接挂到物理网卡所在的网段,虚拟机就像局域网里一台独立主机。
我习惯用nmcli配置桥接,以Ubuntu 22.04、物理网卡名为enp1s0为例:
bash复制sudo nmcli connection add type bridge ifname br0 con-name br0
sudo nmcli connection modify br0 ipv4.method auto
sudo nmcli connection modify br0 ipv4.addresses 192.168.1.50/24 ipv4.gateway 192.168.1.1 ipv4.dns 223.5.5.5
sudo nmcli connection add type ethernet slave-type bridge con-name bridge-port-1 ifname enp1s0 master br0
sudo nmcli connection up br0
注意桥接时要保证物理网卡不再单独获取IP,否则会出现IP冲突。实际配置中,我会先断开原网卡连接再启用bridge端口,避免网络瞬间中断。虚拟机创建时网络类型选择"Bridge br0",就能直接拿到局域网IP。
2.4 virt-install创建虚拟机,以及"给服务器做系统"的正确姿势
创建虚拟机最简单的方式是直接在virt-manager图形界面里操作,点"新建虚拟机",选择ISO镜像,设置内存和CPU,向导式完成。但如果你在纯命令行环境,我更推荐用virt-install,可重放、可改,批量部署时特别方便。
bash复制sudo virt-install \
--name ubuntu2204 \
--ram 4096 \
--vcpus 4 \
--disk path=/var/lib/libvirt/images/ubuntu2204.qcow2,size=50,format=qcow2 \
--os-variant ubuntu22.04 \
--network network=default \
--graphics vnc \
--cdrom /path/to/ubuntu-22.04-server-amd64.iso
参数含义很直观:--name是虚拟机名称,--ram是内存MB数,--vcpus是虚拟CPU数量,--disk指定磁盘路径和大小,--os-variant告诉libvirt优化配置,--graphics vnc表示通过VNC远程安装系统。执行完命令后用virt-manager或VNC客户端连上去就能开始装系统。
热搜词里"通过kvm给服务器做系统"还有另一层含义:用KVM作为基础设施,给一批物理服务器批量安装操作系统。这通常走PXE网络引导,配合DHCP、TFTP、HTTP和kickstart无人值守脚本实现。你可以在KVM里先搭一个PXE服务器,也可以直接用virt-install --location指向一个带kickstart的HTTP仓库,让虚拟机完成自动安装。原理和物理机PXE一样,区别只是把虚拟机当作试验田,把kickstart脚本跑通后再套用到物理机上。
3. 两个绕不开的高频场景:ARM平台和嵌套虚拟化
3.1 ARM平台(麒麟V10、飞腾/鲲鹏)上的KVM
热搜词里出现了"麒麟v10arm安装kvm",这说明国产化替代环境下,ARM服务器上跑KVM已经是越来越多运维人员要面对的需求。
ARMv8架构从设计之初就带了虚拟化扩展,也就是EL2异常级别,相当于x86的VT-x/AMD-V。Linux内核的KVM模块对ARM64的支持早已进入主线,所以只要CPU是飞腾、鲲鹏这种ARMv8芯片,麒麟V10系统上装KVM是完全可行的。
在银河麒麟/中标麒麟V10上安装KVM,命令与Ubuntu类似,只是包管理器变成了yum或dnf:
bash复制sudo yum install -y qemu-kvm libvirt virt-install virt-manager
sudo systemctl enable --now libvirtd
需要注意几点:ARM平台上的虚拟机镜像必须是aarch64架构的系统,别拿x86的ISO去引导;UEFI引导需要安装edk2-ovmf的aarch64版本,系统包里一般叫edk2-aarch64或AAVMF;另外ARM版QEMU的命令是qemu-system-aarch64,但通过libvirt操作时不需要关心底层命令,管理方式和x86环境完全一致。
我在使用飞腾S2500服务器的过程中,遇到最多的反而不是KVM本身的问题,而是操作系统镜像兼容问题。有些x86时代的老安装脚本、旧版kickstart配置里写死了BIOS引导或x86架构判断,迁移到ARM平台时都会出错。排查思路就是先确认/proc/cpuinfo是否包含asimd和fp特性,再确认镜像的架构,最后才是libvirt的配置。
3.2 嵌套虚拟化实战:KVM里跑KVM、VMware里跑KVM
嵌套虚拟化(Nested Virtualization)的意思是虚拟机里再跑虚拟机。KVM官方是支持嵌套的,只是默认开关关闭,需要手动打开。
在Intel平台宿主机上,首先检查当前nested参数:
bash复制cat /sys/module/kvm_intel/parameters/nested
输出N说明没开,需要改内核模块参数。编辑/etc/modprobe.d/kvm_intel.conf,写入:
bash复制options kvm_intel nested=1
重启宿主机后,再执行cat看到Y就成功了。AMD平台的模块名是kvm_amd,操作一样。
光打开宿主机模块参数还不够。既然要在虚拟机里跑KVM,虚拟机本身必须能看到VMX/AMD-V指令,并暴露给虚拟机内部的KVM模块。这就需要在虚拟机的CPU配置里使用host-passthrough模式,把宿主机的CPU特性直接透传进去:
bash复制sudo virsh edit vm-name
在<cpu>标签里修改为:
xml复制<cpu mode='host-passthrough' check='partial'/>
改完重启虚拟机。进到虚拟机里执行egrep -c '(vmx|svm)' /proc/cpuinfo,如果输出大于0,就说明嵌套虚拟化已经生效。
在VMware Workstation里跑KVM也类似。VMware本身支持嵌套虚拟化,但需要在虚拟机设置里勾选"虚拟化 Intel VT-x/EPT 或 AMD-V/RVI",或者在.vmx文件里加一行vhv.enable = "TRUE"。热搜词里那个"vmware workstation 在此主机上不支持嵌套虚拟化,模块hv启动失败",多半是宿主机Windows上Hyper-V占用了VT-x,或者虚拟机配置里没有勾选这个选项。解决办法是先确认Windows的hypervisor是否被Hyper-V/VBS占用,把host的虚拟化释放出来,再勾选VMware的嵌套选项。
3.3 什么时候需要嵌套虚拟化,什么时候千万别开
嵌套虚拟化的典型用途是测试:比如你要在上面跑一套OpenStack,想先在一台虚拟机里搭建整个资源池;或者你在做虚拟化平台研发,需要反复创建和销毁虚拟机做实验。在这些场景下,嵌套虚拟化是省机器、省电的魔法。
但我也建议:生产环境非必要不要开嵌套。每一层虚拟化都会带来性能损耗,嵌套一层KVM的性能损耗通常比原生KVM高出10%到20%,尤其是在IO密集场景下更明显。虚拟机里的时间同步、CPU型号识别、内存大页这些参数在嵌套环境都会变得复杂。如果你只是想在虚拟机里跑个Docker,完全不需要嵌套虚拟化,Docker用的是容器技术,和虚拟化是两套东西。
4. "虚拟化打不开"排查链路:从BIOS到Hyper-V再到VBS
热搜词里有一类问题出现频率特别高:WSL2无法启动、提示"此计算机上未启用虚拟化"、"此平台不支持虚拟化的 Intel VT-x/EPT"、微星B550要不要开虚拟化、怎么判断谁在占用虚拟化。这些问题的本质都指向同一条排查链路。
4.1 第一层排查:BIOS里的VT-x/AMD-V和EPT
最基础的检查永远是BIOS。WSL2报错"此计算机上未启用虚拟化"时,90%的情况是BIOS里根本没开VT-x。很多人刚买的新电脑,主板出厂默认关闭虚拟化开关,Windows系统里装了一堆软件,wsl命令执行后却提示无法启动,就是因为这个。
不同主板开启路径不同,但关键词一致:Intel平台找"Intel Virtualization Technology",有的主板叫"VT-x";AMD平台找"SVM Mode"。华硕主板一般在Advanced→CPU Configuration里,微星主板一般在Settings→Advanced→CPU Configuration或OC菜单里,技嘉一般在Advanced Settings→CPU Configuration里。开启后F10保存重启。
如果你用的CPU比较老,启动VMware或KVM时看到"此平台不支持虚拟化的 Intel VT-x/EPT",就要注意EPT。EPT是Intel的二级地址转换技术,它让虚拟机的内存地址翻译直接由硬件完成,没有EPT的话,虚拟机内存访问会频繁触发VM exit交给软件处理,性能上会非常难看。现在的CPU基本都支持EPT,如果报错说EPT不可用,多数时候不是CPU不支持,而是BIOS里的VT-x没开,或者Windows的Hyper-V/VBS占用了虚拟化层。
4.2 第二层排查:Windows的Hyper-V、VBS、内核隔离
BIOS确认开启后,问题还没解决,那就要看Windows自身的Hyper-V和基于虚拟化的安全(VBS)设置。Win11的"内核隔离"和"内存完整性"功能底层依赖VBS,VBS又依赖Hyper-V。一旦启用,Windows本身就成了一个hypervisor,它会占用CPU的虚拟化扩展。这时候你再跑VMware Workstation、VirtualBox或WSL2(WSL2本身也在Hyper-V之上),行为就会变得非常奇怪。
WSL2无法启动时,先看看Hyper-V相关的Windows功能有没有打开。在"启用或关闭Windows功能"里,确认"Hyper-V"(如果有)和"虚拟机平台"(Virtual Machine Platform)都勾上了。对于WSL2来说,核心是"虚拟机平台"而不是完整的Hyper-V管理工具。
然后看hypervisor是否在运行。管理员PowerShell执行:
powershell复制bcdedit /enum | findstr hypervisorlaunchtype
bcdedit /set hypervisorlaunchtype auto
如果当前是off,WSL2就起不来;改成auto并重启后,WSL2通常就能恢复。反过来,如果你要在Windows上跑VMware/KVM并开嵌套虚拟化,hypervisorlaunchtype必须设为off,否则VT-x被hypervisor占用,VMware会报"模块hv启动失败"。
4.3 用工具定位到底谁占用了虚拟化
"怎么看谁在占用虚拟化"这个热搜词很典型。很多人已经装好了KVM,但创建虚拟机时报错,不知道问题出在哪一层。
Windows下的判断,最快的是运行msinfo32,在"系统摘要"里找到"基于虚拟化的安全性"这一项,如果显示"正在运行",说明VBS已经启动并占用了虚拟化。再用systeminfo查看"Hyper-V 要求"一栏,如果看到"检测到虚拟机监控程序。将不显示 Hyper-V 所需的功能",说明Windows的hypervisor已经运行。
Windows上更底层的判断用Sysinternals的Coreinfo工具:
powershell复制coreinfo.exe -v
输出里如果看到Hypervisor present这个标志,那就是有hypervisor占着。VMX一列如果显示*,说明VT-x当前可用;如果显示-,说明虚拟化被占用或者没开。
Linux下判断更简单:
bash复制lsmod | grep kvm
dmesg | grep -i kvm
如果kvm_intel或kvm_amd模块已加载,说明KVM正在用。如果模块没加载,但/proc/cpuinfo里有vmx/svm,那可能是模块加载失败,看dmesg里有没有VT-x被BIOS锁住或hypervisor冲突的信息。
4.4 一个反直觉的坑:关闭VBS后Windows Hello PIN会失效
Win11用户为了跑VMware或去掉卡顿,会按照网上的教程关闭"内核隔离"和VBS,注册表里把DeviceGuard\EnableVirtualizationBasedSecurity改成0。这个操作本身确实是解决虚拟化冲突的有效手段,但很多人关完发现Windows Hello的PIN不能用了,系统提示"该选项当前不可用"。
原因在于Windows Hello PIN的验证链路依赖TPM芯片和基于虚拟化的隔离容器(VBS的Credential Guard),这些保护机制被关闭后,PIN的安全容器就不可用了,系统自然不允许你用PIN登录。
遇到这种情况,不用慌。如果你确实需要关闭VBS来跑虚拟机,可以先用Microsoft账户或密码登录,然后进入"设置→账户→登录选项→Windows Hello PIN",重新设置一次PIN。如果你不打算恢复VBS但想保留PIN,就重设一次。如果你觉得PIN比VBS更重要,那就把注册表改回去、恢复内核隔离,重启后再重新设置PIN。
我的建议是:做虚拟化排障时,先想清楚关闭VBS到底值不值。如果你只是跑个KVM嵌套实验,临时关闭没问题,但日常使用建议把内核隔离打开,毕竟Win11的安全模型已经默认依赖VBS了。
5. 生产环境里的KVM:商用平台、日常运维和我踩过的坑
5.1 华三CAS、FusionCompute这些商用平台和KVM是什么关系
热搜词里出现了"华三虚拟化平台安装配置手册"、"FusionComputer及dcs虚拟化套件部署安装"、"天逸终端虚拟化软件"这些企业级产品。不少人一看这些名字觉得陌生,其实它们和KVM的关系非常近。
华三CAS(Cloud Automation System)底层走的就是KVM/QEMU路线,虚拟机定义、快照、模板这些能力都是围绕KVM和libvirt构建的。华为FusionCompute在演进过程中,底层架构在不同版本里用过Xen也用过KVM,但管理员接触到的虚拟机生命周期操作、磁盘格式、资源池管理逻辑,和KVM那套思维高度一致。天逸这类终端虚拟化软件,协议层可能做得很花哨,但后端虚拟机引擎大多也跑在Linux内核虚拟化之上。
这意味着什么呢?你花时间把KVM的原理和命令搞熟,再去上手这些商用平台,看到的都是熟悉的概念:虚拟机CPU、内存、磁盘、网络配置,快照和模板,热迁移和HA。底层细节被封装了,但排查思路完全通用。反过来说,如果你先学了CAS或FusionCompute再回头学KVM,你也会发现libvirt的XML里写的东西你早就见过。
遇到这类商用平台的部署安装问题,优先看它的版本对应关系。很多CSP平台对底层内核版本有硬要求,升级内核或qemu版本时需要注意兼容性,我在实践里吃过亏:平台文档写着支持KVM 4.2,结果某次yum update把qemu升到新版本,虚拟机直接启动失败。平台运维和裸KVM运维的区别就在这里——裸KVM你随便折腾,平台环境里动底层包要克制。
5.2 运维KVM必须会的virsh命令和监控思路
日常运维KVM,virt-manager图形界面固然方便,但服务器上往往没有桌面环境,所以virsh才是真正高频使用的工具。我整理几个最常用的:
bash复制virsh list --all # 查看所有虚拟机及状态
virsh start vm-name # 启动虚拟机
virsh shutdown vm-name # 优雅关机(需虚拟机装了ACPI驱动)
virsh reboot vm-name # 重启
virsh destroy vm-name # 强制断电,慎用
virsh edit vm-name # 编辑虚拟机的XML配置
virsh vcpuinfo vm-name # 查看vCPU绑定情况
virsh blockstats vm-name --all # 查看磁盘IO统计
注意virsh shutdown不是直接断电,而是给虚拟机发送ACPI关机信号。虚拟机里如果没装qemu-guest-agent或者系统卡死,优雅关机会卡住。这时候再用destroy强制断电,但先想想有没有未落盘的数据。
监控方面,virt-top是命令行下最直观的工具,类似物理机的top,重点看每个虚拟机的CPU和内存占用。更精细的监控,我建议让虚拟机里安装qemu-guest-agent,这样libvirt能拿到客户机内部的信息,也能配合做快照冻结、在线调整内存等操作。
5.3 关于磁盘格式、快照、迁移和性能的三点实操心得
第一点:磁盘格式别上来就选raw。raw格式性能确实好一点,但生产环境我更推荐qcow2,它支持快照、稀疏分配和压缩,一个50G的qcow2磁盘文件,实际用了多少才占多少空间。对于多数业务,qcow2加virtio驱动的性能差异几乎感知不到,但运维和管理方便太多了。
第二点:快照不等于备份。很多人以为给虚拟机打了一个快照就安全了,实际上qcow2内部快照依赖同一个磁盘文件,一旦磁盘文件损坏,内部快照一起完蛋。我的习惯是:临时变更前打快照,重要数据用外部备份或直接拷贝qcow2文件。对于需要长期保存的虚拟机,考虑整机备份或者用virsh dumpxml导出配置,再备份磁盘文件。
第三点:性能调优优先看CPU pin和NUMA。多路服务器上,虚拟机CPU如果不绑定物理CPU,会引起缓存抖动和NUMA跨节点访问,性能损失在数据库这类延迟敏感场景下非常明显。先用lscpu -e看清楚NUMA拓扑,再用virsh vcpupin把虚拟机的vCPU绑到同一个NUMA节点上,内存也通过virsh edit指定numatune策略。这个操作能解决很多"虚拟机怎么比物理机慢很多"的疑问。
最后再分享一个排查思路上的小技巧:遇到KVM性能或启动问题,先别急着动配置,第一步查dmesg | grep -i kvm,第二步查virsh list --all的状态,第三步查/proc/cpuinfo的vmx/svm标志,第三步查host是否被其他hypervisor占住。这套链路下来,80%的常见问题都能定位到方向。KVM这东西,原理清楚之后,所谓的疑难杂症其实都是那几个老坑的变体。
