使用virt-manager图形化创建和管理KVM虚拟机

676 阅读25分钟

虚拟机是日常开发中比较常见的工具之一,无论是搭建本地集群,还是测试部分系统等,虚拟机都非常实用。在Windows上我们常用VMware虚拟机,但是在Linux上VMware兼容性仍然存在问题,且常常不支持较新的内核。此外,Virtual Box也是一个开源跨平台的虚拟机软件,使用更加简单,不过在性能上仍然存在瓶颈。

当然,在Linux上我们也常常听说KVM(Kernel-based Virtual Machine)虚拟化方案,这是几乎所有云厂商都在使用的虚拟化方案,绝大多数版本的Linux内核都已经集成了KVM模块支持,且作为内核态的虚拟化工具,KVM比起其它虚拟机有着更好的性能。

今天我们就主要讨论一下如何在Linux上安装KVM虚拟化所需的相关软件,以及如何创建管理KVM虚拟机。

1,安装相关软件

首先我们需确保:

  • 已开启Intel VT或AMD SVM虚拟化功能,可在主板BIOS中设置
  • 系统已加载KVM模块

可使用下列命令检查:

lsmod | grep kvm

如图:

image-20251026153108395

只要出现了kvmkvm_amd这两者即可,对于Intel处理器则应当是kvmkvm_intel两个。

若未显示,可使用modprobe手动载入模块或配置开机自动加载这两个模块。如果无这两个模块,可自行编译内核,配置其中启用这两个模块。具体方法不再赘述,默认情况下KVM模块都会包含且自动加载。

然后,使用下列命令安装所需的软件:

# Debian/Ubuntu/Linux Mint
# 安装
sudo apt install virt-manager bridge-utils virtiofsd
# 配置用户组(重启系统或重新连接服务器后才会生效)
sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER

我们安装的软件主要如下:

  • virt-manager 一个libvirt的图形操作界面,即图形化的KVM虚拟机管理客户端,在安装该客户端软件包时就会自动安装关于KVM技术栈的相关核心组件及其依赖,包括但不限于:
    • qemu-system-x86qemu-utils 主要是QEMU(Quick Emulator)软件及其实用工具,这是一个开源的通用机器模拟器和虚拟化软件
    • libvirt-daemonlibvirt-clientslibvirt虚拟机管理框架客户端和服务端守护进程,提供了统一的虚拟机操作接口包括创建、启动、停止、配置虚拟机
    • ovmf KVM虚拟机的UEFI固件支持
    • swtpm-tools 支持添加虚拟的TPM可信计算设备,在安装Windows虚拟机时需要
  • bridge-utils 网络桥接工具集
  • virtiofsd 用于将宿主机上的目录通过virtio-fs协议暴露给虚拟机,实现宿主机和虚拟机共享文件

在这里我们就可以来详细了解一下KVM虚拟化方案的组成,可见我们平时常说的KVM虚拟机并非是像VMware那样一个完整的软件,而是由多个组件构成:

  • KVM:只是一个Linux内核模块,提供硬件辅助虚拟化能力,但是KVM不能单独工作,也不具备创建虚拟机等功能,它只处理CPU和内存的虚拟化
  • QEMU:一个开源的机器模拟器和虚拟机监视器(VMM),能够模拟完整的计算机硬件,并在KVM支持下实现硬件加速的虚拟化。既然KVM模块不能创建和运行单独的虚拟机,因此就需要使用QEMU这种客户端来进行,该客户端能够模拟完整的硬件(包括网络、磁盘、网卡等),且具备最基本的虚拟机管理功能,此外QEMU可以将虚拟机的虚拟化交给KVM完成,这样使用QEMU + KVM,就能够创建并运行一个最基本但完整的虚拟机了
  • libvirt:一个虚拟化管理工具集和API,它作为一个守护进程运行,提供了更加高级、统一的接口来管理虚拟机。上面提到了QEMU + KVM虽然可以创建一个完整的虚拟机,但是缺乏很多高级功能(例如虚拟机配置持久化、生命周期管理等),此外QEMU原生的接口比较复杂繁琐,因此就可以使用libvirt这样的高级工具,实现更加便捷的虚拟机管理功能,且支持更多高级功能,libvirt工具提供了简单的命令行用法可一键创建虚拟机,而上述安装的virt-manager就是一个图形化客户端,让我们使用可视化方式调用libvirt工具创建管理虚拟机

所以,大家平时常说的KVM虚拟化,绝大多数指的是KVM内核模块 + QEMU工具 + libvirt上层客户端所构成的完整虚拟化工具链。

2,libvirt的连接与配置

创建虚拟机之前,可以认识一下libvirt的配置,该配置可理解为虚拟机工具的全局配置,包含了网络和存储位置等。

打开virt-manager,中文环境下显示的是虚拟系统管理器如下:

image-20251026155601367

界面如下:

image-20251026155659690

默认情况下,会自动连接我们本地的libvirt进程,上述在安装过程中,已经安装了libvirt-daemon-systemlibvirt-clients软件包,通常libvirt守护进程就会自动启动且后续会开机自启动。

如果显示连接失败,则尝试手动检查和启动libvirt守护进程:

# 检查状态
sudo service libvirtd status

# 启动进程
sudo service libvirtd start

