ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

KVM虚拟化实战:从零到一创建你的第一台虚拟机

KVM虚拟化实战:从零到一创建你的第一台虚拟机 第一次自己“做”KVM最容易出现的一种情况是什么不是命令敲不出来而是你装完之后发现自己根本不知道刚才那几分钟发生了什么。明明输入了一行virt-install结果有的机器起来了有的机器黑屏有的机器报错明明在图形界面里看到一个大窗口却说不清 Host OS、Guest OS、libvirt、QEMU 之间到底是谁在干活。这篇文章会从一次最小化测试出发把 KVM 从环境检查、组件安装、创建虚拟机到功能验收完整跑一遍同时讲清楚那些手册里不会直接告诉你的关系KVM 到底是不是一个软件Guest OS 有什么用剪贴板为什么不能互通全屏为什么缩小不了需要先说明一个问题标题里的“KVM 1.25”并不代表 KVM 有一个叫 1.25 的发行版。更合理的理解是这是你给第一台 KVM 测试虚拟机起的名字类似“我的第 1.25 版镜像”。KVM 作为 Linux 内核自带的虚拟化基础架构本身没有传统意义上的“安装包版本号”。这一点如果不先建立认知很容易在搜索资料时被各种名词带偏。读完这篇文章你能掌握一套完整的 KVM 最小测试流程知道自己创建的 Guest OS 到底是干什么的也能快速定位网络不通、剪贴板不可用、UEFI 固件缺失、全屏无法缩放这四类经典问题。1. 先说结论KVM 解决的是什么问题KVM 的全称是 Kernel-based Virtual Machine中文常翻译为“基于内核的虚拟机”。它解决的问题可以概括成一句话在一台物理 Linux 服务器上以接近原生性能的方式同时运行多台虚拟机。这个“接近原生性能”是关键。过去很多人在 Windows 上熟悉的是 VirtualBox、VMware Workstation 这类软件。它们安装简单开箱即用但本质上是把整个 CPU、内存、磁盘设备通过软件模拟出来性能和隔离性都会打折扣。KVM 走的是另一条路它直接使用 CPU 自带的硬件虚拟化扩展比如 Intel 的 VT-x 和 AMD 的 SVM让虚拟机里的指令可以大部分绕过软件模拟直接在物理 CPU 上执行。所以它的适用场景非常明确服务器虚拟化。在数据中心里用 KVM 给多台业务系统做隔离一台物理机当好几台用。开发测试环境。需要多套不同系统、不同配置环境时用 KVM 快速创建和销毁。给服务器做系统。也就是网络热搜词里提到的“通过 KVM 给服务器做系统”这里的做法是在宿主机上通过virt-install向虚拟机里装操作系统而不是把 ISO 写到 U 盘再去插物理机。学习虚拟化底层原理。对于想理解内核模块、设备模拟、虚拟网络的人来说KVM 是最直接的学习材料。初次接触的人容易误以为 KVM 是个像 VirtualBox 一样独立安装的软件。实际不是。KVM 是一个内核模块它提供的只是 CPU 和内存层面的虚拟化能力用户还得配合 QEMU、libvirt 这些组件才能拼出完整虚拟机。这一点直接决定你后面排错的方向。从材料看当前你关心的重点也都在这些方向Guest OS 是干什么的、KVM 剪贴板互通、KVM 全屏无法缩小、UEFI 固件下载。这四类问题对应着四个模块虚拟化基础、SPICE 客户端工具链、显卡驱动、OVMF 固件。后面都会逐个展开。2. 必须分清楚的概念KVM、QEMU、libvirt、Guest OS先做一个类比。如果一台虚拟机是一辆车KVM 内核模块是发动机。它负责让物理 CPU 的虚拟化扩展真正可用是动力来源。QEMU 是底盘和车身。它模拟出内存条、磁盘、网卡、显卡、USB 控制器这些设备让虚拟机看起来像一台完整电脑。libvirt 是调度中心。它统一管理虚拟机的创建、启动、停止、销毁屏蔽不同虚拟化平台的差异。virt-manager、virt-install、virsh 是方向盘和仪表盘。它们不直接干活而是把用户操作翻译给 libvirt。所以 KVM、QEMU、libvirt 不是三个竞争关系的东西而是三层配合关系。更准确的表述是KVM 负责 CPU/Memory 虚拟化QEMU 负责设备模拟和用户态管理libvirt 负责统一 API 与管理层。用表来梳理更清楚名称类型职责常见误解KVMLinux 内核模块提供硬件辅助虚拟化能力被误认为一个独立虚拟机软件QEMU用户态程序模拟 CPU、内存之外的设备被误认为必须单独打字使用libvirt守护进程API统一管理虚拟机和存储网络被误认为只是图形工具virt-manager图形前端提供 GUI 操作被误认为非装不可virt-install命令行工具从命令行创建虚拟机被误认为只能用于专家Guest OS虚拟机里运行的系统承载真实业务和应用被误认为和宿主机系统有关联Guest OS 是什么字面意思就是“客户机操作系统”也就是跑在虚拟机里的操作系统。它可以是一个精简版 Linux也可以是一套 Windows Server甚至可以是一套网元设备的专用系统。它的作用和一台真实物理服务器上安装的操作系统没有本质区别承载软件、服务和数据。区别只在于它运行在虚拟化层之上可以得到快照、克隆、热迁移这些物理机不具备的能力。用一个实际场景解释你在一台物理服务器上装了 CentOS同时用 KVM 启动了一台 Windows 测试机。那么 CentOS 是 Host OSWindows 就是 Guest OS。你运行virsh list时看到的一个个名字就是一台台 Guest OS 对应的虚拟机实例。为什么要在 KVM 里跑 Guest OS而不是直接往物理机里装多套系统因为物理机只能同时运行一个系统而虚拟化可以在一台物理机上运行多个 Guest OS。这就是服务器整合的基本逻辑。后台系统需要隔离、开发需要环境复现、测试需要快速回滚时Guest OS 都会是比物理机更灵活的选择。概念厘清之后就可以开始动手了。下面的内容默认使用 Ubuntu 22.04 LTS 作为演示系统CentOS/RHEL 系命令也会单独标注。版本细节请以你实际项目为准本文重点演示通用思路。3. 环境准备先确认这台机器能不能跑 KVMKVM 运行有一个硬性前提物理 CPU 必须支持硬件虚拟化扩展。如果 CPU 不支持或者 BIOS/UEFI 里没有开启相关选项后面所有步骤都跑不起来。要避免“安装了半天结果一个虚拟机都启动不了”环境检查阶段务必执行三件事。第一件事查看 CPU 是否支持虚拟化扩展。egrep -c (vmx|svm) /proc/cpuinfo如果输出结果大于 0说明 CPU 支持 Intel VT-x 或 AMD SVM。如果输出是 0就需要进入物理机 BIOS/UEFI找到类似 Intel Virtualization Technology、VT-d、SVM Mode 的选项并开启然后再重新进入系统验证。这里注意在实体机上改 BIOS 属于安全范围内的配置操作改之前先确认这台机器可以被停机和重启避免影响业务。也可以用更直观的命令查看lscpu | grep -i virtualization在 Intel 平台上会看到Virtualization: VT-x在 AMD 平台上会看到Virtualization: AMD-V。第二件事确认内核模块已经加载。lsmod | grep kvm正常输出会包含kvm和kvm_intel或kvm_amd。如果你的内核已经加载了 KVM 模块但没有对应平台模块则说明 CPU 虚拟化可能未被识别。可以尝试手动加载sudo modprobe kvm_intel或者在 AMD 平台上sudo modprobe kvm_amd注意如果宿主环境本身是一台云服务器而且云厂商没有开启嵌套虚拟化那么lsmod | grep kvm可能没有输出。这种环境不代表物理机硬件不支持而是虚拟化能力没有透传给你。此时可以联系云厂商确认是否支持嵌套虚拟化或者在本地物理机上验证。第三件事确认系统内存和磁盘预算。第一次做 KVM 测试时建议宿主机至少有 4 GB 内存和 30 GB 空闲磁盘。这 30 GB 里要预留出系统安装镜像、虚拟磁盘文件、临时快照三部分空间。如果给测试机分配 2 GB 内存给虚拟磁盘 20 GB那么宿主机自身内存至少还要留下 2 GB不然物理机内存耗尽会触发 OOM直接把宿主机搞挂。这是一个生产环境里非常容易踩的坑所有资源都给了虚拟机宿主机反而没有余量了。4. 安装 KVM 全套组件安装 KVM 不是只安装一个包。在 Ubuntu 上推荐安装全套组件包括内核模块、QEMU、后端管理守护进程、创建工具、图形管理工具和 UEFI 固件。sudo apt update sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients virtinst virt-manager ovmf如果你在 CentOS/RHEL 系环境中安装命令类似sudo yum install -y qemu-kvm libvirt virt-install virt-manager edk2-ovmf安装完成后启动 libvirtd 守护进程并设置开机自启sudo systemctl enable --now libvirtd sudo systemctl status libvirtd如果systemctl status显示active (running)说明管理服务已经正常。接下来要把当前用户加入 libvirt 和 kvm 用户组否则每次执行 virsh 命令都需要加 sudo比较麻烦sudo usermod -aG libvirt $(whoami) sudo usermod -aG kvm $(whoami)执行完后必须重新登录一次用户组才会生效。如果不想重新登录可以使用newgrp libvirt临时切换。最后验证安装结果virsh version virsh list --allvirsh version会输出 libvirt 版本信息virsh list --all应该显示空的虚拟机列表比如Id Name State --------------------到这里KVM 的软件栈已经准备好了。值得强调的一点是安装过程本身并不复杂真正复杂的是理解安装的这些包分别承担什么角色。如果你之后看到virsh找不到 socket或者libvirt无法连接大概率是守护进程没有启动或者当前用户没有权限。不要一上来就重装系统。5. 创建第一台 KVM 测试机KVM1.25现在开始创建第一台测试虚拟机。在项目里我给它起的名字是kvm1.25。名字只是一个标识相当于给虚拟机做标签不影响性能也不影响内部系统识别。创建虚拟机有两条主路径命令行virt-install和图形界面virt-manager。生产环境我建议优先掌握命令行因为可以脚本化、可以参数化后续批量创建时效率差距会非常大。先准备一个操作系统 ISO 镜像文件。我把 Ubuntu 22.04 Server 的 ISO 放到了/opt/iso/目录。然后创建一个虚拟磁盘文件。虚拟磁盘格式我推荐用qcow2支持写时复制、快照和稀疏文件默认情况下不会占用全部预分配空间。5.1 用 virt-install 创建虚拟机下面是一份最小可用的创建命令sudo virt-install \ --name kvm1.25 \ --memory 2048 \ --vcpus 2 \ --disk path/var/lib/libvirt/images/kvm1.25.qcow2,size20,formatqcow2 \ --cdrom /opt/iso/ubuntu-22.04.3-live-server-amd64.iso \ --os-variant ubuntu22.04 \ --network networkdefault \ --graphics spice \ --video qxl解释一下每个参数的作用--name kvm1.25虚拟机名称以后执行virsh start kvm1.25、virsh shutdown kvm1.25时都用这个名字。--memory 2048分配给虚拟机的内存大小单位 MB。首次测试 2 GB 够用生产环境按业务评估不要贪多。--vcpus 2分配给虚拟机的 CPU 核数。--disk path...,size20,formatqcow2指定虚拟磁盘路径预分配 20 GB使用 qcow2 格式。--cdrom /opt/iso/...挂载系统安装镜像。--os-variant ubuntu22.04告诉 libvirt 针对该系统做优化。可以通过osinfo-query os查看系统支持列表。--network networkdefault使用 libvirt 默认的 NAT 网络。--graphics spice启用 SPICE 显示协议。这个参数非常重要它决定了你能不能做剪贴板互通、无缝窗口等操作。--video qxl使用 QXL 显卡。QXL 专门为虚拟桌面优化配合 SPICE 能提高图形显示效率。执行命令后virt-install 会进入一个交互界面让你完成系统安装。如果是在有图形界面的宿主机上执行会弹出 virt-viewer 窗口。如果是 SSH 登录的服务器最好在脚本里加上--graphics vnc或者使用 headless 方式。如果当前服务器没有图形环境推荐加两个参数sudo virt-install \ --name kvm1.25 \ --memory 2048 \ --vcpus 2 \ --disk path/var/lib/libvirt/images/kvm1.25.qcow2,size20,formatqcow2 \ --cdrom /opt/iso/ubuntu-22.04.3-live-server-amd64.iso \ --os-variant ubuntu22.04 \ --network networkdefault \ --graphics spice \ --video qxl \ --virt-type kvm \ --noautoconsole加--noautoconsole后virt-install 不会自动弹出图形窗口创建完成即返回命令行。之后你可以用 virt-manager 或者 SPICE 客户端连接过去完成安装。5.2 用 virt-manager 启动图形界面如果宿主机安装了桌面环境直接启动 virt-managervirt-manager然后在 GUI 里点击左上角“新建虚拟机”选择“本地安装介质”选择 ISO再分配内存和 CPU最后指定磁盘即可。virt-manager 本质上调用的是与virt-install相同的底层 API只是把操作界面图形化了。第一次操作我不建议只看 GUI命令行的含义更直观排错时你也更容易理解系统在做什么。5.3 安装 Guest OS 后的基础检查系统安装完成后先不要急着装业务先做三个基础检查virsh list --all virsh dominfo kvm1.25 virsh dumpxml kvm1.25 | grep -E (memory|vcpu|mac address)如果virsh list --all能列出kvm1.25并且状态为running说明虚拟机从 KVM 角度已经创建成功。接下来尝试从宿主机 ping 虚拟机 IP或者通过 SSH 登录虚拟机。如果你使用的默认 NAT 网络虚拟机通常会自动获取 192.168.122.x 网段 IP。6. 运行结果与效果验证创建虚拟机只是第一步我们需要验证这台测试机是否真的可用。我建议按下面四个层面逐项验收。第一层面libvirt 状态验证。virsh list --all virsh dominfo kvm1.25预期输出中有State: running、CPU(s): 2、Max memory: 2097152 KiB等信息。若状态为shut off需要手动启动virsh start kvm1.25第二层面Guest OS 网络验证。在虚拟机内执行ip addr show ping -c 4 8.8.8.8如果外网通说明默认 NAT 网络工作正常。如果内网能通外网不通通常是因为宿主机的iptables转发规则还没有生效或者是内核ip_forward未开启。可以临时打开转发sudo sysctl -w net.ipv4.ip_forward1第三层面CPU 和内存资源验证。在宿主机上执行virsh vcpupin kvm1.25 virsh vcpuinfo kvm1.25在 Guest OS 里执行lscpu free -h这里的核心判断标准是Guest OS 看到的 CPU 数和内存数是否与virt-install分配的参数一致。如果不一致很可能是 virtio 驱动没加载完整或者你没有重启 Guest OS。第四层面快照与回滚验证。测试虚拟机最核心的价值之一就是可以随便折腾、出了事直接回滚。用快照测试一下virsh snapshot-create-as kvm1.25 --name after-install virsh snapshot-list kvm1.25之后再在虚拟机里改坏配置执行virsh snapshot-revert kvm1.25 --snapshotname after-install这一步能直接证明 KVM 的快照能力是可靠的也是后续所有实验的安全兜底。每次验收都要有输出对比不要只看命令“没报错”就认为成功。比如你运行virsh list就得确认列出的是kvm1.25而不是其他残留实例。你运行free -h就得确认 2G 内存确实被识别。实践中的“成功”必须落到可观察的指标上否则就等于没验证。7. 常见问题与排查思路新手测试 KVM 时最容易遇到下面四类问题。每一类我都会给出现象、原因、排查方式和解决方案。问题现象可能原因排查方式解决方案虚拟机启动失败提示/dev/kvm不存在CPU 虚拟化未开启或宿主机不支持执行ls -l /dev/kvm用lscpu查看虚拟化标志进入 BIOS 开启 VT-x/AMD-V或确认云厂商支持嵌套虚拟化virsh list无法连接 libvirt socketlibvirtd 未启动或当前用户不在 libvirt 组执行systemctl status libvirtd执行groups查看用户组启动 libvirtd将用户加入 libvirt 组后重新登录剪贴板无法与 Guest OS 互通没有安装 SPICE 客户端工具或显卡驱动未安装在 Guest OS 中检查 spice-vdagent 进程是否存在安装并启动 spice-vdagentKVM 虚拟机全屏后无法缩小图形驱动和窗口管理器集成缺失查看是否存在 QXL 渲染异常安装 qemu-guest-agent 和 spice-vdagent切换 virtio 显卡需要 UEFI 启动但找不到 UEFI 固件宿主机未安装 OVMF 固件包检查/usr/share/OVMF/目录Ubuntu 安装 ovmfCentOS 安装 edk2-ovmf虚拟机可以 PING 通但外网不通宿主机未开启 IP 转发或 iptables 规则异常执行sysctl net.ipv4.ip_forward开启 ip_forward并确认 NAT 规则下面详细展开三个最容易困惑的点。7.1 剪贴板互通所谓“KVM 内外剪贴板互通”指的是在 virt-manager 打开的虚拟机窗口里把宿主机上的文本复制粘贴到 Guest OS 里。很多人以为这应该默认可用实际不是。剪贴板互通依赖的是 SPICE 协议下的主机与客户机共享通道。Guest OS 里必须安装spice-vdagent宿主机端要安装spice-vdagent和virgl等客户端库。在 Ubuntu Guest 中可以这样安装sudo apt install -y spice-vdagent systemctl start spice-vdagent安装后重新登录 Guest OS 桌面剪贴板互通才会生效。对于纯命令行服务器其实不需要剪贴板互通直接用 SSH 即可。也就是说这个功能主要面向桌面虚拟化场景服务器场景可以关闭 SPICE 以减少资源开销。7.2 全屏无法缩小“KVM 链接服务器全屏无法缩小”这个热搜词通常指的是使用 virt-manager 或 virt-viewer 连接远程虚拟机时窗口切到全屏后无法退出或者界面被强制拉伸鼠标还被困在虚拟机里。一般原因有两个。第一Guest OS 没有安装增强驱动分辨率无法动态跟随窗口调整。第二SPICE 的 attention 键被占用导致全屏快捷键无效。KVM 下全屏切换的默认快捷键是CtrlAltP但如果你之前设置的是抓取鼠标热键比如CtrlAltG两者会出现冲突。解决方法是安装增强组件。sudo apt install -y spice-vdagent qemu-guest-agent在 virt-manager 菜单里找到“查看” - “缩放显示模式”改为“总是缩放”。如果还是无法缩小可以用快捷键切换全屏状态或执行virsh send-key向 Guest 发送键值组合。7.3 UEFI 固件缺失KVM 默认使用 SeaBIOS 引导但有些操作系统要求 UEFI 启动比如部分 Windows Server 版本或者镜像集成了安全引导的系统。如果创建虚拟机时指定了--boot uefi宿主机却没有安装 OVMF 固件virt-install 就会报如下错误ERROR Unable to find UEFI firmware解决方案是安装 OVMF。Ubuntu 上sudo apt install -y ovmfCentOS/RHEL 上sudo yum install -y edk2-ovmf安装完成后可以在创建虚拟机时显式指定 UEFI 固件路径sudo virt-install \ --name kvm1.25 \ --memory 2048 \ --vcpus 2 \ --disk path/var/lib/libvirt/images/kvm1.25-uefi.qcow2,size20,formatqcow2 \ --cdrom /opt/iso/ubuntu-22.04.3-live-server-amd64.iso \ --os-variant ubuntu22.04 \ --boot uefi注意UEFI 和 BIOS 引导模式会影响磁盘分区表。同一块虚拟磁盘不要在两种引导模式之间反复切换否则容易引导失败。8. 最佳实践与生产环境建议测试跑通了接下来要考虑怎么把它用到真实项目中。下面是几条从实践里沉淀出来的建议。第一虚拟磁盘一律用 qcow2不要用 raw。qcow2 支持快照、压缩、稀疏存储raw 虽然性能略高一点但维护成本高很多。如果追求磁盘性能可以先创建 raw 磁盘再用qemu-img convert转成 qcow2 结合 IO 调优参数而不是在初始化时直接裸用 raw。qemu-img create -f qcow2 /var/lib/libvirt/images/kvm1.25.qcow2 20G第二内存分配要留余量。宿主机内存必须预留至少 2 GB 给系统内核和 libvirtd 运行。贸然把所有内存都分配给虚拟机可能导致宿主机 OOM直接杀掉物理机上所有进程包括你正在远程连接的那个 SSH 会话。这在生产环境里是极其严重的事故。第三网络模式按场景选择。默认 NAT 模式只适合临时测试因为外部无法直接访问虚拟机。生产环境如果要让虚拟机对外提供业务建议用桥接模式让虚拟机直接接入物理网络。桥接模式的配置在 libvirt 中一般通过网桥br0实现interface typebridge source bridgebr0/ model typevirtio/ /interface但改桥接前请一定确认物理网卡和交换机的配置允许否则会导致宿主机断网无法远程恢复。第四在安全边界上要谨慎。KVM 是根权限级的虚拟化平台操作时默认使用普通用户加sudo即可不建议长期用 root 执行所有命令。对于生产虚拟机尽量不要执行virsh destroy这种强制断电操作先尝试virsh shutdown让它优雅关闭。强制关闭有可能导致文件系统损坏。第五快照是很强的工具但不要依赖单点。虚拟机快照不能替代备份。快照文件通常和原始磁盘在同一个存储上如果存储盘故障快照也一起丢失。生产环境中建议将关键虚拟机定期导出为离线镜像放到独立备份存储上qemu-img convert -O qcow2 /var/lib/libvirt/images/kvm1.25.qcow2 /backup/kvm1.25-backup.qcow2第六版本兼容问题要提前测试。KVM、QEMU、libvirt 的版本组合非常多不同发行版自带的 KVM 内核补丁也不一样。在实际项目中引入一套虚拟机模板时先在测试环境完整跑一遍创建、启动、快照、迁移再复制到生产环境使用。这是一种低成本、高回报的工程习惯。9. 总结与后续学习方向从零到一创建一台 KVM 虚拟机这个流程本身不复杂。真正有价值的是你理解了整套架构之间的关系KVM 是内核模块QEMU 负责设备模拟libvirt 负责管理virt-install 是入口工具。只有当这些概念在脑中标定清楚你才会在出现问题时知道去查哪个日志、看哪个进程、改哪个配置。这篇文章里你已经完成了确认 CPU 是否支持硬件虚拟化。安装完整 KVM 软件栈。用virt-install创建第一台kvm1.25测试机。通过virsh命令验证虚拟机状态。解决了剪贴板互通、全屏缩放、UEFI 固件等常见问题。拿到了几条针对生产环境的工程建议。下一步建议从两个方向继续提升。一是深入网络层学习如何创建自定义网桥、vLAN 隔离和 NAT 转发规则这是从“会建虚拟机”到“会做服务器虚拟化组网”的必由之路。二是学习自动化用virt-install --unattended或者 cloud-init 批量部署 Guest OS解决团队里反复手工安装系统的效率问题。最后留一个建议第一次测试 KVM 时不要急着调度太多资源。先把一台 2 GB 内存、20 GB 磁盘的小机器完整跑通再逐步加 CPU、加内存、接桥接网络。KVM 本身是个非常稳定的平台大多数问题上不是它不行而是使用者在第一次配置时把宿主机资源榨干把网络配置改错然后还回不去。从最小案例开始你的第一台 KVM 测试机会比预想中顺利很多。
返回列表