KVM虚拟化技术
KVM 虚拟化技术入门与实战指南
一、 KVM 理论知识
1.1 什么是 KVM
KVM(Kernel-based Virtual Machine,基于内核的虚拟机)是 Linux 内核的一个开源虚拟化模块。它可以将任何 Linux 设备转变为裸机虚拟机监控器(Type-1 Hypervisor),允许在单台物理服务器上运行多个相互隔离的虚拟机(Guest OS)。
1.2 工作原理
KVM 的核心在于利用 CPU 的硬件虚拟化扩展(如 Intel VT-x 或 AMD-V)。其工作机制如下:
- 内核模块:KVM 作为 Linux 内核模块加载,使主机操作系统能够直接管理虚拟机的资源。
- QEMU 仿真器:KVM 结合 QEMU 用户空间组件,为虚拟机提供虚拟硬件(如网卡、磁盘、显卡等)。
- 独立进程:每个虚拟机在宿主机上作为一个独立的 Linux 进程运行,由标准的 Linux 调度器进行 CPU 调度,并由内核直接管理内存。
1.3 KVM 的核心优势
- 高性能:虚拟机直接继承 Linux 内核的高性能特性,并在尽可能接近硬件的位置执行虚拟化,大幅缩短进程延迟。
- 高安全性:支持 SELinux 等 Linux 原生安全功能,确保虚拟环境严格遵守安全边界,强化数据隐私。
- 高稳定性:作为成熟的开源项目,KVM 拥有庞大的社区支持,为企业级应用提供稳定基础。
- 成本效益:完全免费开源,企业无需支付额外的商业许可费用。
- 灵活性:兼容多种硬件配置,支持动态分配 CPU、内存和存储,并支持资源的精简预置(Thin Provisioning)。
1.4 KVM 与 VMware 的区别
| 对比维度 | KVM | VMware (ESXi) |
|---|---|---|
| 开源与授权 | 免费开源,无许可费用 | 商业软件,需购买商业许可证 |
| 架构定位 | 集成在 Linux 内核中的模块 | 独立的 Type-1 裸机虚拟化平台 |
| 适用场景 | 云计算、Web 服务、开发测试 | 传统企业级复杂应用、大型数据中心 |
| 生态与管理 | 依赖 libvirt、OpenStack 等开源生态 | 拥有完善的 vCenter 商业管理套件 |
二、 KVM 核心组件与常用命令
- qemu-kvm:KVM 的核心模块与用户空间仿真器,用户空间进程,负责 I/O 模拟、设备模型及 VM 生命周期控制。
- libvirtd:守护进程,管理虚拟机配置、资源分配及快照。
- libvirt:虚拟化管理工具集,提供统一的 API 和命令行接口。
- virt-install:用于通过命令行创建和安装虚拟机的工具。
- virt-manager:基于图形界面(GUI)的虚拟机管理程序。
- cockpit-machines:基于 Web 的轻量级管理插件,适合现代 Linux 服务器管理。
三、 KVM部署
3.1 环境准备与检查
在部署前,需确认 CPU 支持虚拟化且内核模块已加载:
# 检查 CPU 是否支持硬件虚拟化(Intel 为 vmx,AMD 为 svm),有数字说明支持egrep -c '(vmx|svm)' /proc/cpuinfo
# 检查 KVM 模块是否已加载lsmod | grep kvm3.2 安装核心组件
安装 QEMU、Libvirt 及相关管理工具:
# CentOS/RHEL 系yum install -y qemu-kvm qemu-img libvirt libvirt-client virt-install virt-manager
# Ubuntu/Debian 系apt install -y qemu-kvm libvirt-clients libvirt-daemon-system virtinst bridge-utils3.3 配置并启动Libvirt服务
# 修改libvirtd.conf主配置文件sed -i 's/#unix_sock_group = "libvirt"/unix_sock_group = "libvirtd"/g' /etc/libvirt/libvirtd.conf
# 创建libvirtd用户组,添加root用户到libvirtd用户组groupadd libvirtdusermod -aG libvirtd root
# 修改qemu.conf配置文件sed -i 's/#user = "root"/user = "root"/g' /etc/libvirt/qemu.confsed -i 's/#group = "root"/group = "root"/g' /etc/libvirt/qemu.conf
# 启动服务并设置开机自启systemctl enable --now libvirtd
# 验证服务状态systemctl status libvirtd3.4 配置网络桥接
3.4.1 NAT模式
1.核心特点
- 虚拟机通过宿主机的NAT网关访问外网,无需额外配置物理网卡。
- 外部网络无法直接访问虚拟机(需配置端口转发才能暴露服务)。
- 默认已启用:安装KVM后自动创建名为
default的NAT网络。
2.配置步骤
# 验证默认nat网络virsh net-list --all
# 查看NAT网络详情virsh net-dumpxml default关键参数:
- 网桥名称:
virbr0(虚拟网桥)。 - IP范围:
192.168.122.0/24(DHCP分配范围:192.168.122.2–192.168.122.254)。 - 网关地址:
192.168.122.1(宿主机在NAT网络中的IP)。
3.创建虚拟机时指定NAT网卡
virt-install \ --name nat-vm \ --network network=default \ # 明确使用default NAT网络 --cdrom /path/to/os.iso
# 或编辑虚拟机XML配置 <interface type='network'> <source network='default'/></interface>4.端口转发(若需外部访问虚拟机)
# 编辑NAT网络配置virsh net-edit default
# 在<forward>段内添加端口映射(例如将宿主机8080端口转发到虚拟机80端口):<forward mode='nat'> <nat> <port start='8080' end='8080'/> </nat></forward><portforward proto='tcp' range='8080'> <address proto='tcp' addr='192.168.122.100' port='80'/></portforward>3.4.2 桥接模式(Bridge)
1.核心特点
- 虚拟机直接连接物理网络,获取与宿主机同网段的独立IP。
- 宿主机、局域网设备、虚拟机可互相直接通信。
- 需手动配置网桥(将物理网卡“桥接”到虚拟网桥)。
2.配置方式一:使用nmcli(推荐)
2.1 创建网桥并绑定物理网卡
# 创建桥接接口 br0,(物理网卡为eth0)nmcli connection add type bridge autoconnect yes con-name br0 ifname br0nmcli connection modify br0 ipv4.addresses 192.168.1.10/24 # 宿主机ipnmcli connection modify br0 ipv4.gateway 192.168.1.1 # 网关nmcli connection modify br0 ipv4.dns "8.8.8.8 114.114.114.114" # DNSnmcli connection modify br0 ipv4.method manual
# 将物理网卡加入创建的网桥nmcli connection add type bridge-slave autoconnect yes con-name eth0-br0 ifname eth0 master br0
# 禁用物理网卡IPnmcli connection modify eth0-br0 ipv4.method disabled2.2 激活网桥并验证
nmcli connection up eth0-br0nmcli connection up br0ip addr show br0 # 确认br0持有IPbrctl show # 验证eth0已加入br02.3 创建虚拟机时指定桥接
virt-install \ --name bridge-vm \ --network bridge=br0 \ # 关键:指定桥接网桥 --cdrom /path/to/os.iso
# 或编辑虚拟机XML<interface type='bridge'> <source bridge='br0'/></interface>3. 配置方式二:使用 virsh 定义默认网络
virsh net-start defaultvirsh net-autostart default3.4.3 仅主机模式(Host-Only)
1.核心特点
- 虚拟机仅能与宿主机通信,无法访问外网。
- KVM默认不提供此模式,需手动创建隔离网络(无NAT转发)。
- 适用于完全隔离的测试环境(如安全实验、内部集群)。
2.配置步骤
2.1 创建隔离网络配置文件
新建/etc/libvirt/qemu/networks/host-only.xml:
<network> <name>host-only</name> <bridge name='virbr1'/> <!-- 自定义网桥名 --> <ip address='192.168.100.1' netmask='255.255.255.0'> <!-- 宿主机IP --> <dhcp> <range start='192.168.100.2' end='192.168.100.254'/> </dhcp> </ip></network>2.2 定义并启动隔离网络
virsh net-define /etc/libvirt/qemu/networks/host-only.xmlvirsh net-start host-onlyvirsh net-autostart host-only # 设置开机自启2.3 验证隔离网络
virsh net-dumpxml host-only # 检查配置ip addr show virbr1 # 确认网桥IP为192.168.100.12.4 创建虚拟机时指定隔离网络
virt-install \ --name hostonly-vm \ --network network=host-only \ # 使用自定义隔离网络 --cdrom /path/to/os.iso三、 虚拟机管理
3.1 创建并安装虚拟机
3.1.1 创建存放目录、镜像
创建 kvm虚拟机的存放 目录,同时创建存放虚拟机磁盘和镜像文件的目录
mkdir -p /kvm/{vm,iso}将需要安装的操作系统镜像文件存放在iso目录中
3.1.2 使用virt-install创建虚拟机
3.1.2.1 安装示例参数
# ===== 核心标识与资源分配(必填项)=====virt-install \ --name=prod-centos7 \ # 【必填】虚拟机唯一名称(仅支持字母/数字/_-.:+),命名冲突将直接失败 --memory=8192 \ # 【必填】内存大小(单位MB),此处分配8GB;必须 ≤ 宿主机剩余物理内存 --vcpus=4,sockets=2,cores=2,threads=1 \ # 虚拟CPU拓扑(4核=2路×2核×1线程),影响NUMA性能;简单写法`--vcpus=4`会损失30%+性能
# ===== CPU深度优化(生产环境推荐)===== --cpu=host-passthrough,cache.mode=passthrough \ # 【性能关键】CPU特性透传:host-passthrough最大化性能(跨主机迁移受限);cache.mode=passthrough透传CPU缓存特性 --os-type=linux \ # 系统大类(linux/windows/unix),辅助自动优化;若已指定--os-variant可省略 --os-variant=centos7.0 \ # 【必须精确匹配】通过`osinfo-query os`确认(如centos7.0/win10),错误设置导致性能下降50%+
# ===== 存储配置(必填项)===== --disk path=/var/lib/libvirt/images/prod-centos7.qcow2,size=100,format=qcow2,bus=virtio,cache=none,discard=unmap \ # 【必填】磁盘核心配置: # path=磁盘路径(自动创建) # size=100(单位GB,新建磁盘时必填) # format=qcow2(推荐格式,支持快照/稀疏分配) # bus=virtio(必选高性能总线,比IDE快30%+) # cache=none(SSD直通模式,避免双重缓存) # discard=unmap(启用TRIM,SSD寿命优化)
# ===== 网络与安全(生产环境关键)===== --network bridge=br0,model=virtio,mac=52:54:00:12:34:56 \ # 网络配置: # bridge=br0(需提前用brctl创建网桥) # model=virtio(必选高性能网卡,比e1000快50%+) # mac=...(固定MAC地址,避免DHCP冲突) --graphics none \ # 【文本安装必备】禁用图形界面(VNC/SPICE),否则需配合--console --console pty,target_type=serial \ # 【必须与--graphics none联动】启用串口控制台,否则安装过程无输出 --extra-args="console=ttyS0,115200n8 net.ifnames=0 biosdevname=0" \ # 内核启动参数: # console=ttyS0(指定串口终端,文本安装核心) # net.ifnames=0 biosdevname=0(禁用新式网卡命名,兼容旧脚本)
# ===== 安装源与自动化(必填项)===== --location=http://mirror.centos.org/centos/7/os/x86_64/ \ # 【必填二选一】网络安装源(HTTP/FTP/NFS),ISO路径用--cdrom替代 --initrd-inject=/root/ks.cfg \ # 注入Kickstart文件(实现无人值守安装),路径必须存在且可读
# ===== 高级控制与可靠性(生产环境推荐)===== --autostart \ # 开机自启虚拟机(等效virsh autostart) --noautoconsole \ # 创建后不自动连接控制台(避免阻塞脚本) --check path_in_use=off \ # 禁用路径占用检查(当磁盘路径存在但未被使用时绕过报错) --boot menu=on,useserial=on \ # 启动菜单配置:menu=on(显示启动菜单),useserial=on(串口作为主控制台) --memtune hard_limit=8704000,soft_limit=8388608 \ # 内存管控(单位KB): # hard_limit=8704000(绝对上限,超限触发OOM Kill) # soft_limit=8388608(弹性上限,超限时触发内存回收) --launchSecurity sev,policy=0x07 \ # 【硬件加密】AMD SEV-ES加密(仅限EPYC Rome+): # policy=0x07(策略位:调试禁用+密钥隔离+平台绑定) # ⚠️ 需禁用安全引导(--boot secureBoot=off)且不支持PCI直通 --metadata title="Production VM",description="CentOS 7 Web Server" # 虚拟机元数据(便于管理识别)3.1.2.2 安装centos 7虚拟机
使用 virt-install 命令行工具创建一台 CentOS 7 虚拟机:
virt-install \ --name=centos7 \ # 【必填】虚拟机唯一名称(避免与现有VM冲突) --memory=2048 \ # 分配2048MB内存(CentOS 7图形化安装最低要求) --vcpus=2 \ # 分配2个虚拟CPU核心 --os-type=linux \ # 系统类型(辅助自动优化驱动) --os-variant=centos7.0 \ # 【关键】必须精确匹配(通过`osinfo-query os`确认) --disk path=/kvm/vm/centos7.qcow2,size=20,format=qcow2,bus=virtio \ # 【核心】磁盘配置:路径=/kvm/vm/(按您要求)、20GB空间、qcow2格式、virtio高性能总线 --cdrom=/kvm/iso/CentOS-7-x86_64-Minimal-2009.iso \ # 【核心】ISO路径=/kvm/iso/(请确认文件名与实际一致) --network network=default \ # 【核心】使用libvirt默认NAT网络(自动分配192.168.122.0/24网段IP) --graphics vnc,listen=0.0.0.0,port=5901,password=sunline \ # 【核心】VNC配置:开放所有IP访问(0.0.0.0)、固定端口5901(用于远程连接)、密码sunline --noautoconsole \ # 创建后不自动连接控制台(适合后台执行) --autostart # 开机自启虚拟机(等效virsh autostart)通过网络安装(HTTP/NFS/FTP)
virt-install \ --name=centos7-netinstall \ # 虚拟机名称 --memory=2048 \ # 2048MB内存 --vcpus=2 \ # 2个虚拟CPU --os-type=linux \ --os-variant=centos7.0 \ --disk path=/kvm/vm/centos7-net.qcow2,size=20,format=qcow2,bus=virtio \ # 磁盘存入/kvm/vm/ --network network=default \ # 默认NAT网络 --graphics vnc,listen=0.0.0.0,port=-1 \ # 自动选择一个可用的端口(默认 VNC 端口为 5900 + 显示号) --location=http://mirror.centos.org/centos/7/os/x86_64/ \ # 【核心】网络安装源(HTTP示例) # nfs:192.168.1.100:/centos7。需提前在NFS服务器导出目录(/etc/exports) # ftp://192.168.1.100/centos7。需验证FTP匿名可读(anon_root配置) --extra-args="ip=dhcp ks=http://192.168.1.100/kickstart/centos7.cfg" \ # 【核心】内核参数:DHCP获取IP + 指定Kickstart文件 --noautoconsole通过导入现有磁盘镜像(跳过安装)
virt-install \ --name=centos7-imported \ # 虚拟机名称 --memory=2048 \ --vcpus=2 \ --os-type=linux \ --os-variant=centos7.0 \ --import \ # 【核心】跳过安装,直接导入磁盘 --disk path=/kvm/vm/existing_disk.qcow2,format=qcow2,bus=virtio \ # 【核心】指定已有磁盘路径 --network network=default \ # 默认NAT网络 --graphics vnc,listen=0.0.0.0,port=5903 \ # VNC端口5903 --noautoconsole \ --autostart磁盘文件要求**
- 必须提前存在于
/kvm/vm/目录(示例中为existing_disk.qcow2)。 - 格式必须匹配:
format=qcow2(推荐):需是完整系统镜像(含/boot分区)。- 若为原始磁盘(如
/dev/sdb):format=raw。
- 禁止使用安装介质:移除
--cdrom和--location参数。
3.1.3 虚拟机信息查看
# 查看正在运行中的kvm虚拟机列表virsh list
# 查看所有的虚拟机列表,包含挂掉的virsh list --all
# 查看虚拟机网卡信息virsh domifaddr centos7
# 查看虚拟机VNC远程桌面连接地址/端口,:0 代表 VNC 端口偏移:# VNC 基础端口是 5900,:0 → 实际端口 5900;:1=5901;:5=5905virsh vncdisplay centos7
# 查看虚拟机完整硬件配置virsh dumpxml centos7
# 修改虚拟机xml配置virsh edit centos73.1.3.1 virsh常用命令
virsh 是 libvirt 提供的核心命令行管理工具:
| 命令 | 功能简述 | 操作示例 |
|---|---|---|
autostart | 设置虚拟机随宿主机开机自动启动 | virsh autostart <虚拟机名称> |
autostart --disable | 取消虚拟机随宿主机开机自动启动 | virsh autostart --disable <虚拟机名称> |
connect | 重新连接到 Hypervisor(虚拟机管理器) | virsh connect <连接URI> |
console | 连接到虚拟机的串口控制台会话 | virsh console <虚拟机名称> |
create | 从 XML 文件创建并立即启动虚拟机 | virsh create <XML文件路径> |
start | 启动一个已定义但处于非活跃状态的虚拟机 | virsh start <虚拟机名称> |
destroy | 强制停止(销毁)一个虚拟机 | virsh destroy <虚拟机名称> |
define | 从 XML 文件定义一个虚拟机(不启动) | virsh define <XML文件路径> |
domid | 将虚拟机名称或 UUID 转换为内部 ID | virsh domid <虚拟机名称或UUID> |
domuuid | 将虚拟机名称或 ID 转换为 UUID | virsh domuuid <虚拟机名称或ID> |
dominfo | 查看虚拟机的详细运行信息 | virsh dominfo <虚拟机名称> |
domstate | 查看虚拟机当前的运行状态 | virsh domstate <虚拟机名称> |
domblkstat | 获取虚拟机磁盘块设备的统计状态 | virsh domblkstat <虚拟机名称> <磁盘设备> |
domifstat | 获取虚拟机网络接口的统计状态 | virsh domifstat <虚拟机名称> <网卡设备> |
domrename | 修改虚拟机的名称 | virsh domrename <原虚拟机名称> <新虚拟机名称> |
dumpxml | 输出虚拟机的 XML 配置信息 | virsh dumpxml <虚拟机名称> |
edit | 编辑虚拟机的 XML 配置文件 | virsh edit <虚拟机名称> |
list | 列出当前所有的虚拟机 | virsh list --all |
migrate | 将虚拟机在线迁移到另一台主机 | virsh migrate <虚拟机名称> <目标主机URI> |
quit | 退出 virsh 非交互式终端 | quit |
reboot | 重新启动指定的虚拟机 | virsh reboot <虚拟机名称> |
resume | 恢复被挂起(suspend)的虚拟机 | virsh resume <虚拟机名称> |
save | 保存虚拟机当前状态到文件并关闭它 | virsh save <虚拟机名称> <保存文件路径> |
dump | 将虚拟机的内核状态转储到文件以便分析 | virsh dump <虚拟机名称> <转储文件路径> |
shutdown | 优雅地关闭虚拟机(发送关机信号) | virsh shutdown <虚拟机名称> |
setmem | 动态改变虚拟机的内存分配大小 | virsh setmem <虚拟机名称> <内存大小> |
setmaxmem | 改变虚拟机允许使用的最大内存限制 | virsh setmaxmem <虚拟机名称> <内存大小> |
suspend | 挂起(暂停)虚拟机的运行 | virsh suspend <虚拟机名称> |
undefine | 删除虚拟机配置(不删除磁盘数据) | virsh undefine <虚拟机名称> |
vcpuinfo | 查看虚拟机的 vCPU 运行信息 | virsh vcpuinfo <虚拟机名称> |
version | 显示 virsh 工具的版本号 | virsh version |
3.1.4 连接虚拟机
在日常的 KVM 运维中,通常的优先级是:SSH > virsh console > VNC。
- 只要虚拟机网络正常,首选 SSH(最安全、最流畅)。
- 如果网络断了或者系统起不来,用
virsh console救急。 - 只有当你真的需要操作图形桌面时,才去配置和使用 VNC。
3.1.4.1 终端连接
也就是ssh连接,走ssh连接
ssh root@192.168.122.343.1.4.2 控制台连接
是一种通过虚拟串行端口(Serial Console)进行命令行管理的方式
要通过 virsh console 连接 KVM 虚拟机,必须预先在虚拟机内部配置串口控制台支持。默认情况下,新创建的虚拟机无法直接使用 virsh console 连接(会卡在空白界面或无响应)。核心步骤分为 虚拟机内部配置 和 宿主机连接操作 两部分,重点在于虚拟机需启用串口终端服务并修改内核参数。
1.虚拟机内部配置
# redhat类# 添加串口控制台参数(关键!)# console=ttyS0,115200n8 表示 将系统日志和登录提示输出到串口 ttyS0,波特率 115200,8 位数据位,无校验位grubby --update-kernel=ALL --args="console=ttyS0,115200n8"# 重启生效reboot
# debian类# 编辑 GRUB 配置sudo nano /etc/default/grub# 修改以下两行(取消注释并添加参数)GRUB_CMDLINE_LINUX_DEFAULT="console=ttyS0,115200n8"# GRUB_TERMINAL=serial 强制 GRUB 引导菜单也通过串口输出,避免卡在启动阶段GRUB_TERMINAL="serial"GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"# 更新 GRUB 并重启sudo update-grubsudo reboot2.启用串口登录服务
# redhat类# 启用串口 getty 服务(自动创建配置)sudo systemctl enable serial-getty@ttyS0.servicesudo systemctl start serial-getty@ttyS0.service
# debian类# 创建 systemd 覆盖配置sudo mkdir -p /etc/systemd/system/serial-getty@ttyS0.service.d/sudo nano /etc/systemd/system/serial-getty@ttyS0.service.d/override.conf# 添加以下内容[Service]ExecStart=ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM# 启用服务sudo systemctl enable serial-getty@ttyS0.servicesudo systemctl start serial-getty@ttyS0.service3.宿主机连接操作
# 验证虚拟机 XML 配置virsh dumpxml <虚拟机名称> | grep -A5 "console\|serial"# 必须包含以下内容<serial type='pty'> <target port='0'/></serial><console type='pty'> <target type='serial' port='0'/></console>
# 连接virsh console <虚拟机名称>
# 退出按 Ctrl + ]3.1.4.3 VNC连接
1.配置VNC
在创建 KVM 虚拟机时,需要指定使用 VNC 作为图形显示方式,并允许外部访问。使用 virt-install 命令时,可以添加如下参数:
# 监听所有网络,设置密码,不指定端口系统默认从5900开始自动分配--graphics vnc,listen=0.0.0.0,password=mypassword2.获取虚拟机VNC端口
虚拟机启动后,需要确认其实际监听的 VNC 端口号。可以使用以下命令查看:
virsh vncdisplay <虚拟机名称># 或virsh domdisplay <虚拟机名称>- 如果输出为
:0,则实际端口为5900。 - 如果输出为
:13,则实际端口为5913(即 5900 + 13)
3.VNC客户端连接
在本地电脑(如 Windows 或 Mac)上安装 VNC 客户端软件(如 TigerVNC、RealVNC Viewer 或 TightVNC),然后输入连接地址:
宿主机IP地址:VNC端口 (例如:192.168.0.160:5913)。
输入正确的地址和端口后,即可看到虚拟机的图形安装界面或操作桌面。
4.通过浏览器访问 (noVNC)
如果不想安装本地 VNC 客户端,可以通过浏览器直接访问。这需要在宿主机上使用 websockify 将 VNC 端口映射到 HTTP 端口:
websockify -D --web=/usr/share/novnc/ 6080 0.0.0.0:<VNC端口>映射完成后,在浏览器中输入 http://宿主机IP:6080/vnc.html 即可直接登录并操作 KVM 虚拟机界面。
# 安装noVNC及依赖# 安装 git 和 python3apt install -y git python3 python3-websockify
# 下载 noVNC 源码cd /optgit clone https://github.com/novnc/noVNC.gitcd noVNCgit clone https://github.com/novnc/websockify.git3.2 迁移虚拟机磁盘
场景:现存在一个kvm虚拟机centos7,他的磁盘文件存放在/kvm/vm/中,但现在宿主机的vda磁盘空间不够,现添加一块磁盘,需要将kvm虚拟机迁移到这块新的磁盘中
3.2.1 关闭虚拟机
在迁移磁盘之前,必须确保虚拟机已完全关机,防止数据丢失
# 发送关机信号virsh shutdown centos7
# 确认虚拟机状态为 "shut off"virsh list --all3.2.2 格式化并挂载磁盘
新加的磁盘在系统中被识别为 /dev/sdb(使用 lsblk 或 fdisk -l 确认实际设备名)
# 1.格式化新磁盘(以 XFS 文件系统为例)mkfs.xfs /dev/sdb
# 2.创建挂载点并挂载# 创建新的KVM存储目录mkdir -p /new_kvm_storage
# 将新磁盘挂载到该目录mount -t xfs /dev/sdb /new_kvm_storage/
# 3.配置开机自动挂载# 获取新磁盘的UUIDblkid /dev/sdb
# 编辑 fstab 文件,将类似 UUID="xxxx-xxxx" /new_kvm_storage xfs defaults 0 0 追加到末尾vi /etc/fstab3.2.3 迁移虚拟机磁盘文件
将原磁盘文件移动到新挂载的目录中
# 将 /kvm/vm/ 下的所有文件移动到 /new_kvm_storage/mv /kvm/vm/* /new_kvm_storage/
# 验证文件是否成功移动ls -lh /new_kvm_storage/3.2.4 修改虚拟机配置并启动
由于磁盘的物理路径发生了变化,需要更新 KVM 的 XML 配置文件,让虚拟机知道去哪里找新的磁盘。
# 1. 修改配置文件virsh edit chentos7
# 在打开的 XML 文件中,找到 <disk> 标签下的 <source file='...'/> 行,将旧路径修改为新路径。<!-- 修改前 --><source file='/kvm/vm/centos7.qcow2'/>
<!-- 修改后 --><source file='/new_kvm_storage/centos7.qcow2'/>
# 2.启动虚拟机virsh start centos7
# 3. 验证虚拟机# 确认虚拟机正常运行virsh list
# 验证新磁盘路径是否生效virsh domblklist centos73.3 磁盘管理
3.3.1 磁盘格式
3.3.1.1 raw 格式
raw 是 KVM 默认的虚拟磁盘格式,本质上是一个简单的原始二进制数据流文件。
- 性能极高:由于数据块与物理存储直接映射,没有额外的元数据处理层或转换开销,其 I/O 性能最好,几乎接近物理磁盘。
- 空间占用固定:创建时会立即预分配全部指定的磁盘空间。例如,创建一个 50G 的 raw 镜像,会直接占用宿主机 50G 的物理空间,即使虚拟机内只使用了 1G。
- 功能受限:不支持虚拟机的快照功能,也不支持数据压缩和加密。
- 适用场景:适用于对磁盘 I/O 性能要求极高、不需要频繁做快照的生产环境。
3.3.1.2 qcow2 格式
qcow2 是目前 KVM 环境中最主流、最推荐的磁盘格式,其核心设计理念是“写时复制”(Copy-On-Write)。
- 空间利用率高(动态扩容):采用稀疏存储机制,初始创建时仅占用极小的物理空间(约 MB 级),随着虚拟机实际写入的数据量逐渐动态增长,支持磁盘空间超配。
- 功能丰富:原生支持多级快照(Snapshot),方便进行系统备份和回滚;支持 zlib 磁盘压缩以节约存储空间;支持 AES 加密以保障数据安全。
- 性能表现:由于存在元数据寻址等开销,其性能略逊于 raw 格式(通常有约 5% 的性能损耗),但在经过 virtio 优化后,两者差异已经非常小,完全能够满足绝大多数业务需求。
- 适用场景:推荐作为首选格式,广泛适用于测试环境、需要频繁快照备份的场景以及云计算系统。
3.3.2 磁盘信息查看
# 查看默认格式的磁盘文件[root@kvm-150 ~] $ du -h /kvm/vm/centos7.raw1.4G /kvm/vm/centos7.raw
# 查看磁盘文件信息[root@kvm-150 ~]#qemu-img info /kvm/vm/centos7.rawimage: /kvm/vm/centos7.rawfile format: rawvirtual size: 10G (10737418240 bytes)disk size: 1.9G3.3.3 创建磁盘文件
使用qemu-img create -f <格式> <文件名> <大小>新建一个虚拟磁盘文件
# 创建一个 30G 的 qcow2 格式磁盘qemu-img create -f qcow2 /kvm/vm/openeuler.qcow2 30G3.3.4 转换/压缩磁盘文件
convert用于在不同磁盘格式之间进行转换,或者对镜像进行压缩和稀疏化处理。
-
基本语法:
qemu-img convert -f <源格式> -O <目标格式> <源文件> <目标文件> -
示例:将 raw 格式转换为 qcow2 格式并启用压缩(
-c参数):-
Terminal window qemu-img convert -f raw -O qcow2 -c old.raw new.qcow2
-
-
示例:将 VMware 的 vmdk 格式转换为 qcow2,并显示进度条(
-p参数):-
Terminal window qemu-img convert -p -f vmdk -O qcow2 centos.vmdk centos.qcow2
-
3.3.5 磁盘文件容量调整
resize用于扩大或缩小虚拟磁盘的容量
-
基本语法:
qemu-img resize <文件名> <+/-大小> -
示例:将磁盘容量增加 5G:
-
Terminal window qemu-img resize disk.qcow2 +5G
-
3.3.6 磁盘文件完整性检查
check用于检查镜像文件的内部一致性和完整性,常用于排查镜像损坏问题
- 基本语法:
qemu-img check -f <格式> <文件名>
qemu-img check -f qcow2 disk.qcow23.3.3.7 修改后端磁盘文件*
rebase用于修改差异磁盘(Backing File)的依赖关系
-
基本语法:
qemu-img rebase -f <格式> -b <新后端文件> <差异镜像> -
示例:
-
Terminal window qemu-img rebase -f qcow2 -b new_base.qcow2 diff.qcow2
-
-
后端镜像
在 KVM 中,你可以基于一个基础镜像(例如一个装好操作系统的母盘)创建一个差异镜像。这个差异镜像只记录相对于母盘的“修改部分”,从而极大地节省了存储空间。而
rebase命令的核心作用,就是更改这个差异镜像所依赖的“母盘”。1.修复移动或重命名后的母盘
如果你的母盘文件被移动到了其他目录,或者更改了文件名,依赖它的差异镜像就会因为找不到母盘而无法启动。此时可以使用
rebase的不安全模式(-u参数)来直接更新母盘的路径,而无需进行耗时的数据合并。示例:母盘从
/old/path/base.qcow2移动到了/new/path/base.qcow2Terminal window qemu-img rebase -u -b /new/path/base.qcow2 diff.qcow22.合并基础镜像更新
假设你有一个包含操作系统的基础母盘,并基于它创建了多个虚拟机的差异镜像。后来你更新了基础母盘(比如安装了最新的安全补丁)。你可以使用
rebase的安全模式(默认模式),将差异镜像的依赖切换到这个更新后的新母盘上。-
示例:
-
Terminal window # -f 指定源镜像(diff.qcow2)的格式,-b new_base.qcow2:指定新的母盘(后端镜像)# diff.qcow2:需要被修改依赖关系的差异镜像qemu-img rebase -f qcow2 -b new_base.qcow2 diff.qcow2
- 原理:在安全模式下,
qemu-img会执行一个非常严谨的数据对比过程-
- 它会将
diff.qcow2中的每一个数据块,与旧母盘进行对比,找出那些diff.qcow2中没有修改过的数据块 - 将这些未修改的数据块,从旧母盘中读取出来,然后与新母盘 (
new_base.qcow2) 中的对应位置进行对比 - 如果新旧母盘在这个位置的内容不同,
qemu-img就会把旧母盘的这个数据块写入(合并)到diff.qcow2中 - 最后,将
diff.qcow2的母盘指针安全地指向new_base.qcow2
- 它会将
-
3.重构镜像链
在复杂的虚拟化环境中,有时需要调整镜像的依赖层级。例如,原本 A 依赖于 B,B 依赖于 C,现在你想让 A 直接依赖于 C,或者将 A 的母盘替换为完全不同的 D 镜像。
rebase可以安全地完成这种底层数据结构的重组。 -
3.4 克隆虚拟机
3.4.1 完整克隆
完整克隆是对源虚拟机的配置文件和虚拟磁盘文件进行深度的、物理上的完整复制。克隆后的虚拟机是一个完全独立的副本,与源虚拟机之间没有任何数据共享。
- 优点:独立性极强。克隆体与源虚拟机互不影响,即使删除了源虚拟机,克隆出的虚拟机依然可以正常运行。此外,它的性能隔离性更好,不存在资源争用问题。
- 缺点:创建速度较慢,且需要占用与源虚拟机同等大小的存储空间。
virt-clone --auto-clone -o <源虚拟机名称> -n <新虚拟机名称>-o:指定原始虚拟机(Original)。-n:指定克隆后的新虚拟机名称(Name)。--auto-clone:自动克隆选项。系统会自动生成新的磁盘文件路径,并自动为新虚拟机分配新的 UUID 和 MAC 地址,避免与原虚拟机冲突。
3.4.2 链接克隆
链接克隆并不会完整拷贝源虚拟机的磁盘文件,而是创建一个较小的“差异磁盘文件”。新克隆的虚拟机与源虚拟机共享大部分基础磁盘数据,仅将自身运行过程中产生的新数据或修改记录保存在差异磁盘中。
-
优点:创建速度极快,且占用的物理存储空间非常小,非常适合存储资源有限的环境或需要快速批量扩容的场景。
-
缺点:强依赖性。链接克隆的虚拟机必须依赖源虚拟机的磁盘文件才能运行。如果源虚拟机被删除或其磁盘文件损坏,所有基于它的链接克隆虚拟机都将无法启动
-
操作步骤:
-
Terminal window # 1.使用 qemu-img 命令基于源磁盘创建差异磁盘文件,-b:指定基础镜像(Backing file)的路径qemu-img create -f qcow2 -b /path/to/source_disk.qcow2 /path/to/new_disk.qcow2# 2.生成并修改配置文件,即导出源虚拟机的 XML 配置文件,并进行关键修改:# 导出XML配置virsh dumpxml <源虚拟机名称> > /path/to/new_vm.xml# 编辑配置文件(必须修改以下四项以避免冲突)vim /path/to/new_vm.xml -
Terminal window # 在 XML 文件中,你需要进行以下修改:# 1.修改虚拟机名称:更改 <name> 标签内的名称,确保全局唯一。# 2.删除 UUID:直接删除 <uuid>...</uuid> 标签,启动时系统会自动生成新的 UUID。# 3.删除 MAC 地址:删除 <mac address='...'/> 标签,防止局域网内 MAC 地址冲突导致无法联网。# 4.修改磁盘路径:将 <source file='...'/> 的路径修改为第一步中创建的差异磁盘路径。 -
Terminal window # 导入并启动虚拟机virsh define /path/to/new_vm.xmlvirsh start <新虚拟机名称>
-
3.5 快照管理
快照管理主要包含创建、查看、恢复和删除四个核心操作,快照用于保存虚拟机在特定时间点的状态,便于回滚和测试
在执行快照操作前,必须确保虚拟机的虚拟磁盘格式为 qcow2。最基础的 raw 格式不支持快照功能。如果当前是 raw 格式,需要先使用 qemu-img convert 命令将其转换为 qcow2 格式。
3.5.1 命令行管理
使用 virsh 工具可以高效地进行快照管理
3.5.1.1 查看快照
查看某个虚拟机下已创建的所有快照:
virsh snapshot-list <虚拟机名称>3.5.1.2 创建快照
使用 snapshot-create-as 命令为指定虚拟机创建快照,并可以添加描述信息以便日后识别
virsh snapshot-create-as --domain <虚拟机名称> --name <快照名称> --description "快照描述"3.5.1.3 恢复快照
将虚拟机回滚到指定的快照状态。注意:为了保证数据一致性,执行此操作前通常需要先关闭虚拟机:
virsh snapshot-revert <虚拟机名称> <快照名称>3.5.1.4 删除快照
当确认不再需要某个快照时,可以将其删除以释放存储空间:
virsh snapshot-delete <虚拟机名称> <快照名称>3.5.2 图形界面管理
使用 virt-manager进行图形界面管理快照
- 打开 virt-manager 并选中目标虚拟机。
- 在界面上方点击“快照”图标(通常是两个重叠的方块或类似图标)。
- 在弹出的快照管理器中,你可以直观地点击“创建新快照”,或者对已有的快照进行“恢复”和“删除”操作。
3.5.3 常用快照管理命令
| 命令 | 功能简述 | 操作示例 |
|---|---|---|
snapshot-create | 通过读取 XML 文件创建快照 | virsh snapshot-create <虚拟机名称> <XML文件路径> |
snapshot-create-as | 通过命令行参数快速创建快照 | virsh snapshot-create-as <虚拟机名称> <快照名称> "<快照描述>" |
snapshot-current | 获取或设置当前活动的快照 | virsh snapshot-current <虚拟机名称> |
snapshot-delete | 删除指定的虚拟机快照 | virsh snapshot-delete <虚拟机名称> <快照名称> |
snapshot-dumpxml | 输出快照的 XML 配置详情 | virsh snapshot-dumpxml <虚拟机名称> <快照名称> |
snapshot-edit | 编辑快照的 XML 配置 | virsh snapshot-edit <虚拟机名称> <快照名称> |
snapshot-info | 查看快照的元数据信息 | virsh snapshot-info <虚拟机名称> <快照名称> |
snapshot-list | 列出虚拟机的所有快照 | virsh snapshot-list <虚拟机名称> |
snapshot-parent | 查看指定快照的父级快照 | virsh snapshot-parent <虚拟机名称> <快照名称> |
snapshot-revert | 将虚拟机回滚恢复到指定快照 | virsh snapshot-revert <虚拟机名称> <快照名称> |
3.6 热添加技术
KVM虚拟机的热添加(Hot Plugging)技术允许在虚拟机保持运行(不关机)的状态下,动态为其添加或移除虚拟硬件资源。这极大地提高了服务器的灵活性和可扩展性。目前,KVM主要支持对CPU、内存、硬盘和网卡进行热添加操作。
3.6.1 CPU热添加
CPU热添加只能增加核心数,不支持热删除(减少)。
-
前提条件:必须预先设置虚拟机允许的最大CPU数量(maxvcpus)。如果创建时未设置,需要先关机修改配置文件(例如
<vcpu placement='auto' current='1'>4</vcpu>),然后重启虚拟机。 -
临时生效(重启失效):
-
Terminal window virsh setvcpus <虚拟机名称> <目标CPU数量> --live
-
-
永久生效:
-
Terminal window virsh setvcpus <虚拟机名称> <目标CPU数量> --config
-
- 对于部分Linux系统,热添加后可能需要在虚拟机内部手动激活新CPU(例如执行
echo 1 > /sys/devices/system/cpu/cpuX/online
3.6.2 内存热添加
内存热添加支持动态扩容和缩容(内存气球机制),但调整后的内存总量不能超过预先设置的最大内存上限。
-
前提条件:需提前设置最大内存(maxmemory)。若需提升上限,必须关机修改配置(例如
<memory unit='KiB'>4048576</memory>)后重启。 -
临时调整内存大小:
-
Terminal window # 扩容或缩容内存virsh setmem <虚拟机名称> <目标内存大小> --live
-
-
永久调整内存大小:
-
Terminal window virsh setmem <虚拟机名称> <目标内存大小> --config
-
-
修改最大内存上限(需在关机状态下执行):
-
Terminal window virsh setmaxmem <虚拟机名称> <新最大内存> --config
-
3.6.3 硬盘热添加
支持在虚拟机运行时动态挂载新的虚拟磁盘。
-
创建新磁盘文件:
Terminal window qemu-img create -f qcow2 /path/to/new_disk.qcow2 5G -
临时挂载新磁盘(vdb为虚拟机内的目标设备名):
Terminal window virsh attach-disk <虚拟机名称> /path/to/new_disk.qcow2 vdb --subdriver qcow2 -
永久挂载新磁盘(写入配置文件并立即生效):
Terminal window virsh attach-disk <虚拟机名称> /path/to/new_disk.qcow2 vdb --subdriver qcow2 --config --live -
后续操作:添加完成后,需进入虚拟机内部对新磁盘进行格式化(如
mkfs.ext4 /dev/vdb)并挂载。 -
卸载磁盘:
Terminal window virsh detach-disk <虚拟机名称> vdb --live --config
3.6.4 网卡热添加
支持动态为虚拟机添加新的虚拟网卡。
-
临时添加桥接网卡:
Terminal window virsh attach-interface <虚拟机名称> --type bridge --source br0 --model virtio -
永久添加桥接网卡:
Terminal window virsh attach-interface <虚拟机名称> --type bridge --source br0 --model virtio --config -
移除网卡(需指定要移除网卡的MAC地址):
Terminal window virsh detach-interface <虚拟机名称> --type bridge --mac <MAC地址> -
后续操作:进入虚拟机后,新网卡通常会被识别为新的网络接口(如eth1),需配置IP地址并启用。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
赣公网安备36072602000131号