qemu-img 完全指南:虚拟化镜像生命周期与核心概念深度解析

从创建到回收,深入理解 qcow2 的写时复制、快照链与最佳实践

作为一名虚拟化工程师,每天与 KVM/QEMU 打交道,绕不开一个核心工具------qemu-img。它不仅是创建虚拟机磁盘的"刻刀",更是管理镜像整个生命周期(创建、快照、扩容、转换、合并、回收)的瑞士军刀。本文将系统梳理 qemu-img 管理虚拟机系统盘与数据盘镜像的常用方法,并深入剖析几个关键概念(qcow2、后端镜像、写时复制、预分配、快照链)及其相互之间的关系。


一、基础:安装与工具速览

在大部分 Linux 发行版中,qemu-img 包含在 qemu-utilsqemu-kvm 包中:

bash 复制代码
# RHEL / CentOS
yum install qemu-img
# Ubuntu / Debian
apt install qemu-utils

qemu-img 支持 createinforesizeconvertsnapshotcheckcommit 等子命令,覆盖了镜像从"生"到"灭"的全过程。


二、核心概念:你必须理解的几张"王牌"

在动手操作前,先厘清几个关键概念及其关系,这是理解生命周期管理的基石。

2.1 raw vs qcow2 -- 格式之争

特性 raw qcow2
简单直接 裸二进制,性能最好 复杂元数据,略有开销
稀疏文件 支持(需文件系统支持) 原生支持
实际占用 始终等于虚拟大小(除非稀疏) 仅占用实际写入大小
快照 不支持(需借助外部链) 内置内部快照 + 外部差分盘
后端镜像 不支持 支持(backing file)
压缩/加密 不支持 支持

结论系统盘、需快照/回滚的场景选 qcow2;追求极致 I/O 且无快照需求的数据盘可选 raw 。本文重点围绕 qcow2 展开。

2.2 写时复制 (Copy-on-Write, COW) 与后端镜像

这是 qcow2 最强大的特性。创建一个带 -b backing_file 的镜像时,新镜像(称为"差分盘"或"前端盘")只记录相对于后端镜像的变化。

  • 后端镜像:通常设为"只读"的基础镜像(如安装好 OS 的模板)
  • 前端镜像:可写,所有读操作先查前端,未命中则读后端;所有写操作写入前端。

关系图

复制代码
  +-------------+        +-------------+
  |  前端镜像A   | -----> |  后端镜像    |
  |  (差分盘)   | 依赖   |  (只读模板)  |
  +-------------+        +-------------+
        |                       |
        +------ 链式依赖 ---------+

多个前端可以共享同一个后端,节省大量磁盘空间并加速部署。

2.3 快照链 (Snapshot Chain)

  • 内部快照 :保存在同一个 qcow2 文件内,使用 qemu-img snapshot -c 创建。缺点:单文件过大,删除快照不能立即释放空间。
  • 外部快照 :即通过 -b 创建新的差分盘,形成链:base <- snap1 <- snap2。回滚时只需更换前端文件或执行 commit

关系说明
后端镜像 + COW 机制 = 实现外部快照链的基础。每个差分盘本质上就是后端镜像的一个"可写快照"。

2.4 预分配 (Preallocation)

创建 qcow2 时可指定 -o preallocation=

  • off(默认):稀疏文件,按需分配,创建快但首次写入有延迟。
  • metadata:预先分配元数据(簇指针),减轻运行时元数据分配开销,推荐用于性能敏感场景(如数据库数据盘)。
  • falloc / full:立即分配全部数据空间(falloc 更快,ext4/xfs 支持)。适合需要提前占用物理空间或避免运行期扩容抖动的场景。

三、生命周期管理全流程

3.1 创建 (Create)

1. 创建一个新的空数据盘(20GB)

bash 复制代码
qemu-img create -f qcow2 data01.qcow2 20G

2. 创建后端基础镜像(例如纯净系统盘)

bash 复制代码
qemu-img create -f qcow2 centos7-base.qcow2 40G
# 之后使用虚拟机安装OS,完毕后保持此镜像只读

3. 基于后端镜像创建差分盘(外部快照)

bash 复制代码
qemu-img create -f qcow2 -b centos7-base.qcow2 -F qcow2 vm01-system.qcow2
  • -b 指定后端镜像
  • -F 明确指定后端格式(提高安全性)

4. 创建高性能数据盘(预分配元数据)

bash 复制代码
qemu-img create -f qcow2 -o preallocation=metadata data-mysql.qcow2 100G

5. 创建加密数据盘(LUKS,推荐)

bash 复制代码
qemu-img create -f qcow2 -o encryption=on,encrypt.key-secret=sec0 \
  --object secret,data=MyStrongPassword,id=sec0 secret-disk.qcow2 10G

3.2 查看信息 (Info)

bash 复制代码
qemu-img info vm01-system.qcow2

输出示例:

复制代码
image: vm01-system.qcow2
file format: qcow2
virtual size: 40 GiB (42949672960 bytes)
disk size: 1.2 GiB
cluster_size: 65536
backing file: centos7-base.qcow2
backing file format: qcow2
Snapshot list:
ID        TAG                 VM SIZE                DATE
1         before-update        123M 2025-03-15 10:23:14

重点看 backing file 字段(表示存在后端依赖)和 Snapshot list

3.3 调整大小 (Resize)

扩容(最常用)

bash 复制代码
qemu-img resize vm-data.qcow2 +50G   # 增加50G
qemu-img resize vm-data.qcow2 100G   # 直接设为目标大小(必须比原大)

⚠️ 扩容后需要在虚拟机内部使用 fdisk / growpart 扩展分区,再 resize2fs(ext4)或 xfs_growfs

缩减(极少用,高风险)