virt-manager连接上libvirt守护进程后,就可以操作和管理我们本地的虚拟机了!此外,该客户端还支持连接远程服务器上的libvirt进程(例如采用qemu+ssh连接),这里就不再赘述了,大家可自行查阅和尝试。

首先,右键我们的本地连接-详情可以查看和配置本地的libvirt守护进程配置:

Snipaste_2025-10-26_15-02-27

界面如下:

image-20251026160304459

主要是网络和存储两大方面配置。

(1) NAT网络配置

在网络一栏我们可以创建虚拟网卡,创建的虚拟网卡支持多种模式,平时在本地开发调试时,我们使用NAT模式即可。虚拟网络默认就会包含一个名为default的NAT虚拟网卡,我们一般直接使用该网卡即可,无需再手动创建。大家在系统终端使用ip addr命令,也可以看到一个虚拟的网络就是这里的虚拟网卡。

若要创建网卡,则可点击这里的+按钮:

image-20251026160547051

如下:

image-20251026160841729

(2) 存储池配置

存储池通常是KVM虚拟机存放数据的地方,主要存放的是下列内容:

  • 系统的安装ISO镜像
  • 虚拟机的虚拟硬盘文件
  • UEFI固件配置
  • ...

默认的存储池对应的目录是/var/lib/libvirt/images如下:

image-20251026161016780

我们也可以自定义一个目录作为存储池,点击+新建:

image-20251026161123464

需要注意的是,目标路径需选择一个不位于任何一个用户目录中的一个路径,且需要确保该路径有读取权限,否则可能导致创建虚拟机时无法读取安装ISO文件。

(3) 启用XML编辑功能

虽然后续大多数配置可在图形化界面完成,但个别配置仍需要编辑XML配置文件进行。默认情况下virt-manager不允许直接编辑XML配置,因此建议启用“XML编辑功能”,在virt-manager主界面编辑-Preferences进入首选项:

Snipaste_2025-10-26_15-01-36

在常规选项卡中,勾选启用XML编辑即可:

Snipaste_2025-10-26_15-01-18

(4) 通过SSH连接远程机器的libvirt

virt-manager除了能够管理本地的KVM虚拟机之外,还支持使用SSH连接远程服务器上的libvirt进程,然后直接在客户端操作远程虚拟机。

远程服务器上需完成下列前提条件:

  • 已安装KVM相关软件
  • 已配置SSH密钥对免密登录

这里就不再赘述如何配置免密登录了。

在本机打开virt-manager,添加连接即可:

image-20260111145558632

勾选通过SSH连接到远程主机,并填写相关用户名和远程主机地址:

image-20260111145650577

如果你的远程主机SSH端口不是默认的22,那么则需要使用自定义URI连接:

image-20260111145838902

连接URI填写如下格式:

# URI格式:qemu+ssh://用户名@远程主机地址:端口/system
qemu+ssh://user@host:port/system

3,创建虚拟机

现在,就可以创建虚拟机了。

(1) 复制ISO安装文件到存储池

我们使用默认的存储池位置/var/lib/libvirt/images即可,这里我们复制了个Debian 13安装镜像进去,然后在libvirt的配置中存储池刷新即可看到:

image-20251026161745042

(2) 创建虚拟机并选择系统镜像

virt-manager主界面选择我们本地的libvirt连接后点击左上角按钮可新建虚拟机:

Snipaste_2025-10-26_14-44-28

然后在新建页面选择本地ISO文件:

Snipaste_2025-10-26_14-44-46

选择我们存储池里的ISO文件:

Snipaste_2025-10-26_14-45-13

Snipaste_2025-10-26_14-45-37

然后记得在下面搜索选择你安装的操作系统名称,建议取消“自动从安装介质/源检测”的勾选:

Snipaste_2025-10-26_14-46-05

若找不到你的发行版,则搜索并选择Generic并选择任意一个Generic xxx即可。

(3) 分配CPU和内存

然后指定虚拟机内存与处理器核心数:

Snipaste_2025-10-26_14-46-28

(4) 创建虚拟硬盘

创建虚拟硬盘:

Snipaste_2025-10-26_14-46-44

需要注意的是:默认情况下创建的虚拟硬盘文件存放在ISO安装镜像所在的那个存储池中,若想要自定义虚拟硬盘文件存储位置统一管理,则可以在当前界面选中选择或创建自定义存储这一选项并点击管理按钮:

然后可选中你自己创建的存储池,并在右侧点击+按钮新建虚拟磁盘文件:

填写虚拟磁盘名称、格式、大小信息并确定:

此时,就在我们自定义的存储池中完成了虚拟磁盘文件创建,这时选中你创建的虚拟磁盘文件,并点击Choose Volume按钮确认选择即可:

到此,虚拟机就能够使用我们在自定义位置创建的虚拟磁盘文件。

(5) 安装前的虚拟机配置

建议最后一步勾选在安装前自定义配置选项:

Snipaste_2025-10-26_14-47-06

此时,我们就进入了修改虚拟机详细硬件配置界面,大家可自行修改,大多数配置在虚拟机安装后也可以修改。后续章节将具体说明一些重要配置。

image-20251201150506213

(6) 安装虚拟机操作系统

修改完成配置后,点左上角开始安装即可:

image-20251201152704155

然后就进入了虚拟机系统安装界面,完成后续安装程序的步骤即可:

Snipaste_2025-10-26_14-50-58

按下键盘左侧Ctrl + Alt组合键和强制从虚拟机中拿出鼠标指针。

