1. 先把KVM这个概念捋清楚,别一上来就装错东西
1.1 搜索"KVM安装"的时候,你到底在找哪一个KVM
这个词确实容易串台。我身边不少做机房运维的朋友,一听到"KVM"脑子里蹦出来的是机柜里那台带一排按钮、能切键盘鼠标显示器的切换器;而另一拨折腾Linux虚拟化的,说的KVM是Kernel-based Virtual Machine,内核级虚拟化。这两个东西同名不同命,搜出来的教程南辕北辙,很多人装了半天发现自己装的跟想用的完全是两码事,白白折腾一下午。所以动手之前先自我确认一句:你要的是在Linux机器上跑虚拟机、给服务器装系统、做测试环境,那这篇走的就是Kernel-based Virtual Machine这条路。
这套方案的完整技术栈其实是三到四层叠起来的。最底下是KVM内核模块,它自己不做完整的硬件模拟,只是把CPU的虚拟化扩展能力(Intel的VT-x、AMD的AMD-V)暴露给用户态,负责CPU和内存的虚拟化调度。中间是QEMU,一个纯软件的设备模拟器,负责模拟网卡、磁盘控制器、USB、显卡这些外围设备。KVM和QEMU配合起来,才是一台能跑操作系统的完整虚拟机。再往上是libvirt,它是一套管理API和守护进程,把QEMU那些又臭又长的命令行参数封装成统一的接口,virsh命令和图形界面都是通过它来操作虚拟机的。最上层才是virt-manager,也就是我们要用的图形化管理工具。
理解这个分层挺重要的,因为后面出问题的时候,你得知道往哪一层去查。图形界面点不动,可能是virt-manager和libvirtd之间的连接问题;虚拟机起不来报"KVM is not available",那是内核模块和CPU虚拟化那一层的事;网络不通,多半在QEMU的网卡模拟和宿主机网络配置上。分不清层,排查就是无头苍蝇。
1.2 图形化安装的两种理解,以及它适合谁
标题里"图形化安装"其实有两层意思,我在实际操作里两种都用过,得说清楚。第一种是用图形界面来安装和管理KVM虚拟机,也就是装好libvirt和virt-manager之后,通过点鼠标的方式创建虚拟机、挂载ISO、分配磁盘和网络,全程不用敲virt-install那一长串参数。第二种是在安装虚拟机的过程中走图形化安装向导,比如装Ubuntu、Windows的时候那个一步步点下去的安装界面,通过SPICE或VNC协议把虚拟机的画面显示出来。这两个经常被混在一起说,其实是两个独立的东西:管理端是图形化的,不代表客户机安装过程一定看得到画面;反过来也一样。
这篇内容我打算两个都覆盖。因为实际场景里,很多人是拿一台没有显示器的服务器(俗称无头服务器)来做宿主机,本地电脑装个virt-manager远程连过去管理,虚拟机装系统的画面也能正常显示。这套组合拳我觉得是目前最省心、最不容易出错的路子,比在服务器上硬装一个桌面环境要清爽得多,也比全程命令行敲参数友好,尤其适合刚开始接触虚拟化的朋友。
那么什么样的人需要这套东西?我的判断是这么几类:手头有一台性能还行的Linux机器或者服务器,想在上面跑几个隔离环境做测试的;需要给裸机装系统但没有显示器、或者想批量复现某个系统安装过程的;做开发需要一台干净的、随时能删掉重建的Linux或Windows环境的;还有想学虚拟化、但不想一上来就啃KVM源码和QEMU文档的。如果你属于这几类,下面的步骤基本可以照着抄。
1.3 开始之前,先明确硬件门槛和几个硬性前提
KVM不是装上就能用的,它对硬件有硬性要求,这点必须先说,不然装了发现跑不起来最打击积极性。第一个前提是CPU必须支持硬件虚拟化。Intel平台叫VT-x,AMD平台叫AMD-V,这是Intel和AMD各自实现的CPU虚拟化指令集扩展。近十年的主流服务器和桌面CPU基本都带,但很多机器出厂时BIOS里是默认关闭的,需要手动打开。这个开关通常藏在BIOS的Advanced或者CPU Configuration菜单里,名字可能是Intel Virtualization Technology、VT-x、SVM Mode、AMD-V之类,找到了改成Enabled就行。
第二个前提是内存和磁盘要留够。KVM本身占用很小,但虚拟机是实打实吃内存的。我一般建议宿主机至少留出每个虚拟机内存的两倍余量,比如你想跑一个4GB内存的虚拟机,宿主机最好有8GB以上可用。磁盘方面,虚拟机的虚拟磁盘文件会随着使用不断增长,做实验的话预留50GB以上的空闲空间比较稳妥,用SSD体验会好很多。
第三个是对内核版本的隐性要求。KVM从2.6.20就进主线内核了,现在主流的发行版内核都远高于这个版本,所以基本不用操心。但如果你的系统特别老,或者用的是某些裁剪过度的嵌入式发行版,那就得先确认一下。我后面用的例子主要以Ubuntu 24.04和Rocky Linux 9这两个为主,其他Debian系、RHEL系的发行版命令基本通用,差异我会单独标出来。
2. 装之前的环境体检,别省这一步
2.1 用三条命令确认CPU虚拟化是否就绪
体检这件事,我踩过的坑告诉我千万别跳过。曾经有一次在一台二手工作站上装了半天,虚拟机死活起不来,最后查出来是BIOS里VT-x没开。所以每次拿到一台新机器,我第一步就是确认虚拟化扩展到位了没有。最直接的是看CPU信息,Linux下打开终端敲:
lscpu | grep -i virtualization如果输出里出现VT-x、AMD-V或者Virtualization: VT-x这类字样,说明CPU支持且已经在操作系统里可见了。要是这条命令没输出,先别急着下结论,可能是CPU信息格式不同,再用下面这条兜底:
egrep -c '(vmx|svm)' /proc/cpuinfovmx是Intel的虚拟化标志,svm是AMD的。这条命令会返回一个数字,只要大于0就说明硬件支持,返回0才是真的不支持。我遇到过一次返回0的情况,结果进BIOS一看,VT-x被关了,打开之后立马正常。
如果你用的是Debian或者Ubuntu,还有个更傻瓜的工具叫cpu-checker,它会把KVM相关的几个条件一次性给你检查完:
sudo apt update sudo apt install -y cpu-checker sudo kvm-ok正常情况下会打印:
INFO: /dev/kvm exists KVM acceleration can be used看到这两行,基本就是绿灯了。如果提示KVM acceleration can't be used,它会顺便告诉你是缺了哪一环,照着提示查就行。这个工具特别适合新手,省得自己一条条对着猜。
提示:
/dev/kvm这个设备节点很关键,它是QEMU访问KVM内核模块的入口。如果这个文件不存在,虚拟机就只能以纯软件模拟(TCG)模式运行,速度会慢到让你怀疑人生。确认ls -l /dev/kvm存在且权限正确,是后面一切顺利的基础。
2.2 系统版本、软件源和更新策略
环境确认完了,接着处理系统本身。KVM相关的软件包都在各发行版的官方源里,不需要额外添加第三方源,这点比较省心。但有一点要注意:先把系统更新到当前版本的最新状态,尤其是内核相关的包。因为KVM、QEMU、libvirt三者之间有版本匹配关系,混用太老的组件偶尔会出现兼容性小毛病。
Ubuntu/Debian系:
sudo apt update sudo apt full-upgrade -yRHEL系(Rocky、AlmaLinux、CentOS Stream):
sudo dnf update -y这里有个经验:如果你用的是长期运行的服务器,不建议为了装KVM就无脑全量升级内核,因为升级内核可能需要重启,而重启生产服务器是要排期的。这种情况下我会用--security或者只装必要组件的方式,把影响面控制住。做法是先只装虚拟化组件,观察没问题再考虑内核更新的窗口。
另一个细节是universe仓库。Ubuntu上virt-manager这个图形工具在universe里,如果你的系统默认没启用这个仓库,装的时候会报找不到包。确认一下:
sudo add-apt-repository universe sudo apt updateRocky Linux的情况是,virt-manager在AppStream或者EPEL里。默认AppStream一般就有,如果报缺包,装个EPEL基本能解决:
sudo dnf install -y epel-release这些准备工作看着琐碎,但能帮你避开装到一半卡壳的尴尬。
2.3 网络方案怎么选,NAT、桥接还是macvtap
网络这块是新手最容易懵的地方,我单独拎出来讲。装KVM的时候,网络方案选型会直接影响后面的使用体验,所以我习惯在装之前就把方案定下来,而不是等虚拟机建好了发现连不上再回头改。
NAT模式是libvirt装好后默认就带的那张网,名字叫default,宿主机上会多出一个叫virbr0的虚拟网桥,网段通常是192.168.122.0/24。虚拟机通过它做地址转换访问外网,宿主机能访问虚拟机,但同局域网里的其他机器访问不到虚拟机。适合做测试、装完系统只需要虚拟机自己能上网的场景,配置最简单,几乎不用管。
桥接模式是把虚拟机的网卡直接“焊”到宿主机的物理网络上,虚拟机会从你局域网的DHCP拿到一个跟宿主机同网段的IP,对局域网其他机器来说它就是一台独立主机。适合需要对外提供服务、做集群实验的场景。代价是配置稍微麻烦,而且配错有把宿主机网络搞断的风险,这点我后面会专门讲。
macvtap模式算是桥接的一种轻量替代,性能不错,但有个已知的别扭之处:宿主机自己和macvtap虚拟机之间默认通信有问题。所以除非你有明确的性能诉求,我一般不建议新手一上来就上macvtap。
三种方案的对比整理成一张表,选型的时候对着看:
| 方案 | 宿主机与虚拟机互通 | 局域网访问虚拟机 | 配置难度 | 典型场景 |
|---|---|---|---|---|
| NAT(default) | 可以 | 不可以(需端口转发) | 低 | 测试环境、单机上外网 |
| 桥接(bridge) | 可以 | 可以 | 中 | 提供对外服务、集群实验 |
| macvtap | 默认受限 | 可以 | 中 | 追求网络性能、少干预宿主机网络 |
我的建议是:不确定用哪种就先用默认的NAT,把整套流程跑通,等确实有对外暴露需求再切桥接。这样学习曲线平缓,也不会因为网络配错把宿主机弄失联。
3. 命令行把KVM组件装齐,这是基础中的基础
3.1 各发行版的核心软件包清单与作用
图形化管理虽然好用,但底层的组件必须先装齐,virt-manager只是在这堆组件上的一个壳。这些包各管一段,搞明白它们分别干什么,后面出问题你能快速定位。我列一下常见包和它们的职责:
qemu-kvm(RHEL系叫qemu-kvm,Debian系现在也叫qemu-kvm或qemu-system-x86):提供QEMU和KVM的对接,是虚拟机的运行本体。libvirt-daemon-system/libvirtd:libvirt的守护进程和系统级配置,管理虚拟机、网络、存储。libvirt-clients/libvirt-client:提供virsh这套命令行工具。bridge-utils:桥接网络需要的工具,用NAT的话可以不装,但桥接场景必备。virtinst/virt-install:提供virt-install命令,用命令行创建虚拟机时用。qemu-utils:提供qemu-img等磁盘镜像管理工具。virt-manager:图形化管理客户端。
Ubuntu 24.04 / Debian 一套装下来:
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients \ virtinst bridge-utils qemu-utils virt-managerRocky Linux 9 / AlmaLinux 9 / CentOS Stream 9:
sudo dnf install -y qemu-kvm libvirt libvirt-daemon-kvm \ virt-install virt-viewer virt-manager这里说一下virt-viewer,它在RHEL系里经常和virt-manager一起装,作用是单独打开虚拟机的显示窗口,装系统的时候比在virt-manager大界面里点更清爽。Ubuntu上对应的是virt-viewer包,一般会作为virt-manager的依赖装上。
如果你的宿主机是无头的(没有桌面环境),那virt-manager其实可以不用装在服务器上,本地电脑装一个就行,具体我第4章讲。服务器上只要装到libvirt-daemon-system、libvirt-clients、qemu-kvm、virtinst这几样,能跑起虚拟机和virsh就够了,别在服务器上硬塞一整个桌面环境,占空间又拖累系统。
3.2 开启服务、做开机自启并验证
包装完了,服务得起来才能用。老版本RHEL和Ubuntu上管理的是libvirtd这个大守护进程,新的系统里libvirt开始往模块化方向走,拆成virtqemud、virtnetworkd这些细分的daemon,但绝大多数发行版默认还是靠libvirtd统一拉起。保险起见先管libvirtd:
sudo systemctl enable --now libvirtd sudo systemctl status libvirtd看到active (running)就对了。Ubuntu 24.04上如果你同时装了libvirtd和模块化的socket,可能会看到libvirtd.socket,一般不影响正常使用,virsh能连上就行。
服务起来之后,用virsh验证一下连接和默认网络:
virsh list --all virsh net-list --allvirsh list --all这时候会返回一张空表,说明libvirt连上了,只是还没有虚拟机。virsh net-list --all一般会看到一个名字叫default的网络,状态可能是inactive(未激活)。把它启动起来并设置开机自启:
sudo virsh net-start default sudo virsh net-autostart default再敲一次virsh net-list,状态变成active就正常了,同时宿主机上会出现virbr0这块网卡。可以用ip addr show virbr0确认它拿到了192.168.122.1这个地址。
还有个很好用但容易被忽略的体检命令,专门用来检查宿主机是否满足虚拟化的各项要求:
virt-host-validate它会把CPU、内存、IOMMU、安全相关的一堆检查项列出来,PASS的打勾,WARN的提示你。比如它会提醒你IOMMU没开(做设备直通才需要),或者cgroup版本之类的。我一般装完必跑一遍,心里有底。看到一堆PASS基本就可以放心往下走了。
3.3 普通用户权限配置,别什么都用root
这里有个坑我替朋友填过好几次:默认情况下,普通用户用virsh或者virt-manager连的是qemu:///session这个用户级连接,看到的虚拟机和系统级的qemu:///system不是一套。结果就是他在虚拟机管理界面里新建了一台机器,换回命令行virsh list却看不到,一脸懵。根因是权限没配好,用了user session而不是system。
正确做法是把当前用户加进libvirt和kvm这两个组:
sudo usermod -aG libvirt,kvm $USER加完要重新登录(或者至少newgrp libvirt刷新一下组)才生效。之后普通用户就能免sudo操作system级的libvirt了。Ubuntu上还有个额外步骤,libvirt装了polkit规则,一般sudo usermod之后配合重新登录就能用。如果还是提示权限不足,检查一下/etc/libvirt/libvirtd.conf里有没有把auth_unix_ro和auth_unix_rw设置成none(有些教程会这么改,但我不建议,这等于把门大开,任何本地用户都能操作宿主机上的所有虚拟机,安全性差)。
验证一下是否生效:
id | grep libvirt virsh -c qemu:///system list --all第二条命令如果不需要sudo就能正常返回表格,权限就配好了。这一步做完,后面无论是命令行还是图形界面,都统一走qemu:///system,不会再出现“两台不同的KVM”这种诡异现象。
注意:组权限的修改对已经登录的会话不生效。改完组之后不重新登录,你会觉得改了没用,其实是旧会话的凭据没刷新。这是新手最容易迷惑的点之一。
4. 图形化管理工具,本地装还是服务器装
4.1 virt-manager的两种使用姿势和各自的适用场景
到这一步,底层已经通了,接下来就是图形化这层怎么摆。我实际用下来有两种姿势,各有各的好。
第一种是在宿主机上直接装virt-manager。适合你的宿主机本身就有桌面环境,或者是一台带显示器的台式机、工作站。装完之后直接在菜单里搜"虚拟系统管理器"(Virtual Machine Manager)打开就能用,连接的就是本机的qemu:///system,零配置。这种最简单,推荐给用带屏机器的朋友。
第二种是本地电脑装virt-manager,远程管理无头服务器。这是我极力推荐给服务器用户的方式。你的服务器可能就一个SSH能进,没桌面,那完全没必要在上面硬装图形界面。你在自己常用的Windows、macOS或者Linux桌面机器上装一个virt-manager,然后通过SSH连到服务器的libvirt去管理。图形界面跑在本地,流畅,服务器那边一点图形负担都没有。
我为什么偏爱第二种?因为它的画面显示是走SPICE或者VNC直连的,配合SSH隧道加密,比传统的X11转发整个virt-manager界面要顺畅得多。X11转发那种方式,网络稍微抖动一下,界面就卡成PPT,而且每次连都得挂着一堆X11的包,配置麻烦。而qemu+ssh://这种连接方式,virt-manager本地渲染界面、远程只拉取虚拟机列表和调用libvirt API,虚拟机装系统的画面则通过一个自动建立的隧道传输,体验好太多。
4.2 本地virt-manager远程连接无头服务器,手把手配
假设你的服务器IP是192.168.1.100,SSH用户是ops。本地机器(以Linux桌面或Windows装好virt-manager为例)这样操作:
先确认本地能SSH到服务器,通常做一次密钥免密登录会更省心:
ssh-keygen -t ed25519 ssh-copy-id ops@192.168.1.100然后在本地机器上,如果装的是命令行版的virt-manager,可以直接这样启动并连远程:
virt-manager -c "qemu+ssh://ops@192.168.1.100/system"如果你用的是图形界面,那就打开virt-manager,菜单栏File→Add Connection,勾选Connect to remote host,方法选SSH,用户名填ops,主机名填192.168.1.100,然后点Connect。连上之后,你在界面上看到的就是那台服务器的虚拟机资源,新建、启停、看画面全都在这里完成。
这里有个关键点,服务器端的libvirtd用户要是ops能访问的。前面3.3节我们把ops加进了libvirt组,那就没问题。但如果ops没有system libvirt权限,连接会报权限错误。这时候要么给用户配组权限,要么用qemu+ssh://root@host/system这种(不推荐直接用root),要么配好polkit。
另外一个坑:服务器没有装virt-manager不代表连不上。远程连接时,服务器端只需要libvirtd、qemu-kvm这些运行时的东西,virt-manager纯客户端,装在本地即可。这点很多人搞混,以为服务器也得装一份。省下这个包,服务器能清爽不少。
提示:如果连远程时报
Cannot recv data: Connection reset by peer之类的错,八成是服务器端的libvirtd没启动,或者SSH用户的shell环境有问题。先ssh ops@host "systemctl status libvirtd"确认一下服务状态。
4.3 首次连接后要做的几件事:存储池与连接确认
连上之后先别急着建虚拟机,有两件收尾工作做好,后面省心。
第一件是确认识别到的连接是system级。在virt-manager左侧列表里,QEMU/KVM上面如果有个小箭头展开,能看到system字样(一般显示为QEMU/KVM默认就是system)。双击它连接,看到右侧显示主机名、内存、CPU等信息就对了。要是在列表里看到QEMU/KVM User session,那就是连错级别了,回去检查权限。
第二件是存储池。libvirt有个default存储池,默认路径通常是/var/lib/libvirt/images,用来放虚拟机磁盘和ISO镜像。virsh pool-list --all能看它的状态。如果没激活,用命令行建一下:
sudo virsh pool-define-as default dir --target /var/lib/libvirt/images sudo virsh pool-build default sudo virsh pool-start default sudo virsh pool-autostart default图形界面里对应在Edit→Connection Details→Storage标签页,能看到default池,绿色是激活状态。我习惯再单独建一个放ISO的池,比如把ISO都丢到/var/lib/libvirt/images/iso/,新建虚拟机选镜像的时候一眼就能找到,不至于在一堆qcow2文件里翻。
存储池和权限这两件小事的价值在于,它们能让后续“新建虚拟机”这一步顺滑无比。否则你新建的时候发现镜像列表空空如也,或者磁盘路径报权限拒绝,又得回头折腾。
5. 图形化界面新建虚拟机,把系统装进去
5.1 先建虚拟网络,NAT和桥接各怎么配
我建议在建虚拟机之前,先把网络按你的需求准备好,这样新建向导里直接选现成的网络,干净利落。
NAT网络基本不用建,默认default就是。只要3.2节里你已经net-start并net-autostart了,图形界面的网络列表里就能看到它,直接选。
桥接网络稍微多几步。先在宿主机上把物理网卡桥接起来。Ubuntu 24.04用netplan,假设物理网卡是enp3s0,编辑/etc/netplan/01-netcfg.yaml:
network: version: 2 renderer: networkd ethernets: enp3s0: dhcp4: false dhcp6: false bridges: br0: interfaces: [enp3s0] dhcp4: true parameters: stp: false forward-delay: 0这里最要紧的是物理网卡enp3s0下面不要再配IP,IP要配到br0上。物理网卡只作为桥的成员接口。这是把宿主机网络搞断的头号原因——两边都留了IP,网络路由一乱,SSH当场就断。一定要用netplan try先试,它会在120秒后自动回滚,给你留退路:
sudo netplan try试通了再sudo netplan apply。配完ip addr应该能看到br0拿到了局域网IP,而enp3s0只显示master br0。
然后在libvirt里定义这个桥接网络,存成br0.xml:
<network> <name>br0</name> <forward mode='bridge'/> <bridge name='br0'/> </network>导入并启用:
sudo virsh net-define br0.xml sudo virsh net-start br0 sudo virsh net-autostart br0图形界面里Connection Details→Virtual Networks标签应该就能看到br0变成active了。
注意:桥接配置和生产网卡绑在一起,改错可能失联。动手前最好有带外管理(IPMI、串口)能回得去,或者在本地终端操作而不是SSH。RHEL系用nmcli或者
/etc/sysconfig/network-scripts/下的ifcfg文件,思路一致:物理网卡挂到bridge上、IP配在bridge上。
5.2 新建虚拟机向导逐项拆解,每个选项背后的取舍
打开virt-manager,点左上角那个带加号的电脑图标,或者File→New Virtual Machine,向导就来了。我按步骤拆一下,每一处都讲讲为什么这么选。
第一步选安装来源。做全新系统安装就选Local install media (ISO image or CDROM),然后浏览选中你上传的ISO文件。virt-manager一般能自动识别出系统的类型和版本,比如你挂Ubuntu 24.04的ISO,它会自动把操作系统认成Ubuntu 24.04,这个识别结果会用于后面的优化参数(比如推荐的虚拟硬件、ACPI行为)。如果没识别准,手动在下拉里选对,别让它默认成某个奇怪的通用值,否则客户机可能需要额外驱动才能正常开机。
第二步内存和CPU。内存给多少,看客户机用途加宿主机的余量。跑一个纯命令行的Ubuntu Server测试机,1GB到2GB够了;跑图形界面的桌面版,建议4GB起步;Windows 10/11建议至少4GB到8GB,低于4GB会卡得难受。CPU核数一般给2到4核,除非宿主机核很多,否则不建议一上来就给一半以上的核,容易和宿主机抢资源。勾选Customize configuration before install这个选项,我强烈建议勾上,它会让你在建好之前进到一个细节配置界面,可以顺手把磁盘总线改成virtio、网络模型改成virtio、加装virtio驱动ISO等等。不勾的话它会直接开装,很多优化项就得装到一半再改,很别扭。
第三步磁盘。分配大小按需给,qcow2格式的磁盘是精简置备的,也就是你给40GB,实际上文件大小会随数据增长,不会一上来就占满40GB。所以放心给大一点,40GB、60GB都行。磁盘总线记得用virtio,性能比默认的IDE或SATA好一个台阶,前提是客户机装了virtio驱动。Linux内核原生支持virtio,没问题;Windows需要额外挂载virtio-win驱动盘,这个后面讲。
第四步网络。下拉里选Virtual network 'default': NAT或者你建好的br0桥接。设备型号这里,一定要从默认的e1000改成virtio,e1000是模拟的Intel千兆网卡,兼容性好但性能平庸;virtio是半虚拟化网卡,吞吐和延迟都强得多。Linux客户机原生支持,Windows需要对应驱动。
第五步在Customize configuration界面,还可以顺手做几件事:确认引导模式(BIOS还是UEFI,装某些新系统必须UEFI),检查显示协议(默认SPICE,配合QXL或virtio-gpu,看画面很流畅),需要串口调试的可以加一个Serial设备。这些都确认完,点Begin Installation,虚拟机的画面窗口就弹出来了,跟你坐在一台真机前装系统一模一样。
5.3 通过虚拟机给服务器做系统,以及装系统的实操细节
有朋友问“通过KVM给服务器做系统”是什么操作,我理解大致有两种含义,我都说说。
一种是用KVM虚拟机当作一个临时的Linux环境,去做一些装机前的准备工作,比如批量制作启动盘镜像、跑一些自动化脚本、准备PXE引导环境之类。因为虚拟机可以随时快照、回滚、删了重建,折腾坏了不影响宿主机,很适合做这种一次性、易出错的工作。
另一种,也是更直接的,就是在KVM虚拟机里完整地装一遍服务器操作系统,装好之后把这个磁盘镜像作为模板,或者导出、克隆到别处使用。这在搭建标准化环境、复现问题、做培训环境时特别常见。
具体到装系统的过程,virt-manager弹出的那个窗口里,操作跟真机无异。Ubuntu Server的安装向导是文字菜单式的,方向键选、回车确认;Ubuntu Desktop和Windows是图形化的,鼠标键盘都能用。有几个细节值得提醒。
首次启动顺序。虚拟机默认从硬盘启动,第一次没有系统盘,会自动回退到光驱引导,一般不用手动干预。如果它没进安装界面,在窗口里点进去按一下启动菜单键(不同系统不一样,比如SeaBIOS通常按Esc,UEFI按F2或者直接在virt-manager的Send Key菜单里发Ctrl+Alt+Delete重启)看看引导顺序对不对。
Windows虚拟机装virtio驱动。这是Windows客户机的必踩点。因为磁盘和网卡都用了virtio,Windows安装程序一开始是认不到磁盘的,会提示“找不到驱动器”。解决办法是在虚拟机配置里再加一个CDROM,挂上virtio-win.iso(这个镜像从官方渠道获取),然后在Windows安装到“选择安装位置”那一步,点“加载驱动程序”,从virtio-win盘里选对应系统的vioscsi或viostor驱动目录,装完后磁盘就出来了。网卡驱动同理,装完系统后从virtio-win盘的NetKVM目录里装。这个过程第一次做会觉得麻烦,做一次之后就有肌肉记忆了。
内存和vCPU的热插拔。Linux客户机配合virtio-balloon和virtio驱动,可以在不关机的情况下给虚拟机加内存(前提是宿主机有富余)。CPU热插拔支持得也不错,但要注意客户机内核和配置得允许。日常实验用不上,知道有这么回事就行。
快照不是备份。装完系统、配好环境之后,我习惯立刻打个快照(virt-manager里点虚拟机详情→Snapshots→Add),后面折腾坏了秒回滚。但一定要清楚,快照和虚拟磁盘文件共用存储,磁盘文件一旦损坏,快照跟着一起完蛋,它不能当备份用。真正的备份要么导出qcow2到别的存储,要么用virsh dumpxml保存配置加上磁盘副本。
装完之后,图形界面里虚拟机条目会从“运行中”状态稳定下来,你可以用virsh list在命令行确认它也在。NAT网络下,虚拟机通过DHCP拿到192.168.122.x的地址,宿主机直接ssh进去就行。桥接网络下,虚拟机会从局域网DHCP拿到跟你同一网段的IP,局域网任何机器都能访问。
6. 常见问题速查与踩坑实录
6.1 各类报错的原因与解决办法速查表
KVM用久了,你会发现大部分问题就那么几类,我整理成对照表,遇到问题先来这张表里对:
| 现象/报错 | 可能原因 | 排查与解决 |
|---|---|---|
KVM is not available/ 无/dev/kvm | BIOS未开启VT-x/AMD-V,或CPU不支持 | 进BIOS开虚拟化;lsmod | grep kvm看模块是否加载;kvm-ok检查 |
Cannot access storage file ... Permission denied | 磁盘文件属主/权限不对,libvirt以qemu用户访问 | 磁盘放/var/lib/libvirt/images/下;检查qemu用户对文件有读写权限;SELinux/AppArmor策略 |
virsh普通用户看不到自己建的虚拟机 | 连的是qemu:///session而非qemu:///system | 用-c qemu:///system;把用户加入libvirt组并重新登录 |
| 虚拟机装好连不上网(NAT) | default网络未启动,或防火墙拦截 | virsh net-list --all确认active;iptables/firewalld放行转发 |
| 桥接后宿主机直接失联 | 物理网卡和bridge都配了IP,路由冲突 | 物理网卡不配IP,IP只配br0;用netplan try留回滚 |
| 虚拟机磁盘/网络性能差 | 磁盘总线用了IDE/SATA,网卡用了e1000 | 改用virtio总线、virtio网卡;确认客户机识别到virtio设备 |
| Windows安装时找不到磁盘 | 未加载virtio存储驱动 | 挂载virtio-win.iso,安装界面手动加载驱动 |
| 图形窗口卡顿、延迟大 | 显示协议或显卡模型不合适 | SPICE配QXL/virtio-gpu;远程连接走qemu+ssh,别整机X11转发 |
| 虚拟机时间越走越偏 | 时钟源和定时器设置不当 | 客户机配chrony/ntp;配置里把时钟设成localtime给Windows、utc给Linux |
virt-manager无法远程连接 | 服务器libvirtd未启动或权限不足 | systemctl status libvirtd;确认SSH用户有system级权限 |
这张表覆盖了大概八九成的日常问题。用的时候有个小技巧:报错信息里的关键词直接复制去查,比整句去搜命中率高得多。libvirt和QEMU的报错往往写得很具体,比如它明说“Permission denied on /path/to/file”,那问题就在权限,不用瞎猜。
6.2 那些文档里不会写的实操心得
最后分享几个我这些年攒下的、几乎是踩坑踩出来的经验,常规教程里基本不提,但能帮你省不少时间。
第一,无头服务器永远优先用qemu+ssh的远程virt-manager,别在服务器上装桌面。服务器装桌面环境,一来占资源,二来升级维护一堆图形包很烦,三来服务器本来就不该干这个。远程管理的方式干净、安全,虚拟机的图形画面照样看得到,而且因为画面走的是独立隧道,比在本机上X11转发整个管理界面流畅得多。这个决定会让你的服务器长期受益。
第二,宿主机唯一网卡做桥接要极其小心,最好有带外管理。我见过不止一个人把生产服务器的唯一网卡桥接配错,SSH瞬间断,人又在异地,只能等机房现场救援。桥接这操作本身没问题,风险在于你没有回退通道。所以要么用netplan try这种带自动回滚的机制,要么在本地终端操作,要么确保有IPMI能远程回车。总之,动手前先想好“万一断了我怎么回去”。
第三,性能敏感就用virtio,兼容优先才用e1000和IDE。虚拟机的磁盘和网络,virtio和传统模拟设备的性能差距是肉眼可见的,尤其是磁盘IO。代价是Windows需要额外驱动。所以我的选择是:Linux客户机一律virtio,Windows装好驱动后也切virtio。只有在装系统的引导阶段、驱动还没加载时才临时用兼容设备,装完再调优。
第四,qcow2给实验用,raw或裸设备给性能用。qcow2支持快照、精简置备、压缩,做实验、做开发环境极其方便,磁盘文件还能随便拷来拷去。但如果是要跑数据库这种对磁盘IO极其敏感的负载,qcow2有一层额外的元数据开销,这时候可以考虑raw格式的磁盘文件,或者更进一步用LVM逻辑卷直接做虚拟机磁盘。所以磁盘格式的选择要看你跑什么,别一刀切。
第五,快照和备份是两码事,务必分开对待。快照就存在你的磁盘文件旁边,本质是“时间点标记”,用来快速回滚;备份是独立的副本,用来灾难恢复。把快照当备份,等磁盘文件损坏那天你会哭。我的做法是重要的虚拟机定期用qemu-img convert或者直接复制整份qcow2到别的存储,宿主机再配个定时任务,图个安心。
第六,定期跑一遍virt-host-validate。这个命令就像给宿主机做体检,系统内核升级、装了新驱动、改了安全策略之后跑一下,能提前发现隐患。我把它和virsh net-list、virsh list --all放在一起,作为每次登上一台宿主机后的例行操作,几十秒的事,能避免很多临到用时才发现的问题。
我在实际使用中发现,把基础设施的这些细节一次做到位,后面无论是要快速起几十个测试环境,还是临时复现一个线上问题,都从容得多。反之,桥接配得迷迷糊糊、权限理得不清不楚,每一次新建虚拟机都是一次新的踩坑。