1. 动手前先建立KVM的“生态认知”这不只是一个内核模块1.1 KVM/QEMU/libvirt/OpenStack四层关系梳理很多刚接触服务器虚拟化的人装了KVM之后发现“怎么没有图形界面”“怎么没有管理控制台”然后就开始怀疑是不是装错了。这里我先帮你把KVM的技术栈理顺因为你后面装的是整个虚拟化平台不是一个单独的软件包。KVMKernel-based Virtual Machine从2007年合并进Linux内核后本质上是一个内核模块。它负责把CPU的硬件虚拟化特性Intel VT-x或AMD-V暴露给用户态程序让操作系统认为“自己跑在一台物理机上”。但光有KVM你没法创建虚拟机因为你还需要一个用户态工具去模拟硬盘、网卡、显示输出等设备。这个工具就是QEMU。QEMU单独运行效率不高配合KVM模块后CPU指令可以直接跑在物理CPU上性能非常接近原生。再往上一层是libvirt。它是一套统一的虚拟化管理API提供后台守护进程libvirtd支持virsh命令行、virt-manager图形工具以及后续接OpenStack、Ovirt等云平台。生产环境里很少有人直接敲qemu-system-x86_64命令去启动虚拟机基本都是通过libvirt来管理。所以你装环境时实际上要装的是“KVM内核模块 QEMU用户态 libvirt管理栈”这三层。如果只装了qemu包没启动libvirtd服务虚拟机也能起但你就只能手动敲一长串qemu命令没法用云平台调度碰上都算你运气好。1.2 为什么云计算底层大量在用KVM现在很多做云计算运维的人学习路径是“Docker - Kubernetes - OpenStack - Hadoop搭建”。但你要清楚容器和虚拟机解决的问题不同。Docker共享宿主机内核适合跑无状态应用KVM提供完整的虚拟机隔离适合跑异构操作系统、遗留系统、数据库等关键业务。OpenStack默认的Hypervisor就是KVM各大公有云的底层节点相当一部分也是基于KVM魔改或者定制的。搞明白这个关系还有一个实际好处当你在招聘网站上看到“云计算运维”要求熟悉KVM时其实考察的不是你会不会点virt-manager而是你能不能从裸机开始把宿主机环境、libvirt存储池、桥接网络、安全策略全部搭起来。这部分恰恰是环境搭建的核心也是本系列第一部分要解决的问题。1.3 哪些场景不适合用KVM我遇到过有人想把KVM装在一台Windows桌面电脑上给测试用还有人在云服务器ECS里试图装KVM然后发现没有/vdev/kvm设备。先说结论KVM不是万能的动手前先确认你的场景。如果你的物理机只有4GB内存和一块机械硬盘跑一个Windows虚拟机就很勉强不如直接装VMware Workstation或者VirtualBox它们对资源的要求更低也更适合个人桌面虚拟化。如果你在一台云厂商的通用型ECS上想跑KVM除非云平台明确支持嵌套虚拟化Nested Virtualization否则内核里不会暴露/dev/kvm你装上libvirt也会报“找不到kvm设备”。这时候要么选择裸金属服务器要么就换容器方案。如果你的需求只是隔离进程、快速交付微服务用Docker/K8s就够了KVM的隔离性和性能开销对轻量场景来说是“过重”的。搞清楚了这些再去装环境你就不会因为“装完之后发现没法用”而归咎于操作步骤。2. 宿主机硬件检查与BIOS配置最容易被忽略的一步2.1 三行命令确认CPU是否支持硬件虚拟化在Debian系里装KVM之前永远先跑这三条命令grep -E (vmx|svm) /proc/cpuinfo lscpu | grep -i virtualization ls /dev/kvm第一条结果里如果出现vmx说明你的Intel CPU开启了VT-x出现svm说明AMD CPU的AMD-V可用。lscpu的输出会更直观能看到“Virtualization: VT-x”或“Virtualization: AMD-V”的字样。第三条最关键如果/dev/kvm存在说明KVM模块已经加载或者可以直接被调用。这里有一个容易误判的坑在物理机上如果grep有vmx但/dev/kvm不存在通常是因为BIOS里关闭了虚拟化或者内核没有加载kvm_intel模块也可能是因为你运行在一个已经虚拟化的环境里比如自己套了自己的KVM VM。不要急着执行modprobe先去看BIOS。2.2 BIOS开启VT-x/AMD-V与VT-d这一步很关键给物理服务器做系统时我通常会在装系统前就进到BIOS里做三件事开启CPU虚拟化Intel平台叫Intel VT-xAMD平台叫AMD-V不同厂商BIOS可能叫“Virtualization Technology”或“SVM Mode”。开启VT-dIntel或IOMMUAMD这是给PCI直通用的。如果你后续需要把物理显卡、NVMe SSD、网卡直通给虚拟机这一步不做直通会失败或者性能极差。关闭Secure Boot安全启动。虽然新版本Fedora和RHEL支持Secure Boot下加载KVM模块但Debian系加上第三方编译模块时大概率会遇到签名问题我倾向于在服务器上直接关掉省得折腾。有一点值得说透VT-d不是“开了就一定好”。它开启后系统会让IOMMU接管DMA重映射对某些老旧设备可能出现兼容性问题。如果你的场景只是跑普通虚拟机不开IOMMU也完全能用。我一般在需要GPU直通、SR-IOV网卡虚拟化时才强制开启。2.3 内存、磁盘、网卡的选型思路KVM宿主机对资源的要求和装桌面系统完全不是一个量级。根据我自己的经验给你一个相对稳妥的参考配置配置项最低建议生产环境建议说明CPU4核支持VT-x/AMD-V16核以上每台虚拟机至少分配1-2个vCPU内存8GB64GB以上宿主机自身占2GB左右其余全部分给虚拟机系统盘40GBSSD 240GB以上存放宿主机系统和软件存储盘100GBSSD/HDD按业务分配存放虚拟机镜像建议单独分区或独立盘网卡千兆万兆支持多队列虚拟机数量多时链路聚合和SR-IOV很关键关于CPU还要多说一句KVM允许超分配CPU比如物理机4核你可以开8个vCPU的虚拟机。但这不意味着物理CPU能凭空变多只是让多个vCPU在物理核上排队跑。生产环境建议超分配比例不超过2比1否则延迟和CPU steal会很难看。2.4 嵌套虚拟化的特殊情况有些场景你只有一台VPS或云主机但又想学习KVM可以检查云厂商是否开启嵌套虚拟化。如果有你在云主机里能跑KVM如果没有会像我在前面说的那样卡在/dev/kvm这一关。嵌套虚拟化开启的命令在各平台不一样但Linux侧你只要确认两点CPU flag里有vmx/svm且/dev/kvm存在基本就可以继续。如果只是CPU flag有但/dev/kvm不存在多半是宿主机未开启嵌套功能你再怎么装软件都无解。3. Debian系与麒麟系统安装QEMU/KVM包管理与服务配置全流程3.1 一条命令装齐所有基础组件Debian/Ubuntu系是我最常用的KVM宿主系统安装命令如下sudo apt update sudo apt install -y qemu-kvm qemu-system-x86 libvirt-daemon-system libvirt-clients virtinst bridge-utils virt-manager逐个人说下这些包是干嘛的qemu-kvm与qemu-system-x86提供QEMU用户态负责I/O设备模拟。qemu-kvm是Debian的元包qemu-system-x86是架构相关的二进制。libvirt-daemon-system与libvirt-clientslibvirtd守护进程和virsh管理客户端。virtinst提供virt-install命令这是命令行创建虚拟机的核心工具自动化脚本必用。bridge-utils提供brctl命令用于创建桥接网络。virt-manager图形化管理界面非必须但新手排错时比较直观。如果你的系统是RHEL/CentOS系命令对应为yum/dnf install qemu-kvm libvirt virt-install bridge-utils逻辑完全一致。我这里以Debian为主是因为麒麟等国产系统的上层大多也能贴合这套包管理后面单独说差异。3.2 确认内核模块加载状态装完包后先做一次加载检查lsmod | grep kvm正常情况下能看到kvm_intel或kvm_amd模块以及kvm模块本身。如果没看到执行sudo modprobe kvm_intel # 或 sudo modprobe kvm_amd如果modprobe报错比如Required key not available大概率是Secure Boot的问题。此时别再纠结回到BIOS把Secure Boot关掉再开机。如果报的是CPU不支持虚拟化请回到第2节重新检查。为了开机自动加载可以写入配置文件echo kvm_intel | sudo tee /etc/modules-load.d/kvm.conf有一类特殊情况你的CPU名是海光或者兆芯。海光CPU基于AMD Zen架构走的是kvm_amd模块兆芯则一般识别为kvm_intel。不要因为对方说是“国产CPU”就凭感觉选模块直接lspci和lscpu看架构特征最靠谱。3.3 libvirtd服务的状态检查与开启安装libvirt后服务可能默认没有启动。Debian 11/12上通常启用socket activation你需要确认两个单元的状态sudo systemctl enable --now libvirtd sudo systemctl status libvirtd如果libvirtd启动失败最常出现的原因是默认网络“virbr0”创建失败或者系统中已经存在同名桥接。此时可以查看journaljournalctl -u libvirtd -n 50如果是端口冲突或地址池被占用把/etc/libvirt/qemu/networks/default.xml里的IP段换掉然后重启libvirtd。这个文件内容是192.168.122.0/24的NAT网络如果和你现有的内网冲突建议改成别的段比如192.168.200.0/24。3.4 银河麒麟、统信UOS等国产环境下的安装差异因为国产化替代这些年越来越普遍很多单位的服务器是“麒麟系统 海光/兆芯CPU KVM”组合。但在安装时你会发现直接apt install连镜像源都不一定能通。这里有两套做法第一如果你是用二进制安装包和本地源可以找ISO镜像自带的virt相关包在安装介质里往往已经内置了qemu-kvm和libvirt。用“软件包管理器”或dpkg本地安装即可。第二如果系统能联网麒麟V10x86兼容Debian系可以尝试用apt源安装但部分版本仓库里的包名是“qemu-kvm”、“libvirt-daemon”和原版Debian类似。海光CPU在主板BIOS里通常默认开启SVM但有些国产服务器为了安全默认关闭装机时一定要去BIOS确认。我踩过的一个坑是麒麟系统的内核里默认没有把kvm_amd模块加入initramfs每次重启都要手动modprobe。解决办法是把模块写入/etc/modules和modules-load.d然后执行update-initramfs -u重新生成镜像。装上之后其它管理命令和Debian完全一致。3.5 给当前用户授权libvirt组这一步不做你后面virt-manager会弹“Failed to connect socket to /var/run/libvirt/libvirt-sock”virsh也要用sudo才能跑。原因很简单libvirtd的socket文件默认对root和libvirt组开放权限。sudo usermod -aG libvirt $USER sudo usermod -aG kvm $USER newgrp libvirt这里有个小细节newgrp只对当前终端生效如果你重新登录系统会重新分配组权限属于正常现象。生产环境给运维人员的账号加libvirt组即可不要直接给root。4. 虚拟机的存储与网络准备环境搭建的真正门槛4.1 规划存储池和镜像目录很多教程到这里就结束直接说“可以创建虚拟机了”。但实际上没有规划存储池和镜像目录后面虚拟机一多磁盘空间一两周就被撑爆而且你根本不知道是哪台虚拟机占的。所以在第一次创建虚拟机之前我建议你把存储方向想好。libvirt里的存储池概念可以简单理解为“虚拟机的硬盘放在哪里”。默认路径是/var/lib/libvirt/images如果你系统盘只有40GB那基本没跑几个虚拟机就满了。所以我一般做法是单独准备一块数据盘挂载到/data或者/storage在该目录下创建子目录/data/kvm/images通过virsh pool-define-as创建新存储池或者直接修改默认pool的路径创建并启动存储池的命令如下sudo mkdir -p /data/kvm/images sudo virsh pool-define-as vm-images dir --target /data/kvm/images sudo virsh pool-start vm-images sudo virsh pool-autostart vm-images这样做的价值是存储和系统分离。将来宿主机重装系统虚拟机镜像还在数据盘上恢复libvirt配置就能把虚拟机捡回来。别把鸡蛋放在系统盘上这是我给所有做虚拟化的人的第一条建议。4.2 慎重选择磁盘镜像格式qcow2还是raw创建虚拟机时会要求选择磁盘格式。我见过有人用raw格式装了一个80GB的Windows结果占满了整块磁盘才发现问题。你需要搞清楚两种格式的核心差异raw格式性能最好直来直去文件大小等于磁盘大小。创建80GB的raw磁盘立即占80GB空间。qcow2格式支持写时复制、快照、压缩、加密。创建80GB的qcow2磁盘初始可能只占几MB随着数据写入逐渐变大。生产环境我推荐qcow2除非你有特殊性能需求。一个常见的误区是认为qcow2“不支持原生性能”实际上在普通SATA/SAS盘上qcow2和raw的差距不超过5%。但在SSD上做高IO数据库时raw配合直通确实更稳定。日常虚拟机、测试环境、甚至生产业务qcow2都够用。如果你已经建了raw格式的虚拟机也不用重装可以用qemu-img convert无损转换。命令如下sudo qemu-img convert -f raw -O qcow2 /data/kvm/images/old.img /data/kvm/images/old.qcow2转换期间建议虚拟机处于关机状态否则数据不一致到时候哭都来不及。4.3 默认NAT网络与生产环境桥接网络的选择安装libvirt后会自动生成一个虚拟网络virbr0默认是NAT模式IP段192.168.122.0/24。虚拟机通过这个网络能访问外网但外网无法主动访问虚拟机。这个环境适合学习和隔离测试。但如果你是想给服务器做系统、跑真实业务虚拟机需要被局域网里的其它机器直接访问那你必须用桥接模式。所谓桥接就是让虚拟机像一台独立的物理机一样直接接入宿主机所在的局域网和宿主机共用一个物理网卡和交换机端口。Debian系创建桥接的经典步骤sudo apt install -y bridge-utils sudo ip link add name br0 type bridge sudo ip link set br0 up sudo ip link set eth0 master br0 sudo ip addr add 192.168.1.10/24 dev br0上面这些命令实时生效但重启就没了。要持久化需要改/etc/network/interfaces。以Debian 11为例auto eth0 iface eth0 inet manual auto br0 iface br0 inet static address 192.168.1.10 netmask 255.255.255.0 gateway 192.168.1.1 dns-nameservers 223.5.5.5 bridge_ports eth0 bridge_stp off bridge_fd 0改完执行sudo systemctl restart networking。这一步风险比较高如果配置写错了你可能会直接失去SSH连接。建议在物理控制台或者带外管理如IPMI/BMC的机器上操作万一断网还能救回来。4.4 使用bridged网络后常见的链路故障排查我每次在客户现场做桥接配置时第一次几乎都遇到过虚拟机起不来网络或者通了但丢包严重。这里说两个最典型的问题。第一个是NetworkManager和/etc/network/interfaces冲突。如果系统装了NetworkManager它会尝试接管eth0和br0导致配好的桥接不生效。解决方式是执行systemctl stop NetworkManager systemctl disable NetworkManager或者干脆在NetworkManager里配置连接。第二个是忘记关闭STP生成树协议。在普通交换机环境下虚拟机的bridge端口接上后交换机可能因为检测到环路而阻塞端口几十秒表现为虚拟机开机后Ping不通外部过一两分钟又通了。解决办法是在br0上设置bridge_stp off并把bridge_fd设为0让内核不再走生成树定时器。桥接之后你在虚拟机里配置的IP就是和宿主机同一网段的独立IP。注意IP不要和宿主机或其它机器冲突否则会ARP混乱全网抖动到时候排查起来特别痛苦。5. 环境验证清单确保“能开虚拟机”而不是“装好了软件”5.1 用virt-host-validate全面检查宿主机能力软件装完、网络和存储配好后很多人就直接开始装虚拟机结果遇到一堆莫名其妙的问题。我更建议你先花两分钟跑一个权威的检查命令virt-host-validate这个命令会逐项检查CPU虚拟化、模块加载、设备访问权限、安全配置、IOMMU等。输出里全是“PASS”最佳。如果出现类似“WARN (Unknown if this platform is supported)”的提示通常不代表环境不可用只是libvirt没有收录你这个CPU型号或平台信息不用太紧张。如果出现“FAIL”则要重点看是哪一项。最常见的是“Check for device /dev/kvm”失败这就回到我们之前说的要么BIOS没开虚拟化要么kvm模块没加载要么这是个不支持嵌套的云主机。5.2 检查libvirtd、默认网络、存储池状态下面的命令组合可以一次看清整个环境的健康状况systemctl status libvirtd virsh net-list --all virsh pool-list --all我期望的输出是libvirtd状态activedefault网络存在且active至少有一个存储池无论它是默认的images目录还是我们新建的vm-images。如果net-list里显示default网络没有active先启动它virsh net-start default virsh net-autostart default如果这步报错最可能就是IP段冲突或者防火墙拦了DHCP。看看iptables/nftables里是否有针对virbr0的规则被清掉过。有些运维为了“加固安全”把默认FORWARD链DROP了导致虚拟机连外网几乎不通。排查利器是tcpdump -i virbr0看虚拟机能不能收到DHCP Offer。5.3 用virt-install创建第一台测试虚拟机环境验证的终极标准是能不能实际创建并启动一台虚拟机。我建议用一个最小的云镜像测试比如Debian的cloud-init镜像或Ubuntu cloud image。这里给出一个最简单但完整的命令sudo virt-install \ --name test-vm \ --memory 2048 \ --vcpus 2 \ --disk path/data/kvm/images/test-vm.qcow2,size10,formatqcow2 \ --os-variant debian11 \ --network networkdefault \ --graphics none \ --location /data/iso/debian-11.iso \ --extra-args consolettyS0注意几个参数的意义--graphics none表示不使用VNC图形界面用串口控制台适合服务器远程安装--extra-args只对Linux安装有效让内核输出到串口如果安装Windows你就不能用--location而是需要先制作一个virtio-win驱动盘然后通过VNC连上去手动装。如果创建过程中报“host doesnt support requested virtual machine type”十有八九是KVM加速没生效检查/usr/bin/kvm是否存在或者qemu是否以TCG模式运行。TCG是纯软件模拟慢到怀疑人生生产环境绝对不能用。5.4 启动后还能做什么常用管理与排查命令速查虚拟机创建成功后用几个命令可以快速判断环境是否正常virsh list --all virsh start test-vm virsh console test-vmvirsh console需要虚拟机的串口终端支持连接后可以用ctrl]退出。如果SSH连接不上虚拟机先确认网卡是否识别。比较常见的坑是装出来的虚拟机没有virtio驱动尤其是Windows磁盘和网卡都会显示为未知设备。这时候要挂载virtio-win驱动ISO或者安装时提前指定存储总线和网卡模型为virtio。另外日常排查中virsh edit test-vm可以改XML配置virsh dominfo test-vm查看基本信息virsh vcpuinfo test-vm看CPU使用情况。这组命令相当于虚拟化环境里的“top ps”必须熟练掌握。到这里一台KVM宿主机的环境搭建和验证就算完整了。后面你可以开始规划虚拟机资源分配、做快照、配置迁移或者把libvirt接入OpenStack进行云平台管理。我在实际部署中最常被问的一句话是“为什么我照着教程装了还是起不来虚拟机”——绝大多数都能在前面这几个环节里找到答案。先别急着装几十台虚拟机把宿主机环境一次搭到位后面能省出成倍的时间。
