
相信不少朋友都有过这样的经历工作或学习里需要一个Linux环境但手头只有一台Windows电脑要么装双系统来回重启折腾要么用VirtualBox或VMware开虚拟机总觉得性能差点意思、操作也慢半拍。我个人的选择是QEMUKVM这套组合尤其是宿主系统本身就是Linux的时候这套方案在性能和灵活性上几乎是碾压级的。这篇内容我打算把QEMUKVM从环境准备、虚拟机创建到性能调优的全过程完整梳理一遍目标是让一个接触虚拟化不深的人也能在5分钟内用命令行或图形化工具搭出一台Ubuntu 24.04虚拟机。你不需要是内核专家只要按照步骤走就能复现整个流程并且通过优化让虚拟机的CPU、磁盘、网络性能都尽量贴近物理机。文章里还会专门整理我实际踩过的坑、排查过的常见问题希望能帮你省下不少弯路。1. 为什么我最终选了QEMUKVM1.1 QEMU和KVM到底是怎么配合的刚开始接触这套方案的人很容易被QEMU和KVM这两个词搞晕。简单说KVM是Linux内核里自带的虚拟化模块它把CPU的硬件虚拟化能力Intel的VT-x或AMD的SVM直接暴露给用户态程序让虚拟机里的指令可以“近乎原生”地执行。但它本身只负责CPU虚拟化和内存虚拟化对外设、磁盘、网络的模拟并不直接管。QEMU则是一个功能强大的模拟器它可以纯软件方式模拟出整台机器包括CPU、内存、硬盘、网卡等。当QEMU和KVM配合时QEMU就不再走纯软件模拟路线而是调用KVM提供的加速接口把CPU密集型任务交给硬件虚拟化处理这样虚拟机跑起来的速度非常接近物理机。我用一个不太严谨但好理解的比喻KVM像是给CPU开了一条高速专用车道QEMU则负责把“整台电脑”的其他零件搭出来。在实际部署中我们通常还会引入libvirt这个管理中间层。libvirt是一套API和守护进程libvirtd它统一管理QEMU/KVM、LXC等虚拟化后端提供了virsh命令行、virt-manager图形界面等工具。用libvirt的好处在于创建、删除、迁移虚拟机都可以通过统一语法完成后续写自动化脚本也方便得多。1.2 和VirtualBox、VMware比优势在哪里如果宿主系统是WindowsVMware Workstation和VirtualBox确实是顺手的选择它们安装简单、图形界面友好新手也能很快上手。但当宿主系统是Linux、尤其是服务器或开发机时QEMUKVM的优势就很明显了。第一个是性能。KVM是内核模块虚拟化开销极低CPU、内存、磁盘I/O、网络的性能损耗都远小于用户态模拟方案。对于数据库、编译等重负载场景KVM的表现基本可以达到物理机的九成以上而传统的纯软件虚拟化方案往往只有六七成。第二个是资源管理能力。libvirt支持精细的CPU配额、内存热插拔、磁盘限速、网络带宽控制等能力比如你想限制某台虚拟机最多使用4个vCPU、读写IOPS上限为10000用virsh或者virt-manager就能直接配置这在虚拟化场景里非常实用。第三个是可扩展性和自动化能力。QEMUKVM支持云镜像直接启动、快照、离线迁移、嵌套虚拟化还能和OpenStack这类云平台无缝集成。就算你只是个人用命令行创建虚拟机、批量克隆镜像这些操作也比点鼠标高效得多。当然QEMUKVM的学习曲线确实比VMware要陡一些很多概念桥接网络、virtio驱动、NUMA绑定等都需要理解。但只要把基本概念弄清楚后面你会发现这套方案非常“稳”且“快”值得投入时间。1.3 这台虚拟机适合谁来用QEMUKVM不是只给服务器管理员用的。我身边有不少嵌入式开发、后端开发、测试同学都在用这套方案。如果你属于下面几类人我觉得这篇文章完全适合你日常需要在Linux下开发、编译又不想频繁切换物理机系统的开发者需要快速创建多台隔离环境跑测试、做实验的测试工程师对虚拟化性能有较高要求不想用VirtualBox忍受磁盘I/O慢、网络吞吐低的人想在自己的Linux笔记本或服务器上搭建一套类似云主机体验的虚拟化环境的人。这篇教程的操作环境是Ubuntu 24.04宿主系统但我介绍的命令和思路在Debian、CentOS Stream等主流发行版上同样适用只是包管理命令和软件源略有差异。2. 环境准备与组件安装2.1 确认CPU虚拟化特性已经开启动手安装之前先确认你的CPU支持并开启了硬件虚拟化。在Linux终端里执行grep -E (vmx|svm) /proc/cpuinfo如果你看到了vmxIntel或svmAMD说明CPU支持虚拟化。但支持并不代表已经启用很多时候需要在BIOS/UEFI里打开VT-x或SVM功能。如果grep结果为空大概率是BIOS里没开你需要重启进固件设置界面找一下“Intel Virtualization Technology”或“SVM Mode”选项。还有一个更直观的方法直接看KVM模块是否加载lsmod | grep kvm正常情况下能看到kvm和kvm_intel或kvm_amd两个模块。如果没有输出可以手动加载sudo modprobe kvm sudo modprobe kvm_intel这条命令演示用的是Intel平台如果是AMD平台就把最后的模块名换成kvm_amd。加载之后再用lsmod确认一下即可。2.2 安装QEMU/KVM相关组件Ubuntu 24.04的软件源里已经准备好了所有需要的包一条命令就能装齐sudo apt update sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager这里简单解释一下每个包的作用qemu-kvm提供QEMU系统模拟器是虚拟机的核心执行引擎libvirt-daemon-systemlibvirt守护进程及其系统启动配置libvirt-clients提供virsh等命令行管理工具bridge-utils用于创建和管理Linux网桥的工具virtinst提供virt-install命令行工具用于快速创建虚拟机virt-manager图形化管理界面的包名如果你更习惯命令行操作不装它也行但新手建议装上后面创建虚拟机会方便很多。安装完成后启用并启动libvirtd服务sudo systemctl enable --now libvirtd检查服务是否正常运行sudo systemctl status libvirtd看到active (running)就说明libvirtd已经跑起来了。这时候再执行virsh list --all如果输出为空列表且没有报错说明libvirt可以正常连接QEMU驱动。2.3 用户组与权限配置默认情况下只有root和libvirt用户组的成员才能管理虚拟机。为了避免每次操作都用sudo把自己的用户加入相关组sudo usermod -aG kvm,libvirt $USER注意修改用户组后需要重新登录会话或者注销再登录才能生效。我经常看到有人执行完这条命令后直接运行virsh list还是提示权限不足其实就是因为没重新登录组权限还没刷新。重新登录后执行id如果输出里出现了kvm和libvirt说明权限已经加上。到这里环境已经准备好了。可以下载Ubuntu 24.04的ISO镜像文件备用我用的是desktop版镜像做演示服务器版操作流程几乎一样。下载好镜像后建议把它放到一个统一目录比如~/iso/方便后面指定路径。3. 5分钟搭好Ubuntu 24.04虚拟机的实操路径3.1 图形化方案virt-manager一条龙如果你对命令行还不熟悉最直观的方式就是用virt-manager。启动方式很简单virt-manager如果是第一次运行它会提示连接QEMU/KVM驱动默认地址是qemu:///system直接点“连接”即可。连接成功后界面左侧会显示宿主机信息右侧显示现有的虚拟机列表目前是空的。创建虚拟机的步骤很简单点击工具栏上的“新建虚拟机”按钮或者菜单栏选择File New VM选择安装方式这里选“本地安装介质ISO映像或光盘”然后点击“前进”点击“浏览”选择你下载好的Ubuntu 24.04 ISO文件点击“前进”设置内存和CPU数量。个人建议至少分配4GB内存和4个vCPU如果宿主机配置较紧张2GB内存2个vCPU也能跑基础操作但编译类任务会很吃力启用存储选择“创建磁盘映像”给虚拟机创建一块虚拟磁盘大小建议40GB起步格式默认是qcow2这个格式支持动态增长和快照点击“完成”之前可以在最后一步勾选“安装前自定义配置”这样能提前设置网卡模型、显示协议等参数。如果不想折腾直接完成即可。之后virt-manager会启动虚拟机并从ISO引导后续的Ubuntu安装流程就跟物理机装系统一样了。图形化方案的优势是直观每一步都有提示新手照着点就能完成整个过程确实用不了5分钟。3.2 命令行方案virt-install快速部署如果你更倾向于命令行操作或者需要在脚本里批量创建虚拟机那就绕不开virt-install。首次创建虚拟机我最常用的命令模板是这样的sudo virt-install \ --name ubuntu2404 \ --memory 4096 \ --vcpus 4 \ --disk path/var/lib/libvirt/images/ubuntu2404.qcow2,size40,formatqcow2 \ --cdrom /home/你的用户名/iso/ubuntu-24.04-desktop-amd64.iso \ --os-variant ubuntu24.04 \ --network networkdefault,modelvirtio \ --graphics spice \ --video qxl逐个说明参数的含义--name虚拟机名称后续用virsh管理的时候会用到这个标识--memory内存大小单位是MB4096就是4GB--vcpusvCPU数量--disk指定磁盘路径、大小和格式如果没有该文件virt-install会自动创建--cdrom指定ISO安装镜像路径--os-variant告诉libvirt针对该操作系统做优化可以用osinfo-query os查看支持的列表--network网络配置。networkdefault表示使用libvirt自带的NAT网络modelvirtio是网卡模型--graphics spice启用SPICE显示协议配合--video qxl提供比较流畅的图形界面体验。执行命令后virt-install会创建虚拟机并打开图形窗口如果通过SSH远程操作需要配合VNC或SPICE客户端。如果你使用的是无桌面版Ubuntu服务器可以把--graphics改为--graphics none改用串口控制台安装sudo virt-install \ --name ubuntu2404 \ --memory 2048 \ --vcpus 2 \ --disk path/var/lib/libvirt/images/ubuntu2404.qcow2,size20,formatqcow2 \ --cdrom /home/你的用户名/iso/ubuntu-24.04-server-amd64.iso \ --os-variant ubuntu24.04 \ --network networkdefault,modelvirtio \ --graphics none \ --extra-argsconsolettyS0--extra-args里的consolettyS0会把内核日志和安装界面输出到串口这样你可以在终端里通过virsh console直接控制安装过程。这种无界面安装模式在远程服务器上特别实用。安装系统本身的过程和物理机一样选择语言、配置键盘、设置用户名密码、选择安装位置即可。安装完成后重启虚拟机记得在virt-manager里把ISO光盘从“光驱”中移除或者调整启动顺序为硬盘优先否则每次启动都会重新进入安装界面。3.3 安装Ubuntu 24.04的几个关键配置项Ubuntu 24.04的安装器做得比较友好大部分选项默认即可。但有三个地方值得特别注意磁盘分区建议选择“使用整个磁盘”装LVM。LVM的好处是后续扩容方便不用重建分区。如果你打算做快照测试qcow2格式本身就支持内置快照LVM不是必须但可以给内部文件系统层多加一层灵活性。创建用户账户时建议勾选“开机自动登录”或设置一个简单密码开发测试机上图方便省去每次输密码的麻烦。生产环境还是老实设个强密码。软件源配置建议换成国内镜像源。虽然安装阶段系统自带的源也能用但下载软件包速度可能不理想。装完系统后可以手动修改/etc/apt/sources.list.d/ubuntu.sources把其中archive.ubuntu.com和security.ubuntu.com替换成你所在地区访问速度较快的镜像地址再执行sudo apt update sudo apt upgrade -y这样能让系统更新和应用安装速度快很多。4. 性能优化技巧让虚拟机性能贴近物理机4.1 CPU和内存优化分配只是一部分更关键的是调度策略给虚拟机分配多核CPU并不难难的是让这些vCPU真正跑在合适的物理核心上。默认情况下libvirt会由内核调度器动态安排vCPU这在负载不高时问题不大但在高负载场景下CPU缓存命中率下降、NUMA跨节点访问内存等问题会导致性能明显缩水。如果服务器是单路或多路CPU先查看宿主机的NUMA拓扑numactl --hardware输出里会显示每个NUMA节点的CPU核心范围和内存大小。创建虚拟机时尽量把vCPU和内存都分配在同一个NUMA节点上避免虚拟机跨节点访问内存。在XML配置里可以通过numatune和vcpuplacement来设置。更进一步可以使用CPU pinningvCPU绑定把虚拟机的每个vCPU固定到特定的物理核心上。编辑虚拟机配置virsh vcpupin ubuntu2404 0 2 virsh vcpupin ubuntu2404 1 3这条命令的含义是把虚拟机的第0个vCPU绑定到物理CPU的第2个核心第1个vCPU绑定到第3个核心。具体绑到哪个核心要依据宿主机的拓扑和空闲情况来定。绑定的好处是减少了vCPU在不同物理核心间迁移的开销让CPU缓存和TLB命中率明显提升。不过要注意别把多个虚拟机绑到同一批核心上否则会互相争抢。内存方面建议启用KSMKernel Samepage Merging来合并相同的内存页尤其当你同时运行多台相同操作系统的虚拟机时共享内存页能显著降低内存占用。启用方式sudo sh -c echo 1 /sys/kernel/mm/ksm/run临时生效重启后失效。如果想永久开启可以写一个systemd服务或把配置写入/etc/sysctl.conf。不过KSM有CPU开销如果宿主机内存足够不一定非要开可以用virsh setmem配合内存热插拔按需调整大小。4.2 磁盘I/O优化virtio驱动和缓存策略是重点磁盘I/O是虚拟机性能最直观的短板优化前后差别非常大。首先要确保虚拟机的磁盘总线类型是virtio而不是默认的IDE或SATA。virtio是一种半虚拟化I/O方案虚拟机里的驱动会绕过设备模拟层直接与宿主机通信吞吐量和延迟都远好于模拟设备。在创建虚拟机时--disk参数里可以指定busvirtio--disk path/var/lib/libvirt/images/ubuntu2404.qcow2,size40,formatqcow2,busvirtio如果已经创建好了在virt-manager里打开虚拟机配置把磁盘总线改为VirtIO后重启即可。Ubuntu 24.04的内核自带virtio驱动改完一般直接就能启动。其次是缓存策略。在virt-manager的磁盘配置里有一个“缓存模式”选项默认是None直写。对于大多数应用场景我推荐writeback回写它先把写入数据缓存到宿主机内存里再异步刷入磁盘写入性能提升非常明显。代价是宿主机突然断电时缓存中的数据可能会丢失所以生产环境要权衡一下。如果追求更高的数据安全性可以使用directsync或None。命令行方式修改virsh edit ubuntu2404找到对应的disk段修改driver标签里的cache属性为writeback。如果你的虚拟磁盘是qcow2格式还可以看看discardTRIM是否开启它能让虚拟机删除文件时及时释放宿主机的磁盘空间。在XML配置里给driver加上discardunmap即可driver nameqemu typeqcow2 cachewriteback discardunmap/最后QEMU 8.0以上版本默认支持io_uring作为磁盘I/O引擎相比传统的threads和native模式io_uring在并发I/O场景下延迟更低、吞吐更大。确认QEMU版本qemu-system-x86_64 --version如果版本较新可以在driver标签里添加driver nameqemu typeqcow2 cachewriteback ioio_uring/实测下来调好virtio总线、writeback缓存、io_uring引擎之后虚拟机里做编译、数据库读写速度和物理机差距已经非常小。4.3 网络优化多用virtio-net和vhost-net虚拟机网络性能的默认配置通常比较保守但对于需要高吞吐的应用优化空间很大。首先是网卡模型。创建虚拟机时如果没指定很多工具默认会用e1000这种模拟网卡兼容性好但性能一般。改成virtio-net后网络包处理效率会显著提升--network networkdefault,modelvirtio如果你已经建好了虚拟机用virt-manager打开网络配置把设备模型改成virtio即可。Ubuntu 24.04系统安装时一般会自动加载virtio_net内核模块所以不用担心驱动问题。其次是启用vhost-net。vhost-net是内核态的网络后端它允许虚拟机数据包处理直接通过内核模块完成绕过了QEMU用户态进程的拷贝延迟会低不少。大多数发行版默认已经加载了该模块确认一下lsmod | grep vhost如果有vhost和vhost_net输出说明已经启用。默认创建的虚拟机如果网卡模型是virtio基本上自动走vhost_net路径。另外如果你需要大量的网络吞吐可以考虑给virtio-net开启多队列。多队列允许虚拟机使用多个CPU核心并行处理网络包在转发或高并发场景下提升明显。创建虚拟机前可以用virsh edit给interface添加队列配置或者在virt-install命令中加参数。但需要注意多队列需要虚拟机内部正确配置多个队列的中断和RSS对新手有一定门槛普通开发场景默认单队列完全够用。关于网络模式libvirt默认的NAT模式能让虚拟机上网但如果你需要让外部设备直接访问虚拟机比如部署一个Web服务建议使用桥接模式。宿主机上创建网桥sudo virsh net-list sudo virsh net-info default默认网络是一个NAT网络虚拟机在NAT后面的私有网段里外部无法直接访问。想桥接可以在virt-manager的虚拟网络设置里新建一个桥接网卡或者手动编辑网络XML。桥接模式下虚拟机会直接出现在局域网的网段里拥有独立IP其他设备可以直接访问它。不过桥接需要物理网卡支持一般没问题还要注意公司或校园网可能限制同一物理口下多IP的情况。4.4 容易被忽略的细节优化设备精简、快照和资源限制很多细节其实对体验影响很大但官方文档很少专门强调。我把自己常年积累的几个“小动作”分享给大家。第一个是移除不需要的模拟设备。默认创建的虚拟机会带上USB控制器、软驱、声卡等一堆设备如果只是做服务器或开发环境这些用不上还白白消耗资源。在virt-manager里打开硬件信息列表把不需要的设备比如SoundCard、USB Redirection移除XML配置文件也会相应变短。第二个是合理设置内存气球。libvirt默认会启用内存气球virtio-balloon它允许宿主机动态回收虚拟机空闲内存。但如果你在虚拟机内跑数据库或Java应用JVM或数据库引擎往往会占用大量内存气球动态缩小时可能导致虚拟机内部性能波动。对于性能敏感的应用建议在XML里把memballoon的model改为none让虚拟机内存分配固定下来。第三个是做好镜像快照。qcow2格式天生支持快照可以在执行危险操作前快速打一个快照virsh snapshot-create-as ubuntu2404 baseline clean system with docker installed回滚时virsh snapshot-revert ubuntu2404 baseline快照操作很快比复制整个镜像文件方便太多了。推荐每个重要节点都打一个快照容错率会高很多。第四个是给虚拟机设置资源上限。在XML里cputune可以设置sharesCPU权重、period和quotaCPU配额blkiotune可以设置磁盘权重。比如限制虚拟机最多只能使用4个vCPU的80%时间片cputune shares2048/shares period100000/period quota80000/quota /cputune对于服务器上跑多台虚拟机、想公平分配资源的场景这种配置特别有用。5. 常见问题与排查实录5.1 权限报错和模块加载问题症状是执行virsh list --all时提示failed to connect to the hypervisor或Permission denied。排查思路是先确认libvirtd服务在跑systemctl status libvirtd如果服务正常再看自己的用户是否在libvirt组里groups不在组里就重新执行前面的usermod并重新登录。还有一种情况是SELinux或AppArmor拦了权限路径。Ubuntu默认用AppArmor偶尔会遇到虚拟机无法访问某些目录下的ISO文件或磁盘镜像。简单处理方式是检查/var/log/audit/audit.log或dmesg输出看有没有被AppArmor拒绝的记录。如果是可以把对应的虚拟机配置文件加入AppArmor白名单或者把镜像放到默认的/var/lib/libvirt/images/目录下。5.2 性能达不到预期怎么排查虚拟机内部跑分和物理机差距很大时先别急着调参按下面顺序排查第一确认虚拟机里是否用了virtio驱动的设备。执行ls -l /sys/class/net/如果网卡名称是eth0之类的模拟设备名而不是ens3这类virtio设备名说明可能还在用模拟网卡。同理检查磁盘设备名是否是vd*。第二检查CPU是否被限制或超卖严重。在宿主机上查看virsh vcpuinfo ubuntu2404如果某个vCPU的“cpu time”一直很高但“affinity”绑定导致部分核空转可以调整绑定策略。如果宿主机上还有其他重型虚拟机在跑资源争抢也会导致性能下降。第三验证是不是磁盘I/O瓶颈。在虚拟机里跑一个简单的随机读写测试dd if/dev/zero of/tmp/test bs1M count1024 oflagdirect对比在宿主机上同样操作。如果宿主机瞬间完成而虚拟机卡很久重点检查磁盘缓存模式是否设置成了None、是否用了IDE总线。5.3 网络不通和SSH连接失败新创建的虚拟机能正常上网但宿主机SSH连不进去这种问题我遇到太多次了。通常原因是虚拟机内部没有开启SSH服务或者防火墙拦截了22端口。Ubuntu 24.04默认可能只安装了openssh-server但没启动或没放行端口其实新版Ubuntu安装时只要选过“Install OpenSSH server”一般会自动启。没选过的话手动操作sudo apt install openssh-server sudo systemctl enable --now ssh如果是外部设备想访问虚拟机的服务记得确认虚拟机IP是否是局域网可路由地址桥接模式而不是NAT模式下的私有地址。NAT模式下外部设备想访问虚拟机需要在宿主机上设置端口转发比较麻烦建议直接用桥接。还有一个常见情况是虚拟机内使用了和宿主相同网段的静态IP导致ARP冲突。在虚拟网络配置中最好用DHCP或者手动指定一个不冲突的IP地址。5.4 图形界面卡顿和分辨率不对用virt-manager打开虚拟机图形界面感觉鼠标飘、画面不流畅这通常是显示协议和驱动没配对造成的。推荐SPICE协议搭配QXL显示驱动两者的组合在Linux guest里表现很好。在虚拟机的硬件信息里查看显示项如果当前是VGA建议改成QXL并把显示协议从VNC改成SPICE。如果分辨率最高只有800x600多半是虚拟机内部没有安装增强驱动SPICE guest tools。Ubuntu 24.04安装包默认不一定带需要手动安装sudo apt install spice-vdagent安装后重启虚拟机分辨率就能自由调整剪贴板共享、文件拖拽等功能也一并可用了。写到最后的一点体会从第一次在命令行里敲virt-install到现在我用QEMUKVM跑过嵌入式交叉编译环境、Java服务集群、数据库测试实例也踩过不少性能坑、网络坑但整体上这套组合确实“越用越顺手”。每次新建虚拟机我最深的感受是优化不是一步到位的事而是根据你的实际负载慢慢调出来的。先把virtio驱动和缓存策略做好就能覆盖大多数场景的性能需求再根据频繁出现的瓶颈去调整CPU绑定、网络队列和资源配额一步一步逼近物理机体验。最后再分享一个小技巧给虚拟机配好了常用环境之后别急着关机先打个快照。后面不管怎么折腾系统、装坏什么软件一条命令就能恢复到干净状态。这个习惯帮我省下了大量重复“重装系统”的时间也是我认为在虚拟化工作流里性价比最高的操作之一。