若分辨率问题显示文字较小,可在查看-缩放显示中设定缩放为总是

image-20251201153004381

建议安装Linux系统时勾选“安装SSH工具”,通过SSH连接虚拟机比起直接在虚拟机中操作通常更加方便。

虚拟机运行时,即使关闭虚拟机窗口,甚至关闭virt-manager,虚拟机仍然会在后台运行,虚拟机实际上是由libvirtd守护进程管理。

4,虚拟机重要配置

在上述安装之前,通过勾选在安装前自定义配置选项可进入虚拟机详细配置进行设置。此外,对于已存在的虚拟机,也可以打开后点击左上角显示虚拟机详情图标按钮进入虚拟机配置进行修改:

image-20260107143242879

接下来,将介绍一下常见的重要虚拟机配置。

(1) 启动模式

概况一栏,通过指定固件指定启动模式,建议指定为UEFI模式,需要注意的是固件只能在安装虚拟机之前指定,已存在的虚拟机不能直接在该页面修改固件:

image-20251201150705970

此外,这个页面还有芯片组配置,一般我们选择Q35即可,这是最新的虚拟化芯片组,如果不是就注意设置为这个。

该页面修改后记得点击右下角Apply按钮保存配置,后续配置也一样。

(2) Secure Boot配置

virt-manager中,并没有明确的开关用于开启或关闭Secure Boot(安全启动),而是通过选择不同的UEFI固件进而实现启用还是禁用安全启动。

① 安装系统之前指定

仍然是在概况 - 固件这里,选择不同的UEFI固件即可实现是否启用Secure Boot:

image-20251228155744707

大家根据实际情况,选择对应的固件,例如选择.../OVMF_CODE.secboot.fd,那么该虚拟机就会启用Secure Boot。

② 已存在的虚拟机

不过,对于部分系统无法在该页面选择该固件,或者对于已安装系统想要开启/关闭Secure Boot,我们可通过手动编辑XML配置方式实现。

概况栏,点击右侧XML标签:

image-20251228154808390

找到<os>部分,这里就是安全启动主要相关配置:

image-20251228154851698

在开启或关闭Secure Boot时,仅需修改名称为enrolled-keyssecure-boot这两个<feature>标签的enabled属性即可,其余相关配置会自动生成,这两个feature的意义如下:

  • secure-boot 配置开启或关闭Secure Boot
  • enrolled-keys 配置是否自动安装Secure Boot密钥

一般这两个配置要么一起启用,要么一起禁用。

在修改之前,首先需删除<os>标签中的<loader><nvram>这两个配置,如下图位置:

image-20260107144214481

然后,就可以配置开启或关闭Secure Boot了。

如果你要开启Secure Boot,那么就修改<os>中的<firmware>中名为enrolled-keyssecure-boot这两个<feature>标签的enabled属性为yes,同时在features标签中加入<smm state="on"/>这一行配置开启smm,如下:

<os firmware="efi">
	<!-- 省略其他 -->
	<firmware>
		<feature enabled="yes" name="enrolled-keys"/>
		<feature enabled="yes" name="secure-boot"/>
	</firmware>
	<!-- 省略其他 -->
</os>
<features>
	<!-- 省略其他 -->
	<smm state="on"/>
	<!-- 省略其他 -->
</features>

最终,我这里配置如下图所示:

image-20260107145345530

反之,如果你要关闭Secure Boot,那么就修改<os>中的<firmware>中名为enrolled-keyssecure-boot这两个<feature>标签的enabled属性为no即可:

<os firmware="efi">
	<!-- 省略其它 -->
	<firmware>
		<feature enabled="no" name="enrolled-keys"/>
		<feature enabled="no" name="secure-boot"/>
	</firmware>
	<!-- 省略其它 -->
</os>

我这里最终如下图所示:

image-20260107145201725

完成修改后记得点击右下角Apply按钮保存配置,在保存配置后大家会发现<loader><nvram>这两个配置会被自动生成。

根据上述方法修改配置后,同时还需执行下列命令重置虚拟机的nvram才能使得Secure Boot配置生效:

virsh start 虚拟机名 --reset-nvram

此时,会重置该虚拟机nvram,同时虚拟机也会开机。

(3) CPU核心数与拓扑

在前面创建虚拟机时,我们已经配置过CPU核心数了,不过在安装之前或后续设置中,我们仍然可以修改,并配置更详细的处理器拓扑。

CPU数这一栏,我们可展开拓扑,并勾选手动设置CPU拓扑

image-20251228161601328

这三个字段意义如下:

  • 套接字:即配置有多少个虚拟CPU插槽
  • 核心:配置给虚拟机分配多少个物理CPU核心
  • 线程:配置该虚拟机处理器中每个物理CPU核心对应多少个逻辑处理器

最终,分配给虚拟机的总CPU核心数就是这三个值相乘。

这三个值的实际意义,我们可以对应实际生活中电脑处理器来理解:

  • 套接字就是插槽,一般我们个人电脑只有一个CPU插槽(也就是只能安装一个CPU),而很多服务器主板可安装两个CPU,即有两个插槽
  • 核心和线程其实就是处理器的物理核心和逻辑核心。例如AMD锐龙处理器通常都是1个物理核心包含2个逻辑核心(常说的大核),以R7 9700X为例,有8物理核心,那么一共就有16个逻辑核心;Intel处理器从12代起采用大小核架构,即1大核包含2逻辑核心,而1小核只包含1个逻辑核心,那么以i7 12700为例,有8大核4小核,因此就一共有20个逻辑核心,在操作系统层面,识别到的处理器核心数实际上是总逻辑核心数量