必须先确保镜像内文件系统已缩减,再用 qemu-img resize --shrink,且强烈建议先转换后使用 --shrink 检查。

3.4 转换 (Convert)

raw → qcow2

bash 复制代码
qemu-img convert -f raw -O qcow2 disk.raw disk.qcow2

qcow2 → raw(合并后端链)

bash 复制代码
qemu-img convert -f qcow2 -O raw vm01-system.qcow2 vm01-system.raw

该命令会将差分盘与后端镜像(及整条链)合并输出到一个 raw 文件。

仅合并差分盘到后端(不改变格式)

bash 复制代码
qemu-img convert -f qcow2 -O qcow2 vm01-system.qcow2 merged.qcow2

带压缩的转换(节省空间)

bash 复制代码
qemu-img convert -f qcow2 -O qcow2 -c vm-data.qcow2 vm-data-compressed.qcow2

-c 开启压缩,适合归档冷数据。

3.5 快照管理 (Snapshot)

内部快照(同一文件内):

bash 复制代码
qemu-img snapshot -c clean_install vm01-system.qcow2          # 创建
qemu-img snapshot -l vm01-system.qcow2                        # 列出
qemu-img snapshot -a clean_install vm01-system.qcow2          # 还原
qemu-img snapshot -d clean_install vm01-system.qcow2          # 删除

⚠️ 内部快照的性能和灵活性不如外部差分盘,大型生产环境更推荐外部快照。

外部快照(通过创建新差分盘实现)

假设当前运行的 active.qcow2 依赖 base.qcow2,创建快照并切换:

bash 复制代码
# 1. 创建新差分盘作为当前快照
qemu-img create -f qcow2 -b active.qcow2 -F qcow2 snap1.qcow2
# 2. 之后虚拟机改用 snap1.qcow2 继续运行,active.qcow2 成为只读快照点

3.6 提交与合并 (Commit)

将差分盘的改动合并回后端镜像,简化链结构:

bash 复制代码
qemu-img commit -b new-base.qcow2 diff.qcow2

或者使用 qemu-img convert 先合并再替换。

3.7 检查与修复 (Check)

bash 复制代码
qemu-img check -r all trouble.qcow2

用于修复 qcow2 文件因意外关机导致的损坏。-r all 会尝试修复引用计数和泄漏簇。

3.8 回收与废弃

  • 删除差分盘 :如果不再需要某个快照点,直接 rm 文件即可(注意确认没有其他镜像依赖它)。

  • 回收 qcow2 实际空间 :虚拟机内删除大文件后,qcow2 通常不会自动收缩。可先运行 fstrim(客户机内),然后执行:

    bash 复制代码
    qemu-img convert -O qcow2 disk.qcow2 disk_shrunk.qcow2

    转换相当于重写一次,丢弃空闲簇。


四、典型场景最佳实践

场景1:快速部署一批开发/测试虚拟机

  1. 制作一个"黄金镜像"golden.qcow2(安装好 OS 和基础软件)。

  2. 对每个虚拟机创建差分盘:

    bash 复制代码
    qemu-img create -f qcow2 -b golden.qcow2 -F qcow2 vm_{id}.qcow2
  3. 启动虚拟机,所有更改保存在各自的差分盘中,物理空间节省 80% 以上。

  4. 测试完毕后直接删除差分盘即可回滚到初始状态。

场景2:数据库数据盘(性能与安全)

  • 创建时使用 -o preallocation=metadata 减少运行时 I/O 抖动。
  • 挂载 virtio 驱动并启用 cache=none + aio=native
  • 定期使用 qemu-img convert -c 归档冷备数据盘。
  • 敏感数据使用 LUKS 加密创建。

场景3:处理长时间运行的快照链

  • 避免链长度超过 10 层,否则读性能会退化。
  • 定期执行 qemu-img commitconvert 合并链。
  • 合并前关机虚拟机,或者使用 qemu-img rebase 动态调整后端(高风险,需细心)。

五、概念关系总结

text 复制代码
         +-------------------+
         |     raw 格式       |  (简单, 快, 无快照)
         +-------------------+
                    |
                    v (convert)
         +-------------------+        -b依赖       +----------------+
         |     qcow2 格式     | <----------------  |   后端镜像      |
         +-------------------+      (写时复制)      | (只读模板)      |
                    |                               +----------------+
                    | 创建内部快照                          |
                    v                               +----------------+
         +-------------------+                      |  差分盘1 (VM1) |
         |  同一文件快照链表  |                      +----------------+
         +-------------------+                      |  差分盘2 (VM2) |
                                                    +----------------+
         qemu-img snapshot -c                           (外部快照)

          预分配 (preallocation)
         +-------+--------+
         | off | metadata | falloc
         +-------+--------+

核心关系

  • 后端镜像 + qcow2 = 写时复制差分盘(外部快照)
  • 差分盘可以串成链,实现任意时间点回滚。
  • 内部快照是另一个维度,保存在文件内部,适合临时备份。
  • 预分配影响首次写入性能与物理空间占用。
  • convert 是合并链、压缩、转换格式、回收空间的全能手段。

掌握这些概念与命令,你就能像管理代码版本一样管理虚拟磁盘的生命周期。qemu-img 虽小,却是虚拟化世界的 git------善用它,你将获得对磁盘镜像的完全掌控力。

🧠 思考题:一个虚拟机同时有内部快照和外部差分盘,提交顺序如何影响数据完整性?欢迎在评论区讨论。


本文作者 :虚拟化实践者 · 文章编号 2026-05-14
许可:自由转载,请保留出处。

相关推荐
tianyuanwo4 个月前
QEMU-img 缓冲区溢出错误(SIGABRT)分析与系统性解决方案
virt-sparsify·buffer overflow·qemu-img