最近折腾了一台搭载AMD Ryzen AI Max+ 395的迷你主机,目标很明确:宿主机跑Ubuntu Server 24.04 LTS,做家里的常驻服务器,但手头有几个Windows专属软件也必须能跑起来。和大多数人的第一反应不同,我没直接在这台机器上装双系统,而是选择了KVM/QEMU方案,把Win10装成虚拟机。这套组合踩下来,有惊喜也有坑,把完整过程整理出来,给想在高性能AMD平台上跑服务器+Windows虚拟机的朋友做个参考。折腾环境、装虚拟机这事,细节决定成败,少踩一个坑就能省一晚上。
1. Ryzen AI Max+ 395到底强在哪,为什么选它跑Win10虚拟机
1.1 一块“APU天花板”带来的虚拟机红利
AMD Ryzen AI Max+ 395这颗处理器,严格说已经不是传统意义的APU了。它集成了Zen 5架构的16核32线程CPU、RDNA 3.5架构的40CU核显,以及XDNA 2架构的NPU。最关键的是内存——它支持超高位宽的LPDDR5X统一内存,顶配规格下容量轻松来到96GB甚至128GB级别。这种“CPU+GPU+内存全部打包”的设计放在服务器场景里,简直是为虚拟化量身定做的。
跑虚拟机这件事,最怕的不是CPU不够快,而是“吃不饱”。CPU慢一点无非是多等几秒编译、多转一会儿码,但如果内存带宽不足,虚拟机里的磁盘IO、网络转发、图形绘制全都会卡,而且卡得毫无规律,排查起来非常折磨。Ryzen AI Max+ 395的超高位宽统一内存恰好把这层瓶颈拿掉了,我在Win10虚拟机里同时开浏览器、Office套件和几个绘图软件,宿主机的负载依然很轻松。
另一个红利来自核显。很多人在Linux服务器上装Win10虚拟机,默认会放弃图形加速,Windows桌面卡成幻灯片。但在这颗处理器上,Radeon 890M级别的核显有amdgpu驱动,QEMU可以借助它给虚拟机提供不错的图形性能。后续如果愿意深入折腾,这块核显还支持SR-IOV直通,能给虚拟机分出独立的显卡设备——这个后文会细说。
1.2 无头服务器场景下的资源分配思路
我这台机器内存是128GB,硬盘用了两条NVMe组了软件RAID 1。规划资源时,我给自己定了这么一套分配方案:
| 资源项 | 宿主机保留 | Win10虚拟机分配 | 备注 |
|---|---|---|---|
| CPU | 6核12线程 | 10核20线程 | 宿主机跑Docker和编译任务,不能全给虚拟机 |
| 内存 | 64GB | 64GB | Win10给64GB已是“豪横”水平,剩余留给文件缓存 |
| 存储 | 2TB NVMe RAID 1 | 200GB虚拟磁盘 | qcow2格式,后续可按需扩容 |
| 网络 | 千兆/2.5G物理网卡 | 桥接模式 | 虚拟机需要能被NAS和其他设备直接访问 |
很多第一次玩虚拟化的人容易犯一个错误:把所有核心全塞给虚拟机。我一开始也这么干过,结果宿主机卡到连SSH都延迟。原因很直白,宿主机本身要跑文件系统、网络协议栈、虚拟化层,这些都得吃CPU。你给虚拟机32个vCPU,KVM调度器本身也会产生额外开销,反而降低整体吞吐。
预留资源这件事没有标准答案,我的经验是:宿主机至少保留25%的CPU和25%的内存,尤其在无人值守的服务器上。你要是只跑一个Windows虚拟机、宿主什么都不干,那可以多给点;但只要跑Docker、跑监控、跑NAS服务,务必要留余量。Ryzen AI Max+ 395一共就16个物理核心,给虚拟机10到12个,剩下的足够稳住宿主机,这个平衡点是最舒服的。
2. 宿主机Ubuntu Server 24.04 LTS的环境准备与踩坑
2.1 安装时容易被忽略的SSH与RAID配置
Ubuntu Server 24.04 LTS用的还是subiquity文本安装向导,整体很清爽,但有两个选项非常容易被忽略。第一个是OpenSSH server,安装向导在“软件配置”阶段会问你要不要装SSH,默认是不装的。无头服务器没有显示器没有键盘,不装SSH就意味着你得再接显示器去救,极其痛苦。所以我建议这里直接勾选“Install OpenSSH server”,并且准备好自己电脑上的终端软件。
第二个是磁盘布局。24.04的安装器支持自定义存储配置,可以用软件RAID。我现在这台机器是两条NVMe组RAID 1,当时在安装界面里选了“Custom storage layout”,然后对两块盘分别建了相同的分区,再组合成md设备。具体的菜单路径是:先选中对第一块盘,新建GPT分区表,创建EFI和Linux文件系统分区;第二块盘做同样操作;然后点“Create RAID”,选RAID 1,把两个对应分区加进去,最后在RAID设备上建LVM或者直接用ext4。这套操作在subiquity里不算难,但要记住RAID 1是“两块盘完全镜像”,容量只有单盘大小,数据安全性远比性能重要。
装完之后第一件事,我建议马上跑一遍:
sudo apt update && sudo apt upgrade -y sudo reboot不要跳过升级。24.04刚发布后有几个内核小版本修正,涉及KVM和amdgpu驱动的稳定性,长期跑虚拟机最好穿上最新补丁。
2.2 安装后必做的虚拟化确认与内核参数
系统装完,确认虚拟化是否可用的标准动作如下:
egrep -c '(vmx|svm)' /proc/cpuinfo如果输出数字大于0,说明CPU的虚拟化扩展已经打开。AMD平台对应的是SVM,通常在BIOS里叫“SVM Mode”或者“AMD-v”。有一类迷你主机默认把SVM关闭,哪怕你在系统里看到/dev/kvm不存在,也没法用KVM,只能退回QEMU纯软件模拟——那个性能落差会让人怀疑人生。所以拿到新机器第一件事,进BIOS把SVM打开,顺便确认Secure Boot的模式不要影响后续加载OVMF。
再安装一个cpu-checker工具做确认:
sudo apt install cpu-checker kvm-ok理想输出是:
INFO: /dev/kvm exists KVM acceleration can be used到这里,宿主机的虚拟化地基就打好了。
3. 虚拟化方案选型:KVM/QEMU为什么是唯一靠谱选项
3.1 对比VirtualBox、VMware后的结论
这个话题容易引战,但我只从“服务器长期跑虚拟机”这个场景说结论。VirtualBox的GUI和易用性确实好,但它的无头管理、性能以及稳定性和KVM不在一个量级,而且VirtualBox的vboxdrv内核模块每次内核升级都要重新编译,在无人值守的服务器上这就是定时炸弹。VMware Workstation的兼容性很强,但它是面向个人桌面场景的,且需要GUI辅助管理,许可证也是开销,放在纯命令行SSH环境里很别扭。
KVM/QEMU是Linux内核自带的全虚拟化方案,架构上分两层:KVM负责CPU虚拟化和内存虚拟化,直接利用AMD-V/SVM硬件扩展;QEMU负责模拟设备。这套方案的优势一句话总结:它是Linux系服务器上性能损耗最小的方案,同时libvirt生态提供了完整的命令行管理能力,备份、快照、迁移、自动启动全都有成熟API。Ryzen AI Max+ 395这种性能怪物,配KVM才不浪费。
3.2 virtio全套驱动:虚拟机性能的关键
用QEMU装Windows,最容易被人忽视却又影响最明显的,是磁盘和网卡的总线类型。装的时候如果图省事用默认的IDE硬盘和e1000网卡,装完系统也能用,但磁盘IO和网络吞吐会惨不忍睹。
KVM里有个概念叫半虚拟化设备,也就是virtio系列。简单解释:普通设备模拟是QEMU给虚拟机模拟出一块“像真的一样”的网卡/硬盘,每次IO请求都要经过完整的设备仿真路径,开销巨大;而virtio让虚拟机直接感知到自己运行在虚拟化环境中,与QEMU通过共享内存环形队列交换数据,省去仿真损耗。
这就好比你要送一个包裹:模拟设备是快递员每层楼敲门问有没有人;virtio是直接在楼道里装了一部专用货梯+楼层对讲,快递员不用出电梯就知道各家需求。
virtio全家桶包括:
| 组件 | 对应驱动 | 作用 |
|---|---|---|
| virtio-blk | viostor.sys | 虚拟磁盘控制器 |
| virtio-net | NetKVM | 虚拟网卡 |
| virtio-gpu | viogpudo | 虚拟显卡 |
| qemu-guest-agent | qemuwatchdog | 宿主机与虚拟机通信的小助手 |
所以创建虚拟机之前,必须准备好一份virtio驱动镜像(ISO格式),装系统的时候在“加载驱动”步骤预装,否则一切白搭。
4. Win10虚拟机创建全过程:从virt-install到系统安装
4.1 准备Win10 ISO和virtio驱动ISO
安装KVM相关软件包:
sudo apt install qemu-system-x86 qemu-utils libvirt-daemon-system libvirt-clients virtinstlibvirt通过systemd管理,装好会自动启动libvirtd服务,可以用systemctl status libvirtd确认。
然后要准备两个ISO文件,都放进/var/lib/libvirt/images/目录:
- Win10官方ISO:建议用微软官方媒体创建工具或官方镜像站下载。
- virtio-win ISO:Fedora项目维护的Windows virtio驱动集合,文件名一般是
virtio-win-x.x.xx.iso,里面包含了viostor、NetKVM、viogpudo等所有需要的驱动。
这两个文件是后续安装的基础,缺一不可。我遇到过有人只准备Win10 ISO、装系统时才发现认不出virtio硬盘,然后各种乱改配置,纯粹浪费时间。
4.2 用virt-install一行命令创建虚拟机
下面是我实际使用的virt-install命令,先贴出来,再逐段解释:
sudo virt-install \ --name win10 \ --memory 65536 \ --vcpus 20 \ --cpu host-passthrough,cache.mode=passthrough \ --machine q35 \ --boot uefi \ --disk path=/var/lib/libvirt/images/win10.qcow2,size=200,format=qcow2,bus=virtio,cache=writeback \ --cdrom /var/lib/libvirt/images/Win10_22H2_Chinese.iso \ --disk path=/var/lib/libvirt/images/virtio-win.iso,device=cdrom \ --os-variant win10 \ --network network=bridged-network,model=virtio \ --graphics vnc,listen=127.0.0.1,port=5900 \ --video virtio \ --boot hd,cdrom,menu=on几个关键点说下为什么这么选:
--cpu host-passthrough:直接把宿主机的CPU特性全部透传给虚拟机,CPU性能和迁移性不可兼得,但在同一台机器上长期跑,这是最高性能选择。不要用默认的qemu64,性能差很多,而且缺少部分指令集可能导致Win10某些软件崩溃。--machine q35:QEMU的新一代芯片组,支持PCIe、UEFI、原生NVMe模拟。老式的i440fx芯片组虽然兼容性好,但对Win10来说功能缺失太多,性能也有损耗。--boot uefi:使用OVMF固件,也就是UEFI启动。Win10对UEFI支持很成熟,Legacy BIOS能避则避,安装系统时分区风格也统一用GPT。--network network=bridged-network,model=virtio:这里我的libvirt里已经定义了一个名为bridged-network的桥接网络,后文会讲怎么建。
创建命令跑完,如果没加--noautoconsole,终端会卡在等待VNC连接的状态,别慌,这是正常的。它其实在等待你去连VNC完成安装。
4.3 安装Win10时的几个关键选择
VNC连上去之后,就会看到Win10安装界面。这里有几个坑:
第一,选择安装版本时,建议选专业版(Pro),因为专业版支持组策略、RDP远程桌面等远程管理功能,家庭版会少很多服务器场景需要的东西。
第二,到了“您想进行哪种类型的安装?”这一步,一定要选“自定义:仅安装Windows(高级)”,因为我们要在空虚拟磁盘上安装,不是升级。
第三,最关键的一步:进入磁盘分区界面后,会看到“无法找到任何驱动器”或者磁盘显示未分配,但无法新建分区。这就是因为在virtio磁盘上还没加载驱动。点击“加载驱动程序”→“浏览”,找到光驱里的virtio-win目录,进入vioscsi\w10\amd64或viostor\w10\amd64文件夹,系统会自动识别驱动,加载后就能看到磁盘了。我第一次装的时候在这个界面卡了半小时,后面才知道还得加载vioscsi控制器驱动,而不仅仅是viostor。
装完系统后重启,VNC画面会黑屏一段时间,然后进入Windows首次启动的OOBE流程。走到这一步,Win10虚拟机的基础就已经立住了。
5. 安装后的性能调优与网络打通
5.1 让Win10用上接近原生的磁盘性能
系统装完,第一件事不是装驱动、不是调设置,而是用virsh关闭虚拟机,然后对配置做几项微调。
先用virsh shutdown win10优雅关机,然后编辑配置:
sudo virsh edit win10在<disk>标签里确认有这些关键属性:
<disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='writeback' iothread='1' queues='4'/> <source file='/var/lib/libvirt/images/win10.qcow2'/> <target dev='vda' bus='virtio'/> </disk>cache=writeback在虚拟机层面看来是异步写入,能显著提升小块随机写的性能;iothread和queues让磁盘中断可以由多个线程分发,减少CPU单核瓶颈。这套配置下,我在Win10里跑CrystalDiskMark,顺序读写能到接近宿主机裸盘性能的七八成,随机4K也远好于默认的IDE模拟。
如果对性能极致敏感,还可以在关机状态下用qemu-img convert把qcow2转成raw格式:
sudo qemu-img convert -O raw win10.qcow2 win10.raw -praw格式没有qcow2的元数据和写时复制开销,性能更高,但代价是失去快照能力。我个人的取舍是:服务器环境优先保快照能力,所以保留qcow2,性能损失在日常使用里几乎不可感。
5.2 桥接网络配置,让外部设备直接访问虚拟机
默认的KVM NAT网络让虚拟机只能从宿主机访问外部,外部设备想直接连虚拟机里的Windows就费劲了。要解决这个问题,要用桥接网络。
在Ubuntu Server 24.04的netplan配置文件/etc/netplan/01-netcfg.yaml里,把物理网卡加入网桥:
network: version: 2 ethernets: enp1s0: dhcp4: no bridges: br0: interfaces: [enp1s0] dhcp4: yes parameters: stp: false forward-delay: 0然后应用配置:
sudo netplan apply如果这才发现连不上SSH了,是因为enp1s0的IP已经转移到了br0上,重新用主机IP连一次即可。
接着在libvirt里定义这个桥接网络:
sudo virsh net-define /dev/stdin <<EOF <network> <name>bridged-network</name> <forward mode='bridge'/> <bridge name='br0'/> </network> EOF sudo virsh net-start bridged-network sudo virsh net-autostart bridged-network然后编辑虚拟机配置,把<interface>改成:
<interface type='network'> <source network='bridged-network'/> <model type='virtio'/> </interface>重启虚拟机后,Win10会直接从路由器获取局域网IP,外部设备可以RDP远程桌面、访问文件共享,跟在实体机上装了Win10没有任何区别。
5.3 CPU、内存与虚拟化层面的精细调优
到这里虚拟机已经能用了,但离“舒服地长期跑”还差几步。
CPU拓扑最好在创建时就规划好。如果系统里经常跑需要识别核心数的软件,建议用virsh edit在<cpu>标签里显式声明拓扑:
<cpu mode='host-passthrough' check='none'> <topology sockets='1' cores='10' threads='2'/> <cache mode='passthrough'/> </cpu>10核20线程,配合Windows本身的调度器,足够把多线程任务压满。注意不要把sockets设太多,Windows对多路CPU的NUMA感知和授权策略有很多历史包袱,单socket多核多线程是最稳的配置。
内存侧,如果宿主机内存富余,建议给虚拟机锁定内存并开启大页:
<memoryBacking> <hugepages/> <locked/> </memoryBacking>使用大页能减少TLB miss,内存密集型应用明显受益。但锁内存后虚拟机占用的物理内存不能再被宿主机回收,所以仅在内存充足时这样设置。我给了64GB锁定,宿主机还剩64GB,日常完全够用。
还差最后一步,安装qemu guest agent。在Win10虚拟机里加载virtio-win ISO,安装guest-agent组件,然后宿主机执行:
sudo virsh qemu-agent-command win10 '{"execute":"guest-ping"}'能看到响应就说明宿主机和虚拟机之间建立了可靠通道。这个工具在关机冻结文件系统、做快照迁移时是刚需,没有它,快照容易损坏文件系统。
6. 无头环境下最折磨人的几个坑
6.1 没有显示器时怎么完成Win10初始化
无头服务器装Windows虚拟机,最大的障碍不是技术,而是你没法像在实体机上一样盯着屏幕操作。虽然virt-install创建时已经开启了VNC,但VNC在无头环境下的使用有几个隐含的坑。
第一,VNC端口默认只听本地回环地址。我之前创建命令里用了listen=127.0.0.1,这样从外部直接连VNC是连不上的。解决方式不是把它改成0.0.0.0裸奔,而是通过SSH隧道转发:
ssh -L 5900:localhost:5900 user@your-server然后本地VNC客户端连localhost:5900即可。这一来,VNC服务不暴露到公网,SSH加密隧道也保护了会话内容。
第二,Win10首次启动OOBE时,VNC下鼠标键盘操作偶尔会漂移或者没反应。我遇到过两次,解决办法是先按Ctrl+Alt+Del切换登录画面再切回来,或者等OOBE加载完再操作,别一上来就急着点。
第三,分辨率。VNC默认只有800x600,Win10桌面看着很难受。装完virtio-gpu驱动后,可以在显示设置里调整分辨率,也可以直接在virsh edit里给<video>标签加一行<model type='virtio' heads='1' primary='yes'>。
6.2 Win10找不到磁盘与TPM报错的处理
无头环境遇到“自动修复”循环和TPM报错是另一个高频坑。“自动修复”循环大多是因为强制关机或者VNC写入中断,系统文件出现异常。Win10的自动修复在虚拟机里很容易失效,因为它要用的恢复环境可能没装全。碰到这种情况,先在VNC里选“高级选项”→“命令提示符”,然后执行:
sfc /scannow dism /online /cleanup-image /restorehealth大概率能救回来。如果连高级选项都进不去,只能用Win10安装介质引导,进入“修复计算机”,多半就是重装系统或者从快照恢复了——这就是我为什么坚持用qcow2格式保留快照能力的原因。
TPM方面,Win10不像Win11那样硬性要求TPM 2.0,但有些软件和Windows更新会检查这个设备。如果想彻底消除这类弹窗,可以给虚拟机装配软件TPM(swtpm):
sudo apt install swtpm然后在虚拟机XML里加入:
<devices> <tpm model='tpm-crb'> <backend type='emulator' version='2.0'/> </tpm> </devices>重启后Windows就能识别到TPM 2.0设备了。
6.3 虚拟机随宿主机自启与快照管理
服务器长期运行,最不希望的就是宿主机重启后,还得手动一个个启动虚拟机。libvirt提供了非常简单的自启设置:
sudo virsh autostart win10这样宿主机开机后libvirtd会自动拉起这台虚拟机,Windows也会以恢复模式短暂检查后进入桌面。
说到快照,qcow2格式支持两种快照:内部快照和外部快照。内部快照是把状态和磁盘变更都记在同一个qcow2文件里,简单但会拖慢整个虚拟磁盘性能;外部快照是生成一个新的增量qcow2文件,性能和灵活性更好,但要自己管理备份链。日常操作建议用外部快照:
sudo virsh snapshot-create-as win10 win10-clean-state "win10刚装完系统时的干净状态" --disk-only --atomic这个快照会生成一个新的磁盘镜像文件,原文件变成只读底座,新写入的数据都进增量文件。想回滚时,删除增量文件即可瞬间回到快照时刻的状态。要注意的是,做快照前最好通过qemu guest agent冻结一下Windows文件系统,否则正在写入的数据可能处于不一致状态。这也是我前面为什么强调guest agent一定要装。
到这里,这台Ryzen AI Max+ 395迷你主机上的Win10虚拟机就算完整落地了:KVM原生虚拟化、virtio全驱动、桥接网络、自启管理、快照备份,该有的都有了。实际跑了一周多,日常办公、跑Windows工具软件、访问共享文件夹都很稳定,宿主机负载低得离谱。如果你手头也有这台处理器的高性能主机,或者类似的高核心数AMD平台,完全可以照这套流程搭一套自己的Linux服务器+Windows虚拟机环境。硬件性能越强,虚拟化带来的体验就越接近原生,这是用一次就回不去的体验。