(4) 显示和3D加速

KVM虚拟机支持VNC和Spice两种显示协议:

  • VNC:通用、轻量级的远程桌面协议,最初为跨平台远程控制设计,以“像素推送”方式工作:将图形界面以位图形式传输,对图形内容本身无语义理解
  • SPICE:专为虚拟化环境优化,具备语义感知能力,能区分图形元素(如视频、3D、鼠标、剪贴板等),并针对性优化,目标是提供接近本地体验的远程桌面性能,尤其适合桌面虚拟化

Spice协议比起VNC更新,且支持更多高级特性,推荐大家选择Spice协议,在显示协议一栏,选择类型Spice服务器即可:

image-20251201151120417

这里讲解一下监听类型配置,Spice显示协议是支持通过网络(TCP协议)远程访问的,也就是说我们可以远程通过Spice协议显示并操作KVM虚拟机,而该配置主要影响该虚拟机的Spice协议是否暴露到网络环境:

  • :不绑定到任何端口,仅能本地通过工具(例如virt-manager自己)访问
  • 地址:绑定到某个地址,接受通过网络方式访问,可选择仅本地(绑定至127.0.0.1)、指定地址或监听所有地址

如果仅仅是在本地使用虚拟机,则建议选择,若需要使用Spice协议远程访问,则建议选择地址并配置合适的地址端口。

此外,我们还需要配置虚拟显卡驱动,在显卡这一栏可选择型号

image-20251201151827945

一般来说,我们通常只会选择下列两个型号:

  • Virtio:是Virtio标准的一部分,目标是提供标准化、轻量、跨平台的虚拟GPU接口,支持2D/3D图形加速,更符合现代虚拟化趋势
  • QXL:为SPICE远程桌面协议量身打造,专用于提供高性能的2D图形加速,强调与SPICE客户端的协同优化

可见两个型号驱动的适用场景不同:

  • 仅需简单2D图形显示、命令行无图形界面或对兼容性有要求场景:选择QXL即可
  • 需3D图形显示加速:需选择Virtio且勾选3D加速

这里,建议大家选择Virtio并勾选3D加速选项

image-20251201152211664

需要注意的是,勾选3D加速后,我们还需回到显示协议配置,勾选OpenGL选项:

image-20251201152330312

部分系统安装过程中,对Virtio 3D加速兼容性存在问题,可能导致黑屏或断开连接。可在安装系统阶段使用QXL,后续安装完成后改用Virtio并采用3D加速。

(5) Windows虚拟机TPM

需要注意的是,如果你要安装Windows 11的虚拟机,则还需要在安装之前配置TPM设备,一般情况下只要你选择了Windows 11系统,就会自动添加TPM设备,我们仅需设定一下TPM版本即可:

image-20251209203541635

如果没有找到TPM设备,则点击左下角添加硬件按钮:

image-20251103133941314

添加虚拟的TPM设备即可,选择CRB型号,2.0版本:

image-20251103134138841

5,挂载宿主机目录至虚拟机

在KVM中,要实现将宿主机目录挂载到虚拟机,达到宿主机和虚拟机文件共享的目的,我们通过virtiofs驱动挂载共享文件系统即可,该驱动从Linux 5.4开始就集成在内核里面了,因此只要你的KVM虚拟机中安装的系统内核版本是大于5.4的,且宿主机安装了virtiofsd软件包(前面已经安装),我们就无需再配置其它软件或模块。

(1) 添加共享文件系统

我们首先需要在宿主机上创建一个目录作为共享目录,该目录会暴露到虚拟机中,我这里以/data/share/kvm为例:

# 宿主机上创建目录
sudo mkdir -p /data/share/kvm
# 设定权限(可选,这里方便起见设为777,可能不安全)
sudo chmod 777 /data/share/kvm

然后打开虚拟机详细设置,我们首先需要打开内存共享功能,点击左侧内存一栏,勾选Enable shared memory一项,然后记得点击右下角Apply按钮保存配置:

image-20251124140220613

然后点击左下角添加硬件按钮:

image-20251124140343106

选择左侧文件系统,界面如下:

image-20251124135051497

首先设定宿主机共享目录,确保驱动程序一栏选择的是virtiofs,然后点击源路径这一项的浏览按钮:

image-20251124134951264

在弹出的窗口点击右下侧本地浏览按钮,选择我们上面新建的共享目录:

image-20251124134901549

然后设定虚拟文件系统名称,可自定义一个,在目标路径这一栏填写:

image-20251124135235956

需要注意的是,这里虽然显示的是目标路径,但它并不代表虚拟机内的挂载路径,而仅仅是暴露给虚拟机内部的虚拟文件系统名称,我这里自定义名称为share-data了。

最后点击右下角完成按钮,共享文件系统添加完成。

(2) 虚拟机内挂载共享文件系统

启动虚拟机,假设我们要将共享文件系统挂载到虚拟机的/mnt/data下,执行下列命令即可:

# 新建文件夹
sudo mkdir -p /mnt/data
# 挂载virtiofs文件系统
# 命令:mount -t virtiofs <虚拟文件系统名称> <挂载到的路径>
sudo mount -t virtiofs share-data /mnt/data

