如何防止KVM所用qcow2镜像在宿主机文件系统中无限增长
如何防止KVM所用qcow2镜像在宿主机文件系统中无限增长
嘿,我太懂这种qcow2镜像悄悄在宿主机上疯长的烦恼了!先看看你给出的镜像信息,里面能找到不少关键线索:
image: my_vm.qcow2 file format: qcow2 virtual size: 125 GiB (134217728000 bytes) disk size: 173 GiB cluster_size: 65536 Snapshot list: ID TAG VM SIZE DATE VM CLOCK ICOUNT 1 1714792201 19.7 GiB 2024-05-04 05:10:01 06:24:17.339 2 1714878601 30.5 GiB 2024-05-05 05:10:01 30:22:58.504 3 1714965001 30.6 GiB 2024-05-06 05:10:01 54:21:23.382 Format specific information: compat: 1.1 compression type: zlib lazy refcounts: false refcount bits: 16 corrupt: false extended l2: false
比如这里的disk size: 173 GiB已经超过了虚拟大小125GiB,还有3个占用空间不小的快照,这些都是镜像膨胀的核心原因。下面给你几个实用的解决办法:
1. 清理冗余快照,合并增量数据
快照是qcow2镜像变大的头号原因——每个快照都会保留镜像的某一状态,后续所有写入都会存在增量文件里,时间久了就会堆出大量空间占用。
- 先排查哪些快照是没用的:比如旧的测试快照、已经备份过的历史状态
- 删除单个快照用这个命令(比如删除ID为1的快照):
qemu-img snapshot -d 1 my_vm.qcow2 - 要是想彻底把快照的增量数据合并回基础镜像,先关闭虚拟机,再执行:
合并完成后再删除快照,就能真正把空间还给宿主机了。qemu-img commit my_vm.qcow2
2. 回收虚拟机内部的空闲空间
虚拟机里删除文件后,宿主机上的qcow2镜像不会自动缩小——那些被删掉的文件占用的空间还会留在镜像里。得手动回收:
- 先在虚拟机内部,用
zerofree把空闲分区填充为0(要注意:得先卸载目标分区,或者进入单用户模式操作,避免文件系统被占用):
把路径换成你虚拟机里的实际LVM分区路径就行zerofree /dev/mapper/vg0-root - 关闭虚拟机后,在宿主机上用
qemu-img convert压缩镜像,回收空闲空间:
这里qemu-img convert -O qcow2 -c my_vm.qcow2 my_vm_compressed.qcow2-c用的是你当前镜像的zlib压缩格式,转换完可以把新镜像替换原镜像,原镜像记得备份后再删。
3. 调整镜像参数,从根源控制增长
从你的镜像信息看,lazy refcounts是false,开启它能减少运行时的不必要写入,限制镜像膨胀:
- 关闭虚拟机后,修改这个参数:
qemu-img amend -o lazy_refcounts=on my_vm.qcow2 - 另外,还可以设置镜像的最大虚拟尺寸,避免虚拟机内部的文件系统无限制扩容(要确保虚拟机里的实际文件系统大小不超过这个值):
qemu-img resize my_vm.qcow2 120G
4. 定期监控,防患于未然
养成定期检查的习惯,用这两个命令跟踪镜像大小:
- 查看镜像的详细信息:
qemu-img info my_vm.qcow2 - 查看镜像在宿主机上的实际占用:
du -sh my_vm.qcow2
一旦发现大小异常增长,就可以及时用上面的方法处理。
备注:内容来源于stack exchange,提问作者manifestor




