KVM 虚拟化入门与热迁移实战
从零开始认识 KVM:先学会用图形界面和命令行管理虚拟机,再深入共享存储下的在线热迁移。一篇笔记,覆盖 KVM 单机使用与热迁移实验全流程。
目录
-
[一、KVM 是什么](#一、KVM 是什么)
-
[二、KVM 图形界面使用(virt-manager)](#二、KVM 图形界面使用(virt-manager))
-
[2.1 呼出 virt-manager 的两种方式](#2.1 呼出 virt-manager 的两种方式)
-
[2.2 上传镜像并创建 Windows 虚拟机](#2.2 上传镜像并创建 Windows 虚拟机)
-
[2.3 快照与添加硬件](#2.3 快照与添加硬件)
-
-
[三、KVM 命令行使用(virsh)](#三、KVM 命令行使用(virsh))
-
[3.1 查看版本与帮助](#3.1 查看版本与帮助)
-
[3.2 虚拟机生命周期管理](#3.2 虚拟机生命周期管理)
-
[3.3 开机自启动设置](#3.3 开机自启动设置)
-
[3.4 配置文件查看与修改](#3.4 配置文件查看与修改)
-
-
[六、KVM 热迁移实验](#六、KVM 热迁移实验)
-
[6.1 热迁移原理与适用场景](#6.1 热迁移原理与适用场景)
-
[6.2 实验拓扑与环境准备](#6.2 实验拓扑与环境准备)
-
[6.3 配置 NFS 共享存储](#6.3 配置 NFS 共享存储)
-
[6.4 添加共享存储并创建虚拟机](#6.4 添加共享存储并创建虚拟机)
-
[6.5 在线热迁移操作](#6.5 在线热迁移操作)
-
一、KVM 是什么
KVM(Kernel-based Virtual Machine) 是 Linux 内核原生的全虚拟化方案。它把 Linux 内核直接变成一个 Hypervisor(虚拟机监控器),配合 QEMU 模拟硬件设备、libvirt 提供统一管理 API,再通过 virt-manager / virsh 等工具完成对虚拟机的创建与管理。
技术栈关系可以这样理解:
| 组件 | 作用 |
|---|---|
| KVM | 内核模块,提供 CPU 虚拟化和内存虚拟化能力 |
| QEMU | 用户态模拟器,模拟磁盘、网卡、显卡等硬件 |
| libvirt | 统一管理接口,屏蔽底层 Hypervisor 差异 |
| virt-manager | 图形化管理界面(GUI) |
| virsh | 命令行管理工具(CLI) |
| virt-install | 命令行创建虚拟机工具 |
二、KVM 图形界面使用(virt-manager)
2.1 呼出 virt-manager 的两种方式
方式一:图形界面调出
在桌面环境中,从应用程序菜单找到「Virtual Machine Manager」直接打开即可。
方式二:命令行调出
\[root@KVM1 \~]# virt-manager
前提:主机上已安装
virt-manager软件包,且当前用户有权限访问 KVM。
2.2 上传镜像并创建 Windows 虚拟机
第 1 步:创建存放镜像的目录并上传镜像
先用终端软件(如 Xshell / MobaXterm / FinalShell)连接 KVM 主机,创建 /iso 目录存放安装镜像:
\[root@KVM1 \~]# mkdir /iso
\[root@KVM1 \~]# cd /iso
\[root@KVM1 iso]# ls # 验证镜像已经上传
cn\_windows\_7\_enterprise\_with\_sp1\_x64\_dvd\_u\_677685.iso
第 2 步:在 virt-manager 中新建虚拟机
-
在 virt-manager 主界面点击左上角「新建虚拟机」图标;
-
安装方式选择「本地安装介质(ISO 镜像或光驱)」;
-
找到镜像位置:
Other Locations -> Computer -> /iso,选择 win7 镜像; -
设置合理的内存 和 CPU 资源(示例:内存 4G、CPU 2 核);
-
设置磁盘容量(示例:40G,格式为 qcow2);
-
设置虚拟机名称
win7; -
弹出提示 "Virtual Machine Manager wants to inhibit shortcuts(抑制快捷方式)",选择 allow。
第 3 步:正常安装 Windows 7
后续流程和物理机装系统完全一致:
-
点击「现在安装」
-
点击「我接受许可条款」→ 下一步
-
点击「自定义(高级)」
-
选择磁盘 → 下一步
-
跳过普通用户创建 :在创建用户界面按
Shift+F10呼出 CMD(笔记本可能需要加按Fn),输入命令启用内置 administrator 账户:net user administrator /active:yes
原理:Windows 7 默认禁用内置 administrator 账户,通过
net user命令将其激活,从而跳过创建普通用户环节。
-
回到图形界面把「账户已禁用」勾选去掉,即可用 administrator 登录。
-
系统安装结束后,先关闭虚拟机。
2.3 快照与添加硬件
给虚拟机拍快照
双击虚拟机弹出配置界面,点击「快照」标签 →「+」拍摄快照。快照用于保存虚拟机某一时刻的状态,方便出问题后回滚。
测试热插拔:加硬盘、加网卡
双击虚拟机 → 点击「添加硬件」:
-
添加一块新硬盘(类型选 disk / 总线 sata 等);
-
添加一块新网卡(选择网络类型,默认 NAT 网络
default)。
说明:部分设备支持在虚拟机运行状态下热添加,磁盘 / 网卡也可在关机后添加,重启生效。
三、KVM 命令行使用(virsh)
virsh 是 libvirt 提供的命令行管理工具,功能与 virt-manager 对应,但更利于脚本化与远程管理。
3.1 查看版本与帮助
\[root@KVM1 \~]# virsh version
Compiled against library: libvirt 8.0.0
Using library: libvirt 8.0.0
Using API: QEMU 8.0.0
Running hypervisor: QEMU 6.2.0
virsh --help 会列出全部命令,并按功能分组:
| 分组 | 说明 |
|---|---|
| Domain Management | 虚拟机生命周期管理(核心) |
| Domain Monitoring | 查看虚拟机信息 |
| Host and Hypervisor | KVM 物理机(节点)管理 |
| Snapshot | 快照相关配置 |
| Storage Pool / Volume | 存储池与存储卷管理 |
| Network | 虚拟网络管理 |
3.2 虚拟机生命周期管理
以 win7 虚拟机为例,常见生命周期命令如下:
\[root@KVM1 \~]# virsh shutdown win7 # 正常关机(推荐,向系统发送关机指令)
Domain 'win7' is being shutdown
\[root@KVM1 \~]# virsh list # 列出正在运行的虚拟机
 Id Name State
\--------------------
 1 win7 running
\[root@KVM1 \~]# virsh list --all # 列出所有状态的虚拟机(含关机)
 Id Name State
\-----------------------
 \- win7 shut off
\[root@KVM1 \~]# virsh start win7 # 开启虚拟机
Domain 'win7' started
\[root@KVM1 \~]# virsh reboot win7 # 重启虚拟机
Domain 'win7' is being rebooted
\[root@KVM1 \~]# virsh destroy win7 # 强制关闭(相当于拔电源,慎用)
Domain 'win7' destroyed
\[root@KVM1 \~]# virsh suspend win7 # 挂起:内存数据存盘,释放 CPU/内存
Domain 'win7' suspended
\[root@KVM1 \~]# virsh list # 挂起后状态为 paused
 Id Name State
\---------------------
 2 win7 paused
\[root@KVM1 \~]# virsh resume win7 # 恢复挂起的虚拟机
Domain 'win7' resumed
常用命令速查表:
| 命令 | 作用 |
|---|---|
virsh list |
列出运行中的虚拟机 |
virsh list --all |
列出所有虚拟机 |
virsh start <name> |
开启虚拟机 |
virsh shutdown <name> |
正常关机 |
virsh reboot <name> |
重启 |
virsh destroy <name> |
强制关闭(拔电源) |
virsh suspend <name> |
挂起(暂停) |
virsh resume <name> |
恢复运行 |
小贴士:对运行中的虚拟机,既可以用名字(Name)也可以用 ID 操作,例如
virsh destroy 1。
3.3 开机自启动设置
默认情况下,guest os(虚拟机)不会随 host os(宿主机)一起开机 。可以通过 autostart 设置开机自启:
\[root@KVM1 \~]# virsh start win7
\[root@KVM1 \~]# virsh autostart win7 # 设置 win7 随宿主机一起开机
Domain 'win7' marked as autostarted
\[root@KVM1 \~]# virsh list --autostart # 查看随宿主机自启动的虚拟机
 Id Name State
\---------------------
 1 win7 running
\[root@KVM1 \~]# virsh autostart --disable win7 # 取消开机自启
Domain 'win7' unmarked as autostarted
验证方法:设置自启动后,重启宿主机,观察 win7 是否跟着一起启动。
3.4 配置文件查看与修改
每台虚拟机的配置都以 XML 文件形式保存,包括 CPU、内存、磁盘、网卡、显卡等所有硬件定义。
\[root@KVM1 \~]# virsh dumpxml win7 # 查看虚拟机 win7 的完整 XML 配置
\[root@KVM1 \~]# virsh edit win7 # 编辑虚拟机 win7 配置(带语法校验)
\[root@KVM1 \~]# virsh vcpucount --active win7 # 查看虚拟机当前配置的 CPU 数量
2
XML 配置中的关键字段举例:
\<name>win7\</name> \<!-- 虚拟机名称 -->
\<memory unit='KiB'>4194304\</memory> \<!-- 内存 4GB -->
\<vcpu placement='static'>2\</vcpu> \<!-- 2 个 vCPU -->
\<disk type='file' device='disk'> \<!-- 磁盘设备 -->
  \<driver name='qemu' type='qcow2'/>
  \<source file='/var/lib/libvirt/images/win7.qcow2'/>
\</disk>
\<interface type='network'> \<!-- 网卡设备 -->
  \<source network='default' bridge='virbr0'/>
  \<model type='e1000e'/>
\</interface>
四、磁盘管理(qemu-img)
创建的虚拟机磁盘文件默认存放在 /var/lib/libvirt/images 目录(在 virt-manager 的 Storage 中显示为 default 存储池)。
\[root@KVM1 \~]# cd /var/lib/libvirt/images/ # 默认磁盘存放目录
\[root@KVM1 images]# ls
win7.qcow2 # win7 虚拟机的硬盘文件
\[root@KVM1 images]# ll -h
total 7.7G
-rw-------. 1 qemu qemu 41G Sep 3 12:00 win7.qcow2
\[root@KVM1 images]# qemu-img info win7.qcow2 # 查看磁盘详细信息(建议关机状态下查看)
image: win7.qcow2
file format: qcow2 # 硬盘格式:qcow2
virtual size: 40 GiB (42949672960 bytes) # 逻辑大小(上限)40G
disk size: 7.66 GiB # 实际占用磁盘 7.66G
cluster\_size: 65536
Snapshot list: # 快照列表
ID TAG VM SIZE DATE
1 win7 0 B 2024-09-03 09:54:06
知识点:qcow2 是稀疏文件
。创建 40G 的 qcow2 磁盘,实际只占用使用量大小(7.66G),写入多少占多少,支持快照、压缩、加密等功能。
创建一块新的虚拟机硬盘:
\[root@KVM1 \~]# qemu-img create -f qcow2 vm2.qcow2 20G
Formatting 'vm2.qcow2', fmt=qcow2 size=21474836480
参数说明:
| 参数 | 含义 |
|---|---|
create |
创建新镜像 |
-f qcow2 |
指定磁盘格式为 qcow2 |
vm2.qcow2 |
磁盘文件名 |
20G |
磁盘逻辑容量 20G |
五、命令行创建虚拟机(virt-install)
virt-install 是命令行下创建虚拟机的工具,非常适合批量部署。
示例:使用 CentOS 7 镜像创建虚拟机 vm2
\# 1. 创建磁盘(放在非默认目录 /disk)
\[root@KVM1 \~]# mkdir /disk
\[root@KVM1 \~]# qemu-img create -f qcow2 /disk/vm2.qcow2 20G
\# 2. 用 virt-install 创建虚拟机
\[root@KVM1 \~]# virt-install --name vm2 --memory 4096 --vcpus 2 \\
\> --disk path=/disk/vm2.qcow2 \\
\> --location /iso/CentOS-7-x86\_64-Minimal-1810.iso \\
\> --network network=default --noautoconsole
Starting install...
Retrieving file vmlinuz...
\| 6.3 MB 00:00:00
Retrieving file initrd.img...
\| 50 MB 00:00:00
Domain is still running. Installation may be in progress.
核心参数详解:
| 参数 | 含义 |
|---|---|
--name vm2 |
指定虚拟机名称 |
--memory 4096 |
指定内存大小(单位 MiB) |
--vcpus 2 |
指定 vCPU 数量 |
--disk path=... |
指定磁盘路径(可指向非默认目录) |
--location /iso/...iso |
指定安装镜像位置 |
--network network=default |
指定网络,default 是 KVM 默认的 NAT 网络 |
--noautoconsole |
安装时不自动连接控制台 |
补充常用参数:
--os-variant win10(指定操作系统类型)、
--graphics vnc,port=5901(指定显示方式)、
--autostart(开机自启)、
--wait(等待安装完成时间)。
六、KVM 热迁移实验
前面学会了 KVM 单机管理,接下来进入进阶实验:虚拟机在线热迁移,让虚拟机从一台宿主机 "无缝" 跑到另一台宿主机,业务不中断。
6.1 热迁移原理与适用场景
热迁移(Live Migration) 适用于可以容忍极短时间中断、但必须快速恢复业务的场景,比如轻量级数据库业务、桌面云业务。
核心前提条件:磁盘共享存储
迁移的机器必须使用 共享存储(NFS / Ceph / RBD /iSCSI) 。源宿主机和目标宿主机同时访问同一份 虚拟机磁盘 ------磁盘不迁移,只迁移 "内存 + CPU 设备状态"。
迁移四步走:
-
在目标主机上创建一个规格与源虚拟机相同的空虚拟机;
-
通过 ** 迭代迁移(pre-copy)** 技术,把源虚拟机内存迁到目标主机;迁移过程中变化(脏页)的数据再继续迁移,经过几轮后数据量很小时,暂停源虚拟机,把最后一点数据迁过去;
-
删除源虚拟机;
-
目标主机拉起新的虚拟机,业务无缝切换。
典型使用场景:
-
服务器维护前:把该服务器上的虚拟机迁走,降低维护过程中业务中断的风险;
-
服务器升级前:把虚拟机迁走,升级完成后再全部迁回;
-
资源整合:把空闲服务器上的虚拟机集中到其他服务器,关闭无负载的服务器,降低运营成本。
6.2 实验拓扑与环境准备
实验环境共 3 台虚拟机:
  +-------------------+
  \| NFS |
  \| 192.168.108.100 | <-- 共享存储
  +---------+---------+
  |
  +---------+---------+
  \| KVM1 | <-- 源宿主机
  \| 192.168.108.101 |
  +-------------------+
  \| KVM2 | <-- 目标宿主机
  \| 192.168.108.102 |
  +-------------------+
准备步骤:
-
KVM1 做完单机实验后还原快照 ,通过 KVM1 完整克隆出 KVM2 和 NFS 两台虚拟机(克隆时选择「完整克隆」);
-
三台虚拟机开机,先开 KVM1,然后依次开机;
-
KVM2 修改主机名:
[root@KVM1 ~]# hostnamectl set-hostname KVM2
[root@KVM1 ~]# bash
[root@KVM2 ~]#
-
KVM2 修改 IP 为 192.168.108.102:
[root@KVM2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens160
# 修改 IPADDR=192.168.108.102,并删除 UUID 那行(避免和源虚拟机冲突)
[root@KVM2 ~]# nmcli connection reload ens160
[root@KVM2 ~]# ifconfig ens160 # 验证 IP 已修改
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.108.102 netmask 255.255.255.0 broadcast 192.168.108.255
-
NFS 修改主机名和 IP(192.168.108.100): 操作同上,
hostnamectl set-hostname NFS,IPADDR=192.168.108.100,同样删除 UUID 行。
关键点:克隆出来的虚拟机
网卡 UUID 相同会冲突
,务必删除 ifcfg 文件中的 UUID 行并 reload。
-
三节点配置相同的 hosts 文件:
# KVM1 操作:
[root@KVM1 ~]# cat >> /etc/hosts << EOF
192.168.108.100 NFS
192.168.108.101 KVM1
192.168.108.102 KVM2
EOF
[root@KVM1 ~]# scp /etc/hosts root@KVM2:/etc/hosts # 复制到 KVM2
[root@KVM1 ~]# scp /etc/hosts root@NFS:/etc/hosts # 复制到 NFS
6.3 配置 NFS 共享存储
在 NFS 节点上:
\[root@NFS \~]# mkdir /nfs # 创建共享目录
\[root@NFS \~]# vim /etc/exports # 编辑共享配置
/nfs \*(rw,no\_root\_squash,no\_subtree\_check)
\[root@NFS \~]# systemctl restart nfs-server.service # 重启 NFS 服务
\[root@NFS \~]# showmount -e localhost # 本地验证共享
Export list for localhost:
/nfs \*
\[root@NFS \~]# systemctl stop firewalld.service # 停止防火墙(实验环境)
/etc/exports 配置详解:
| 字段 | 含义 |
|---|---|
/nfs |
共享出去的目录 |
* |
允许所有网段访问 |
rw |
客户端对共享目录有读写权限 |
sync |
数据同步写入内存和磁盘 |
no_root_squash |
客户机以 root 访问时不映射 root 用户 |
no_subtree_check |
不检查父目录权限 |
补充:
root_squash则会把客户机的 root 用户映射成匿名用户(更安全但权限受限)。实验用
no_root_squash便于迁移。
KVM1 / KVM2 验证并挂载:
\[root@KVM1 \~]# showmount -e 192.168.108.100 # 测试能否访问 NFS 共享
Export list for 192.168.108.100:
/nfs \*
\[root@KVM1 \~]# mkdir /NFS # KVM1 创建挂载目录
\[root@KVM2 \~]# mkdir /NFS # KVM2 创建挂载目录
6.4 添加共享存储并创建虚拟机
在 virt-manager 中添加共享存储(KVM1、KVM2 都操作):
-
在 KVM1 的 virt-manager 中,先通过
Details把两台 KVM 改名,方便区分; -
点击左下角 +,添加新存储;
-
配置共享存储参数:
| 配置项 | 值 |
|---|---|
| Type | nfs |
| Target Path | /NFS(KVM1/KVM2 的挂载目录) |
| Host Name | NFS 服务器地址 192.168.108.100 |
| Source Path | /nfs(NFS 共享目录) |
- KVM2 上做同样的操作。
上传镜像并用共享存储创建虚拟机:
-
上传 CentOS 镜像到 KVM1;
-
点击 KVM1 → 新建虚拟机 → 选择刚才上传的镜像;
-
关键步骤:选择安装到共享存储 NFS(而不是默认本地存储);
-
正常安装虚拟机,装完重启时会自动弹出光盘。
核心点:虚拟机磁盘必须落在 NFS 共享存储上,KVM1 和 KVM2 才能同时访问同一份磁盘,这是热迁移的前提。
6.5 在线热迁移操作
关闭两台宿主机防火墙:
\# KVM1:
\[root@KVM1 \~]# systemctl stop firewalld.service
\# KVM2:
\[root@KVM2 \~]# systemctl stop firewalld.service
执行迁移:
在 virt-manager 中,右键要迁移的虚拟机(KVM1 上)→ 选择「迁移」→ 目标主机选择 KVM2,即可看到虚拟机从 KVM1 平滑迁移到 KVM2,迁移过程中业务基本无感知。
迁移完成后:
-
目标主机 KVM2 上出现运行中的虚拟机;
-
源主机 KVM1 上的虚拟机被删除 / 停止;
-
整个过程磁盘不拷贝,只迁移内存状态,因此速度快、中断时间极短。
七、总结
| 阶段 | 关键技能 | 核心命令 / 工具 |
|---|---|---|
| 单机管理 | 图形界面建机 | virt-manager |
| 单机管理 | 命令行管理 | virsh(list/start/shutdown/suspend/autostart) |
| 单机管理 | 磁盘管理 | qemu-img(create/info) |
| 单机管理 | 命令行建机 | virt-install |
| 热迁移 | 共享存储 | NFS(/etc/exports) |
| 热迁移 | 在线迁移 | virt-manager 迁移功能 |
几个关键认知:
-
KVM = 内核虚拟化 + QEMU 设备模拟 + libvirt 统一管理;
-
qcow2 磁盘按需分配,逻辑容量与实际占用分离,天然支持快照;
-
热迁移的前提是共享存储,磁盘不迁移,只迁移内存与 CPU 状态;
-
迁移采用 pre-copy 迭代迁移:反复拷贝变化数据,数据量小到阈值后短暂暂停源机、完成最后同步、目标机拉起。
掌握 KVM 基础使用,再吃透热迁移原理与实验,就具备了企业级虚拟化运维的入门能力。接下来可以继续探索快照、存储池、虚拟网络、以及 Ceph /iSCSI 等更多共享存储方案。