若没有任何输出说明挂载成功,我们也可以在宿主机放一个文件到共享目录,然后在虚拟机里面查看挂载的目录里面是否同步能看到:

image-20251124140444496

到此,共享目录挂载完成。

(3) 虚拟机自动挂载

可见共享目录需要我们手动通过mount命令挂载,那么如何实现虚拟机开机自动挂载呢?

我们可能会想到增加/etc/fstab配置,但事实上对于virtiofs是不推荐的,因为该配置加载时机非常早,通常在virtiofs之前加载,因此可能会导致找不到设备错误。

因此,我们需要通过编写Systemd Mount文件实现,在KVM虚拟机/etc/systemd/system目录下创建mnt-data.mount文件,并在文件中编写如下配置:

[Unit]
After=systemd-modules-load.service

[Mount]
What=share-data
Where=/mnt/data
Type=virtiofs
Options=defaults

[Install]
WantedBy=multi-user.target

上述配置要点:

  • 文件名必须与挂载的路径对应,我这里将共享目录挂载至了虚拟机的/mnt/data目录下,那么配置文件名就必须是mnt-data.mount,即挂载的路径去掉开头的/,然后把其它的/替换为-作为配置文件名才行,且扩展名是mount而不是service
  • 配置文件中的What字段填写虚拟文件系统名称,也就是我们在virt-manager中给虚拟机添加文件系统时定义的虚拟文件系统名称
  • 配置文件中的Where字段填写虚拟机中挂载共享文件系统的路径即可

然后,执行下列命令启用开机自动挂载:

sudo systemctl daemon-reload
sudo systemctl enable --now mnt-data.mount

到此,虚拟机开机自动挂载共享文件系统配置完成。

6,虚拟机增强驱动

通过上述步骤,我们虽然完成了虚拟机安装配置,但是体验仍然较为原始。不过,我们仍然可以安装相关的Spice或Virtio相关增强驱动,实现更好的虚拟机体验,例如支持:

  • 宿主及和虚拟机共享剪切板
  • 文件拖拽
  • 减少卡顿
  • ...

下面,将介绍如何在Linux和Windows的KVM虚拟机中安装增强驱动。不过,必须满足下列前提条件:

  • 虚拟机使用Spice显示协议
  • 虚拟机使用QXL或Virtio显示驱动

(1) Linux虚拟机

在Linux虚拟机中通常使用spice-vdagent驱动,即SPICE Virtual Desktop Agent,是一款虚拟机内部增强工具。

安装该驱动非常简单,只需在虚拟机内部直接使用包管理器安装即可:

# 安装(Debian/Ubuntu/Linux Mint/Pop!_OS)
sudo apt install spice-vdagent

# 启动并设置开机自启
sudo systemctl enable --now spice-vdagentd

然后,重启虚拟机,就能够发现可共享剪切板、文件拖拽等操作了!

如果虚拟机桌面使用的是Wayland会话,则部分桌面可能出现兼容性问题,导致剪切板共享失效,建议换回X11会话。

(2) Windows虚拟机

① 安装virtio-win驱动

对于Windows虚拟机,通常在虚拟机内安装virtio-win驱动程序以获得更好的兼容性,该驱动程序由Fedora维护,可在该页面查看和下载:传送门

image-20260109143512728

下载这个Latest virtio-win-guest-tools.exe即可,得到一个exe安装包,不过现在我们无法将其直接放入Windows虚拟机,因此可以把这个安装包打包为iso文件以光驱形式挂载进虚拟机。(或者,直接在虚拟机里面下载该exe文件)

使用下列命令在Linux宿主机上打包这个安装包文件为iso文件:

# 命令格式:
# genisoimage [一些参数] -input-charset <字符集> -o <输出ISO文件路径> <打包文件/目录>
genisoimage -J -r -allow-limited-size -input-charset utf-8 -o virtio-win.iso ./virtio-win-guest-tools.exe

得到如下:

image-20260109144453893

然后,在Windows虚拟机中添加一个光驱(如果没有):

image-20260109144627618

选择文件时,点击本地浏览即可:

image-20260109144649135

然后开启虚拟机,打开资源管理器进入光驱安装即可。

② 安装Winfsp支持挂载共享文件系统

前面我们也探究了如何挂载宿主机目录到虚拟机,但是对于Windows无法使用mount命令挂载virtiofs文件系统,因此除了安装上述virtio-win驱动之外,还需要在虚拟机安装Winfsp这个FUSE驱动才能够实现挂载。

首先,在虚拟机下载并安装Winfsp这个组件:传送门

image-20260109145130600

安装完成后,重启虚拟机。

然后,在虚拟机打开服务管理,找到VirtIO-FS Service右键属性,启动服务并设定为自动启动即可:

image-20260109145333923

image-20260109145424787

最后,就可以看到盘符为Z的共享文件系统了。

7,本地NAT网络固定虚拟机IP地址

在使用KVM虚拟机时,数据交换基本使用SSH进行,但是默认情况下NAT虚拟网络使用DHCP动态IP,因此难以确保IP地址是不变的,这会对我们造成不便。此外,在搭建一些本地集群时,若IP地址变化,也会造成许多配置上的麻烦。

(1) 查看虚拟机MAC地址

自定义固定IP地址之前,我们需要知道虚拟机的MAC物理地址,该地址创建后就不会变化,也就是说这个MAC地址就可以代表我们这个虚拟机。

首先要将虚拟机关机,然后在主界面双击打开我们的虚拟机:

image-20251026163139292

点击左上角配置按钮,切换至虚拟机配置页面:

image-20251026163225785

选择网卡配置就可以看到虚拟机所使用的虚拟网卡是哪个,以及其MAC地址:

image-20251026163254261

我们先将其复制下来备用。

(2) 编辑libvirt网络配置

回到主界面右键编辑我们的本地libvirt连接配置:

Snipaste_2025-10-26_15-02-27

进入虚拟网络配置,选择虚拟机所使用的那个网卡(这里只有default这个网卡,我们虚拟机就是使用的该网卡),切换到XML配置,首先停止网络,然后加入一行配置设定我们虚拟机为一个固定IP,然后重启虚拟网络即可,如下图:

image-20251201153439580

可见我们在dhcp块下加入了下列内容:

<host mac="52:54:00:06:c1:a4" ip="192.168.122.100"/>

该配置就表示:将MAC地址为52:54:00:06:c1:a4的虚拟机的IP地址配置为192.168.122.100,可见这个MAC地址就是上述虚拟机的MAC地址。

通过上图这个虚拟网络的XML配置,我们还可以得到下列信息:

  • 网络的网关IP地址192.168.122.1,由ip标签中address属性定义,使用该网络的虚拟机可在虚拟机内通过网关地址访问宿主机
  • 网络的子网掩码255.255.255.0,由ip标签中netmask属性定义
  • 网络中设备的IP地址范围192.168.122.2 - 192.168.122.254,由dhcp块中range定义

大家也可以在这里修改这些关于虚拟网络的高级配置。

到此,我们就将我们的虚拟机IP固定为我们自定义的了!重启虚拟机就生效了,我们也无需修改虚拟机内部系统的网络配置,其系统内部网络配置保持自动DHCP即可无需修改,只不过后续自动分配到的IP都是我们设定的固定IP地址

image-20251026164410630

需要注意的是大家设定自定义IP时一定要在该虚拟网络的IP范围内!例如我这里的范围:

image-20251026164002934

后续,我们就可以在本机使用ssh连接这个虚拟机:

ssh root@192.168.122.100

此外,还可以克隆该虚拟机,然后使用上述同样方法配置克隆的虚拟机的IP地址,实现搭建虚拟机集群。

image-20251026164651124

8,配置网桥实现局域网内直接访问虚拟机

上述在本地NAT网络模式下,通过配置固定的虚拟机IP地址,我们可以很方便地在宿主机上访问到各个KVM虚拟机。那么当我们要将范围扩大到整个局域网,在局域网内也能够访问虚拟机的时候,使用NAT网络模式的虚拟机就无法被访问了,因为NAT网络是在宿主机上虚拟出来的路由,只能在宿主机内访问,在宿主机外局域网内,是无法直接访问到的。

此时,我们可以借助Linux的网桥功能,实现在局域网内也可以直接访问到KVM虚拟机,仅需创建一个网桥,然后将宿主机网卡和KVM都接入到网桥即可。

Linux的网桥可以理解为:一个虚拟的网络交换机。 它能够把物理网卡和虚拟机的网卡“连接”在一起,让它们处于同一个二层网络(局域网)中。当KVM虚拟机和宿主机网卡均接入网桥时,就能够实现:

  • 宿主机网卡仍然正常通过网桥上网
  • KVM虚拟机直接获得局域网IP地址,且局域网内其它设备可直接访问

可以通过下列示意图对比理解一下。

NAT模式下,虚拟机网络IP由宿主机内虚拟的NAT路由分配,此时仅有宿主机可通过这个内部IP访问到虚拟机:

而在接入网桥时,宿主机的物理网卡和虚拟机均接入网桥,此时虚拟机也能获得局域网IP地址,不仅宿主机可访问虚拟机,局域网内设备也可以通过其地址访问到虚拟机:

此时,宿主机网卡将不再直接连接网络,而是作为一个网络管道接入网桥,所有流量均走网桥,因此宿主机的物理网卡此时不再被分配IP地址;同理,虚拟机也直接接入了网桥,网络流量也同样走这个网桥进出。此时,在局域网内,宿主机和虚拟机“看起来”就像是在同一层级了,即均位于局域网内,其它设备也可以直接通过相应IP地址访问虚拟机。

下面,我们就来进行实际的网桥配置和KVM配置操作。需要注意的是:WiFi网卡通常不支持接入到Linux网桥,因此大家需确保自己的服务器/主机使用的是有线网卡。

(1) 宿主机安装配置NetworkManager

Linux系统的网络通常由特定的网络管理器管理,而一般情况下:

  • 对于无图形界面的服务器系统,通常使用的是ifupdown网络管理器
  • 对于有图形界面的Linux,通常默认会安装NetworkManager,我们常见的Linux桌面例如KDE Plasma、Gnome、Cinnamon等,其设置界面的网络配置其底层就是调用NetworkManager完成的

由于ifupdown的网桥配置过于繁琐,因此这里建议大家统一安装NetworkManager网络管理器替换ifupdown,这样我们就可以直接使用nmclinmtui这类命令快速完成网桥配置。

如果你的服务器/电脑的Linux系统已有图形界面,则通常已经自带了NetworkManager了,就无须安装,可跳过这一部分;如果是纯命令行界面,则继续进行下面的安装操作。下面操作过程中网络会短暂中断,建议不要使用SSH远程进行,而是直接在服务器/电脑上操作或使用云服务厂商提供的VNC等方式。

首先是安装NetworkManager,直接使用命令安装即可:

# 安装NetworkManager (Debian/Ubuntu/Linux Mint/Pop!_OS)
sudo apt install network-manager

然后,我们需卸载ifupdown并清除其配置文件,建议清除之前备份配置:

# 卸载ifupdown
sudo apt purge ifupdown
# 清除配置,建议先备份配置文件
sudo rm /etc/network/interfaces
sudo rm -r /etc/network/interfaces.d/

此时,服务器会断开网络,重启NetworkManager即可:

sudo service NetworkManager restart

一般情况下,重启后会自动探测网络设备并加入一个默认网络配置,宿主机就可以正常联网了,大家可以使用下列命令分别查看网络设备网络配置列表:

# 查看网络设备列表
sudo nmcli d

# 查看网络配置列表
sudo nmcli c

例如我这里:

Snipaste_2026-02-11_17-28-59

Snipaste_2026-02-11_17-31-25

如果重启后并未自动生成网络配置,宿主机仍无法联网,则需要手动创建配置,下面给出创建网络配置命令示例,大家根据实际情况自行选择创建动态IP配置还是静态IP配置,选择其一即可:

# 物理网卡名称为enp2s0

# 添加一个DHCP连接配置,使用自定义DNS且关闭IPv6
# con-name 指定网络配置名称
# ifname 指定网络设备(网卡)名称
# 名称均可自定义
sudo nmcli c add type ethernet \
	con-name "Main" ifname enp2s0 \
	ipv4.method auto \
	ipv4.dns "114.114.114.114 114.114.115.115" \
	ipv4.ignore-auto-dns yes \
	ipv6.method disabled

# 或者,添加静态IP连接
# 假设宿主机所在局域网内IP网段为:192.168.122.xxx,实际情况请以自己的为准
# ip4 指定IP地址
# gw4 指定网关地址
# ipv4.dns 指定DNS服务器,多个使用空格隔开
sudo nmcli c add type ethernet \
	con-name "Main" ifname enp2s0 \
	ipv4.method manual \
	ip4 192.168.122.100/24 \
	gw4 192.168.122.1 \
	ipv4.dns "114.114.114.114 114.114.115.115" \
	ipv6.method disabled

到此,NetworkManager就配置完成了。

nmcliNetworkManager的管理命令,上述也涉及到了两个关键概念:

  • 网络设备:也就是我们的物理/虚拟网络设备,例如有线网卡、无线网卡、本地回环虚拟网卡lo等,这些都属于网络设备,使用nmcli d命令可列出网络设备
  • 网络配置:网络配置定义了特定的网络设备如何进行联网,例如配置动态IPv4或特定的静态IPv4地址,使用什么样的DNS服务器等配置,这些就属于网络配置,网络配置需应用到特定的网络设备上,当然也可以定义多套网络配置,在需要时一个设备可灵活切换至不同配置,使用nmcli c命令可列出网络配置

(2) 宿主机添加网桥

现在,我们就需要在宿主机上添加网桥,同时将宿主机网卡接入至网桥(作为网桥附属设备)。首先需创建网桥虚拟设备及其连接配置,这里仍然给出配置动态IP的网桥和配置静态IP的网桥两种方法,大家选择其一即可。

创建一个动态IP的网桥:

# 创建网桥连接,网桥连接配置命名为bridge-br0,网桥设备名为br0
# 使用DHCP自动配置IP地址,手动指定DNS,关闭IPv6
# 同时关闭STP(生成树协议)以减少延迟
sudo nmcli con add type bridge \
	con-name bridge-br0 ifname br0 \
	ipv4.method auto \
	ipv4.dns "114.114.114.114 114.114.115.115" \
	ipv4.ignore-auto-dns yes \
	ipv6.method disabled \
	bridge.stp no

上述命令中:

  • con-name 用于指定网桥连接配置的名称
  • ifname 用于指定要创建的网桥虚拟设备的名称

若要创建静态IP的网桥,我们首先需查看我们当前网卡的IP地址以及网关地址:

# 查看当前活动配置的IPv4地址和网关
# '有线连接' 是我宿主机有线网卡正在使用的网络配置名,大家需更换为自己实际的配置名称,使用nmcli c查看
nmcli -g IP4.ADDRESS,IP4.GATEWAY connection show '有线连接'

结果:

Snipaste_2026-02-11_17-34-17

然后,根据实际IP创建网桥设备,建议网桥IP可以和原网卡一致:

# 创建网桥连接,手动配置IP地址
sudo nmcli c add type bridge \
	con-name bridge-br0 ifname br0 \
	ipv4.method manual \
	ipv4.addresses 192.168.110.23/24 \
	ipv4.gateway 192.168.110.1 \
	ipv4.dns "114.114.114.114 114.114.115.115" \
	ipv6.method disabled \
	bridge.stp no

上述我们的IP地址均写作192.168.110.23/24这样的形式,后面的/24代表当前网段内不同设备的IP地址前面24位(二进制位)是固定的(即192.168.110部分),如果你处在更大的局域网内,则可能是:172.30.xxx.xxx/16,即不同设备的IP地址172.30部分固定,后面两个数字均可变。因此,需根据自己实际情况正确配置IP地址。

到此,我们就创建了个名为br0的网桥设备,并完成了其配置。

(3) 将宿主机网卡接入网桥

此时,我们仅仅创建了网桥设备,但并没有用起来,因此我们还需要:将宿主机网卡接入到网桥中,并关闭原网卡的连接配置。

执行下列命令:

# 将物理网卡接入网桥
# 命令实际意义:创建一个有线连接配置,并将实际网卡作为网桥从属设备
# con-name是连接名,可以随便取,这里是bridge-br0-enp6s0
# ifname是你的物理网卡名称
sudo nmcli c add type ethernet slave-type bridge \
	con-name bridge-br0-enp6s0 ifname enp6s0 \
	master br0

# 关闭旧连接同时启用网桥配置(配置名称记得换成自己的)
sudo nmcli c down '有线连接' && nmcli c up bridge-br0-enp6s0

此时,网桥配置基本全部完成,我们的宿主机的物理网卡将不再直接作为上网设备,而是接入到这个网桥联网。执行sudo nmcli c结果应当如下:

Snipaste_2026-02-11_17-40-46

(4) KVM虚拟机接入网桥

直接在virt-manager中,打开对应虚拟机网络配置进行修改即可:

image-20260212000101502

记得点击右下角Apply应用配置后重启虚拟机生效,这时虚拟机已成功接入网桥,在宿主机执行brctl show命令,就可以很清晰地发现我们的网桥下接入了我们的宿主机网卡和一个KVM虚拟机设备:

Snipaste_2026-02-11_18-04-46

(5) KVM虚拟机静态IP配置

在网桥模式下,我们就不能直接通过virt-manager直接分配静态虚拟机IP地址了!而是要在虚拟机的系统中进行配置

在这之前,我们首先需要知道宿主机的IP地址和网关,由于上述我们已经配置了宿主机网卡也同过网桥联网,因此我们直接查询网桥设备的IP地址和网关即可:

# 查询网桥设备br0的IP地址
ip addr show br0

# 查询网桥设备br0的网关
ip route show dev br0

结果:

image-20260212000942249

可见我这里宿主机:

  • 网桥IPv4地址:192.168.110.33/24/24可得当前网段IP地址最后一位不固定,前三位固定
  • 网桥网关地址:192.168.110.1

后续在虚拟机中配置静态IP时,也需要根据宿主机网桥IP段进行配置。

下面,将阐述下列几种情况下虚拟机配置静态IP地址的方法:

  • 虚拟机内使用无图形化界面系统,使用ifupdown管理网络
  • 虚拟机内系统安装了图形化界面,使用NetworkManager管理网络

大家根据自己实际情况选择其一即可。

ifupdown配置静态IP

在KVM虚拟机内,编辑/etc/network/interfaces文件:

sudo vim /etc/network/interfaces

找到类似iface enp2s0 inet dhcp这一行(enp2s0是我这里虚拟机内默认网卡),将dhcp改成static,并在这一行下方加入下列几行配置IP地址和网关配置:

address 192.168.110.233/24
gateway 192.168.110.1

可见:

  • 网关gateway必须和宿主机网桥的相同
  • IP地址address的网段也必须和宿主机网桥的一致,但整个IP地址不可与宿主机网桥以及局域网内任何其它设备冲突,大家可自定义一个IP地址值

最终如图所示:

image-20260212001933881

然后,还需配置DNS服务器,编辑/etc/resolv.conf文件:

sudo vim /etc/resolv.conf

加入下列配置:

nameserver 114.114.114.114

最后重启网络服务即可:

sudo service networking restart

到此,虚拟机静态IP配置完成!大家可以试试在局域网内直接访问虚拟机的静态IP,是可以访问到的,就像一个实际的局域网设备一样。

NetworkManager配置静态IP

如果虚拟机内Linux系统使用了图形界面,则通常网络管理器使用的是NetworkManager,此时可直接在图形界面内设置自行修改网络配置,修改IP地址为网段内自定义IP地址,子网掩码为255.255.255.0(对应的是前面IP的/24这个后缀),以及网关配置为宿主机网桥的网关即可,这里不再过多赘述。

此外,也可以使用nmcli命令行修改,可在虚拟机中执行下列命令查看连接配置:

sudo nmcli c

假设虚拟机内网卡网络连接配置名为Connection,那么执行下列命令配置其为静态IP地址:

# 将获取IP的方式从auto改为manual(静态)
sudo nmcli c modify "Connection" ipv4.method manual
# 设置IP地址和子网掩码(使用 CIDR 格式),自定义一个局域网内无冲突的IP,网段必须和宿主机的网桥的一致
sudo nmcli c modify "Connection" ipv4.addresses 192.168.110.233/24
# 设置网关,必须和宿主机网桥的一样
sudo nmcli c modify "Connection" ipv4.gateway 192.168.110.1
# 设置DNS,多个地址用空格隔开
sudo nmcli c modify "Connection" ipv4.dns "114.114.114.114 114.114.115.115"
# 关闭IPv6(可选)
sudo nmcli c modify "Connection" ipv6.method disabled

最后重新激活配置生效:

sudo nmcli c up "Connection"

到此,虚拟机的NetworkManager静态IP配置完成。