资讯详情

资讯详情

Ubuntu上部署KVM:从零创建Ubuntu与Rocky虚拟机实战指南

我早年间在服务器上跑虚拟化一直用的都是Workstation那套图形界面方案后来接手了一台只有命令行接口的Ubuntu服务器要在上面同时维护一套Ubuntu测试环境和一套Rocky Linux运行环境图省事直接用之前那套思路结果远程图形界面卡到怀疑人生License和各种兼容问题也是一堆。后来把所有虚拟机迁到KVM上才意识到在Linux服务器上做虚拟化KVM才是真正被原生支持的那套方案。这篇文章不聊概念就聚焦在Ubuntu上部署KVM以及基于KVM手动创建Ubuntu与Rocky两类虚拟机把中间踩过的坑和最终落地的步骤完整拆开讲。KVM这套东西的好处在于它本身就是Linux内核的一部分性能损耗非常接近物理机远优于纯软件模拟的方案。对经常要在多套Linux发行版之间切换测试、跑CI构建、做服务端环境验证的开发者来说掌握这层能力之后效率完全不是同一个量级。以下内容面向的是已经有一台Linux服务器、想认真跑虚拟机但还没系统接触过KVM的读者全程用命令行实际操作无桌面依赖。1. 为什么最终选了KVM虚拟化方案的选型思路1.1 和VMware、VirtualBox那套方案的本质差异很多人第一次接触虚拟化都是在Windows桌面上装VirtualBox或VMware Workstation这种方案本身没问题但它是宿主操作系统上的一个用户态程序虚拟机的CPU指令需要经过一层软件转换再怎么优化都有额外开销。KVM就不一样它把Linux内核变成了一个Type-1虚拟化管理程序CPU的虚拟化指令直接由内核处理虚拟机里的进程和宿主机的进程一样被内核调度。放在实际使用中最直观的感受是IOPS和网络吞吐量的差距。同一个应用在KVM虚拟机里跑数据库类负载磁盘性能损失基本可以控制在10%以内而纯用户态模拟方案动辄损耗30%以上。我做过一个很直接的对照测试同样的磁盘顺序读写脚本在VMware Workstation里跑出来的速度大概只有宿机机的六成换到KVM以后恢复到了九成以上这个差距在高并发场景下非常致命。1.2 拆解KVM的组成部分它不是一个软件刚开始接触KVM的人通常会晕一阵子因为它不像VMware那样是一个整体产品而是由一组组件协同工作KVM内核模块提供CPU虚拟化和内存虚拟化的能力对应kvm_intel或kvm_amd两个模块QEMU负责模拟各类硬件设备比如网卡、磁盘控制器、显示输出让虚拟机以为自己在操作真实硬件libvirt一个统一管理API它屏蔽了底层QEMU的细节提供virsh、virt-manager等工具来操作虚拟机virt-install基于libvirt的命令行安装工具专门用来快速创建虚拟机。可以简单理解为KVM模块是引擎QEMU是传动轴libvirt是方向盘。日常操作里我们主要跟libvirt打交道很少直接裸调QEMU命令但理解这个分工对后面排错很重要。1.3 什么样的机器才能跑KVMKVM对CPU有硬性要求CPU必须支持硬件虚拟化指令Intel的VT-x或者AMD的SVM。绝大多数近十年的x86服务器和桌面CPU都支持但BIOS里默认可能是关闭状态。在Linux里确认的方法非常简单先看CPU标记中是否有vmx或svmegrep -c (vmx|svm) /proc/cpuinfo输出数字大于0就说明CPU支持且已经暴露给了系统。如果这里是0那就得进BIOS找Intel Virtualization Technology或SVM Mode选项打开。有些云服务器或者嵌套的虚拟机环境里光看CPU支持还不够还要确认LLVM特性等嵌套虚拟化标记这个后面踩坑部分再细说。2. 宿主机准备从BIOS到软件栈一次装到位2.1 先确认内核模块是否加载确定CPU支持后先检查KVM模块有没有正常加载lsmod | grep kvm正常情况下能看到kvm、kvm_intel或者kvm_amd两个模块。如果看不到执行modprobe kvm_intelAMD平台换kvm_amd手动加载同时systemctl reboot前可以把它写进/etc/modules-load.d/kvm.conf保证开机加载。这里有一个很常见的现象云厂商的VPS即使CPU显示支持vmx也无法加载KVM模块因为这些VPS的CPU虚拟化功能被云平台隔离了。这也是为什么我强烈建议想学KVM的读者用实体机或者能开嵌套虚拟化的专用服务器而不是普通云主机。2.2 Ubuntu宿主机安装KVM软件栈我当前宿主机用的是Ubuntu 24.04 LTS服务器版安装命令如下apt update apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager逐个解释这些包的作用对面刚上手的读者会有帮助qemu-kvm核心的QEMU用户态进程负责硬件模拟libvirt-daemon-systemlibvirt守护进程以及它的系统服务配置装好之后会在后台起一个libvirtdlibvirt-clients提供virsh、virt-host-validate这类命令行工具bridge-utils提供brctl工具后面配置网络桥接时会用到virtinst提供virt-install这个创建虚拟机的利器virt-manager图形化管理工具在纯命令行服务器上不装也没关系我装它主要是为了连VNC时省事。如果宿主机是Rocky Linux或CentOS系列对应的安装命令是这样dnf install -y qemu-kvm libvirt virt-install bridge-utils包名略有差异但组件逻辑完全一样。装完以后启动并设置开机自启systemctl enable --now libvirtd验证一下服务是否健康virsh version virsh nodeinfonodeinfo能看到宿主机CPU、内存、架构信息说明libvirt和KVM已经正常接通了。2.3 让当前用户获得virt-manager和virsh的管理权限这是一个非常容易被忽视的细节。装完libvirt之后系统默认只有root用户能通过virsh管理虚拟机。普通用户直接执行virsh list会出现权限报错。解决办法是把目标用户加入libvirt用户组usermod -aG libvirt $USER newgrp libvirtnewgrp是让当前会话立即生效不用退出重登录。如果不做这一步后面每次敲virsh前都要带sudo不仅麻烦还容易在脚本自动化时踩权限坑。libvirt的权限控制走的是Polkit机制加入了libvirt组之后默认策略允许组内用户对本地QEMU进行完全管理。2.4 确认KVM是否真的可用libvirt自带一个环境检查工具安装完后通常建议跑一次virt-host-validate它会对CPU虚拟化指令、IOMMU、安全模块等做全面体检。如果出现类似Device not available的WARN通常不影响基本使用但如果直接FAIL说明宿主机缺少必要特性这时候不用急着往下走先解决这个问题才是最优路径。3. 网络规划直接决定后续体验3.1 默认的virbr0 NAT网络够用但有限libvirt装好后会自动创建一个名为default的NAT网络对应虚拟网桥virbr0网段一般是192.168.122.0/24。新创建的虚拟机只要指定networkdefault就能自动通过NAT访问外网宿主机也能访问虚拟机。这个模式的优点是零配置开箱即用适合学习实验环境。缺点也很明显外部设备无法直连虚拟机只能通过宿主机端口转发进去。如果你只是用KVM装个系统练手这个模式最合适如果虚拟机要对外提供服务就得靠桥接。查看默认网络配置virsh net-list --all virsh net-dumpxml default3.2 桥接模式让虚拟机拥有独立IP生产环境里我基本全部使用桥接网络让宿主机物理网卡和虚拟机共享一个二层网络虚拟机就像局域网里一台独立机器。基于Ubuntu 24.04默认的netplan配置创建一个桥接网卡的操作大致如下。假设宿主机物理网卡叫eno1先备份现有配置然后编辑/etc/netplan/01-network-config.yamlnetwork: version: 2 ethernets: eno1: dhcp4: false bridges: br0: interfaces: [eno1] dhcp4: true应用配置netplan apply ip addr show br0执行之后br0会获取到原物理网卡的IP地址eno1本身不再持有IP。这样虚拟机创建时指定bridgebr0就能直接拿到局域网IP后续SSH、Web服务访问都不需要额外转发。这里有个坑需要特别提醒如果你是通过SSH远程操作宿主机netplan配置写错会导致网络断掉。稳妥的做法是先写一个临时配置文件并执行netplan try它会在120秒内自动回滚避免把自己锁在门外。我第一次配置时就因为直接apply导致宿主机失联只能跑去机房处理。3.3 什么场景需要直通或多网卡对绝大多数虚拟化用途来说NAT加桥接已经覆盖了全部需求。个别场景例如虚拟机需要跨多个VLAN、或者对网络性能有极致要求时可以考虑SR-IOV或者网卡直通让虚拟机独占物理网卡队列。这个运维成本会明显上升我日常很少用这里就不展开配置细节了。有这方面需求的读者先理解KVM网络的基本模型再去查对应硬件的直通文档会事半功倍。4. 用virt-install创建第一台Ubuntu虚拟机4.1 virt-install核心参数逐项拆解virt-install是创建虚拟机的主命令参数比较多但核心逻辑其实很清晰告诉它这台虚拟机有多大的CPU内存、磁盘放哪、ISO从哪引导、网卡接哪个网络、系统类型是什么。下面是我创建Ubuntu 24.04虚拟机时用的完整命令virt-install \ --name ubuntu2404 \ --memory 4096 \ --vcpus 4 \ --cpu host-passthrough \ --disk path/var/lib/libvirt/images/ubuntu2404.qcow2,size30,formatqcow2,busvirtio \ --network networkdefault,modelvirtio \ --graphics vnc,listen127.0.0.1 \ --os-variant ubuntu24.04 \ --location /data/iso/ubuntu-24.04.2-live-server-amd64.iso逐个参数拆解--name虚拟机名称virsh管理时的唯一标识--memory / --vcpus分配的内存MB和虚拟CPU核心数--cpu host-passthrough让虚拟机直接用宿主机的CPU型号和指令集相比默认的qemu64型号对性能提升非常显著尤其涉及SHA、AVX等高级指令的场景--diskpath指定磁盘镜像路径size设定磁盘大小GBformat指定镜像格式busvirtio表示使用半虚拟化磁盘控制器这是KVM性能最佳的组合--networknetworkdefault表示使用默认NAT网络modelvirtio同理使用半虚拟化网卡--graphics vnc通过VNC提供显示输出。前面配置listen127.0.0.1意味着VNC只监听本机回环地址外部无法直接连安全性更高--os-variant告诉libvirt目标系统类型它会根据系统类型优化默认参数。执行osinfo-query os可以查看所有支持的os-variant。这个命令执行后virt-install会启动虚拟机并进入Ubuntu安装界面同时终端会提示VNC连接地址。因为我把listen设为127.0.0.1需要在本机执行以下命令做SSH隧道转发然后才能通过VNC Viewer连接ssh -L 5900:127.0.0.1:5900 user宿主机IP本地打开VNC Viewer连接127.0.0.1:5900即可看到安装器界面。4.2 安装过程中的实际注意事项Ubuntu Server版安装器是TUI界面VNC里操作起来非常流畅没有复杂的地方。有两个细节值得注意第一裁剪安装时最好在安装器里预先配置好SSH server。Ubuntu安装器到最后一步有一个Install OpenSSH server勾选项这一步建议直接勾上省得进系统后再补装。第二磁盘布局。如果这台虚拟机只是用于测试直接用安装器默认的Use an entire disk就行让逻辑卷管理自动创建LVM以后扩容方便。不要为了省事选择一个特别小的分区后面装工具链时磁盘不足还得折腾扩容。我的经验是初始磁盘给30GB起步实际测试环境很快就会被容器镜像、编译输出占满。4.3 虚拟机装完后的基础验证Ubuntu安装完成后重启系统会从磁盘镜像启动进入登录界面。我在宿主机上执行virsh list --all虚拟机状态应为running。然后通过SSH隧道或局域网地址SSH进虚拟机确认网络通了跑一下systool或者lscpu直观看到虚拟机内部把宿主机的CPU型号透传进去了这时候第一台Ubuntu虚拟机就算正式落地。5. 手把手搭一台Rocky Linux虚拟机无桌面环境的安装路径5.1 用VNC完成Rocky的安装流程Rocky Linux在服务器场景里大多是无桌面环境的它的安装器Anaconda在纯文本模式下交互比较痛苦所以还是要借助VNC来完成图形化安装。创建Rocky虚拟机的命令与Ubuntu大同小异只有os-variant和ISO路径不同virt-install \ --name rocky9 \ --memory 2048 \ --vcpus 2 \ --cpu host-passthrough \ --disk path/var/lib/libvirt/images/rocky9.qcow2,size40,formatqcow2,busvirtio \ --network networkdefault,modelvirtio \ --graphics vnc,listen127.0.0.1 \ --os-variant rocky9.0 \ --location /data/iso/Rocky-9.4-x86_64-minimal.iso同样做SSH隧道转发VNC连接后进入Anaconda安装器。Rocky Server安装时有一个步骤和Ubuntu不同它默认会让用户手动选择软件包组如果只是做基础服务选Minimal Install即可不要选带图形界面的Workstation白占资源。Anaconda里还有一步磁盘分区需要手动点击确认否则自动分区功能不会真正执行。这一步选Automatically configured partitioning就行它会自动用逻辑卷管理分配。5.2 Rocky内部的静态IP配置这大概是Rocky踩坑率最高的一环。热词里频繁出现rocky linux设置静态ip不是没道理的很多人在安装界面跳过网络配置等进系统发现网卡状态是DOWN且有概率不自动拉起。最小化安装更狠默认网卡甚至可能没有启用。Rocky 9默认用NetworkManager推荐用nmcli来配静态IP。以默认NAT网络为例虚拟机的网卡一般是ens3或者ens4网关是192.168.122.1。执行以下命令nmcli connection modify ens3 \ ipv4.addresses 192.168.122.50/24 \ ipv4.gateway 192.168.122.1 \ ipv4.dns 223.5.5.5 \ ipv4.method manual nmcli connection up ens3如果你用的不是默认NAT网段先用ss -tunlp或者ip route看看网关是多少千万别照抄。这里有另一个需要注意的操作nmcli connection modify ens3 connection.autoconnect yes这个参数在绝大多数场景下默认就是yes但RHEL家族某些最小化安装里会自动配置成no导致每次重启网卡都起不来。配完静态IP后顺手加这一句能省掉很多不必要的重启排查。5.3 安装qemu-guest-agent让虚拟机变为可管理状态这是个经常被忽略的关键组件。qemu-guest-agent是安装在虚拟机内部的一个守护进程它负责和宿主机上的QEMU通信让virsh能获取虚拟机内部信息、执行优雅关机、冻结文件系统等操作。没有它宿主机执行virsh shutdown时只能模拟硬件电源键虚拟机可能强制断电有了它virsh shutdown会通知虚拟机内部分发systemctl关机相当于正常执行关机命令。Rocky虚拟机里安装dnf install -y qemu-guest-agent systemctl enable --now qemu-guest-agentUbuntu虚拟机里则是apt install -y qemu-guest-agent systemctl enable --now qemu-guest-agent装好之后在宿主机执行virsh domifaddr rocky9就能直接看到虚拟机的IP地址不需要进虚拟机去查。有qemu-guest-agent之后宿主机对虚拟机的掌控力完全是另一个层级。这一步建议在两台虚拟机装完系统后就立刻做掉别等后续运维时再补。6. 虚拟机日常管理与性能调优6.1 快照、克隆与备份的正确姿势KVM配合qcow2镜像格式快照功能是原生支持的。日常做系统变更前我会先在宿主机上拍一个快照virsh snapshot-create-as ubuntu2404 before-upgrade --disk-only --atomic这会为虚拟机磁盘创建一个快照文件后续如果能正常升级可以继续往快照上叠加增量如果升级出问题恢复方式就是virsh snapshot-revert ubuntu2404 before-upgrade克隆虚拟机是另一个高频操作。克隆前先确保源虚拟机处于关机状态否则复制到一半的数据会不一致virsh shutdown ubuntu2404 virt-clone --original ubuntu2404 --name ubuntu2404-test --auto-clone virsh start ubuntu2404-test还有个细节克隆之后虚拟机的网络配置需要进去改因为克隆会导致machine-id和网卡MAC地址变化但系统内的静态IP配置还是旧的会有IP冲突。CentOS/Rocky克隆后deb系统一般会自动重新生成machine-id但IP还得手动改。日常备份则更简单qcow2镜像本质上就是一个文件关机或快照状态下对整个镜像做rsync或cp复制就是一份完整的备份。对生产虚拟机我更推荐用块级备份工具如backupninja来辅助但个人实验环境直接复制文件就够。6.2 不关机动态调整CPU和内存KVM支持在线调整部分资源这在业务高峰期临时扩容时很实用。调整虚拟机CPU数virsh setvcpus ubuntu2404 --maximum 8 --live virsh setvcpus ubuntu2404 --count 8 --live这里有个限制--maximum只能调大不能调小且部分操作系统对CPU热插拔支持不好以Ubuntu 24.04、Rocky 9这些新系统来说基本没问题。调整内存则需要先查看当前配置virsh setmem ubuntu2404 --size 8G --live虚拟机内部执行free -h确认内存变化。需要说明的是这个动态调整只对运行中的实例生效想永久生效还是要编辑虚拟机配置virsh edit ubuntu2404在domain配置里修改memory和vcpu字段或者用virsh setmaxmem之后再setmem保存后重启虚拟机立即生效。6.3 磁盘格式与IO模式的选型选择磁盘格式可以直接用qemu-img查看qemu-img info /var/lib/libvirt/images/ubuntu2404.qcow2qcow2和raw两种格式的对比我已经在实战中验证过多次整理成表格方便直接对照对比项qcow2raw空间占用按需分配稀疏文件省空间预先分配完整大小快照原生支持快照链灵活不支持原生快照压缩加密支持压缩和加密不支持性能接近raw有少量元数据开销极高无额外转换适合场景日常开发、测试、多快照需求数据库等重度IO、极致性能日常运维我全部用qcow2理由很简单灵活性和快照功能带来的收益远大于那点性能损耗。真到了需要极致性能的生产数据库环境更合理的选择是物理机部署或直通硬件而不是在虚拟化层和磁盘格式上较劲。磁盘IO模式上virt-install默认的busvirtio已经是很优选的方案如果觉得IO还有提升余地可以在虚拟机配置里给磁盘加上cachewriteback和iothreads这两个参数在延迟和吞吐之间取得平衡。曾经在Ubuntu虚拟机里压测fio开启writeback缓存后4K随机写性能提升接近三倍。7. 我从KVM部署实战里爬出来的常见坑7.1 虚拟机开机黑屏或VNC连不上VNC连不上通常是监听地址问题。我在前面配置里特意把listen改成了127.0.0.1如果某天你发现VNC无法从外部连接先确认虚拟机配置里的graphics段virsh edit ubuntu2404找到graphics这行看看listen属性是否被设成了0.0.0.0。0.0.0.0虽然能从外部直连但裸奔在网络上极不安全强烈不建议生产环境使用。如果一定要远程访问就采用SSH隧道而不是直接暴露VNC端口。黑屏问题还和显卡驱动有关。Linux安装器用的标准VGA进系统后如果虚拟机分配的显存太小默认16MB桌面系统可能直接黑屏。在虚拟机配置里增加Video RAMvideo model typevirtio/ address typepci domain0x0000 bus0x00 slot0x01 function0x0/ /video纯服务器环境没有桌面需求黑屏通常不影响SSH登录这时候别慌着重装。7.2 宿主机重启后虚拟机没有自动启动这是排障过程中最容易发现的问题宿主机正常重启后所有虚拟机的状态变成shut off必须手动virsh start。这个行为是默认设计解决办法就一条命令virsh autostart ubuntu2404这会创建/etc/libvirt/qemu/autostart目录下的软链接让libvirtd在宿主机开机后自动拉起这台虚拟机。但是要注意autostart只负责启动虚拟机如果虚拟机内部的服务依赖顺序有讲究还是建议用systemd自建service来做更强的编排控制。7.3 磁盘空间悄悄变大删了文件也不回收qcow2这种格式是稀疏文件虚拟机里删除了文件宿主机上的磁盘镜像并不会自动变小。这是新手最容易恐慌的坑明明虚拟机里df显示磁盘占用不到20%宿主机上du盘镜像却占了40GB。如果确认虚拟机不再需要那些已删除数据可以做个压缩virt-sparsify --in-place /var/lib/libvirt/images/ubuntu2404.qcow2这个工具可以把稀疏的未使用块重新变为空洞宿主机上文件大小立刻缩回来。为了更主动地控制空间记得在虚拟机里定期执行fstrim -avfstrim -av7.4 Windows虚拟机在KVM里性能差的常见原因虽然这篇文章的主题是Linux虚拟机但肯定有读者也会在KVM里跑Windows做一些兼容性测试。Windows虚拟机性能差的大概率原因只有一个没装virtio驱动导致磁盘和网卡走的是QEMU的模拟设备性能极差。解决办法是在创建Windows虚拟机时挂载virtio-win驱动镜像virt-install \ --name win11 \ --memory 8192 \ --vcpus 8 \ --disk path/var/lib/libvirt/images/win11.qcow2,size100,formatqcow2,busvirtio \ --disk path/data/iso/virtio-win.iso,devicecdrom \ --network networkdefault,modelvirtio \ --os-variant win11Windows安装时在磁盘选择界面加载virtio驱动装完后设备管理器里所有带黄色感叹号的设备都指向virtio-win盘符安装一遍即可。7.5 嵌套虚拟化虚拟机里面再跑KVM最后一个值得知道的场景是嵌套虚拟化也就是在KVM虚拟机里面再使用KVM常见于学习环境或需要隔离出多级开发环境的情况。要让虚拟机内部能再跑KVM创建时有两点必须注意一是CPU模式必须是host-passthrough这样虚拟机内部才能看到vmx/svm标记--cpu host-passthrough二是需要把CPU的虚拟化特性透传给虚拟机默认情况下KVM会隐藏这些特性。配置为virsh edit vmname找到cpu段确保有以下属性cpu modehost-passthrough checknone feature policyrequire namevmx/ /cpuAMD平台就把vmx换成svm。改完重启虚拟机执行grep -c (vmx|svm) /proc/cpuinfo结果大于0就说明嵌套虚拟化已经开启。我在实际部署KVM的过程中把以上几类坑都踩过一遍基本每次都是查文档、看日志、再验证的节奏。对比起来安装动作本身没多少技巧真正拉开体验差距的是对虚拟化资源规划、网络模式选型和故障排查思路这几个环节的理解深度。希望这篇实战记录能让你的KVM部署少走几段弯路。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →