释放 kvm/qemu 上 qcow2-image-file 中未使用的空间

释放 kvm/qemu 上 qcow2-image-file 中未使用的空间

我们正在使用带有 qcow2-images 的 kvm/qemu 作为虚拟机。

qcow2 有一个很好的功能,即图像文件仅分配虚拟机实际需要的空间。但是,如果虚拟机的分配空间变小,我该如何缩小图像文件?

例子:

1.) 我创建了一个 qcow2 格式的新图像,大小为 100GB

2.) 我使用此映像来安装 ubuntu。安装需要大约 10 GB,映像文件最大增大到大约 10GB。到目前为止没有什么意外。

3.) 我在图像中填充了大约 40 GB 的额外数据。图像文件大小增加到了 50GB。我对此没意见 :-)

4.) 奇怪的地方就在这里:我删除了图像上的所有 40GB 数据,但图像大小仍然占用了 50GB。

问题:我如何释放 40GB 的数据并将图像缩小到仅需要的 10 GB?

提前致谢,伯尼

答案1

virt-sparsify 可以完成所有这些工作,减少您的麻烦: http://libguestfs.org/virt-sparsify.1.html

答案2

图像不会自动缩小,因为删除文件时实际上并没有删除数据(这就是取消删除功能起作用的原因)。Qemu 有一个功能可以将 qcow2 图像缩小,但该实用程序实际上所做的是从磁盘中删除重复的零,而其他所有信息保持不变。因此,这个想法是:

  1. 将驱动器填零(dd if=/dev/zero of=/some/file直到空间不足)
  2. 删除/一些/文件
  3. 关闭虚拟机
  4. cd 到虚拟机镜像保存的位置并运行qemu-img convert -O qcow2 original_image.qcow2 deduplicated_image.qcow2
  5. 更改虚拟机设置以使用新的 deduplicated_image.qcow2,测试虚拟机是否正常工作,然后删除旧映像

据我所知,这只适用于 qcow2 图像,我还没有测试其他格式。

答案3

除了可接受的答案(描述了缩小 qcow2 文件的更常见、更通用的方法)之外,libvirt/qemu/qcow2 堆栈的现代版本(即:RHEL7+)提供了virtio-scsi支持该discard='unmap'选项的驱动程序。

如果虚拟机使用virtio-scsi并且 libvirt 定义包含discard='unmap',则客户机文件系统上的简单操作fstrim将释放主机上已分配但未使用的可用空间。这可以du -hs <guestdisk>在主机端使用进行检查(注意:ls -al <guestdisk>不是显示实际分配的大小,仅是逻辑分配的大小)。

注意:qemu 4.x 也添加了discard对的支持virtio-blk,因此不再需要virtio-scsitrim 才能工作。

在较新的 libvirt/qemu 实例(即 RHEL8+)上,使用时,virtio-scsi即使客户机操作系统不支持 trim,也可以减少客户机文件大小:通过启用两个都 discard='unmap'并且discard_zeroes='unmap'在客户机端写入连续的零流(即通过dd if=/dev/zero of=/zero.img bs=1M count=1024)将触发受影响的 LBA 范围的主机大小修剪。但是,请注意,这可能会占用大量 CPU(主机必须“解析”任何客户机写入以搜索重复的零),因此应仅在特定情况下启用它。

这两种方法都会减少身体的分配的大小(du -hs显示的内容)。为了减少逻辑大小(简单ls -al给出的内容),您需要使用virt-spasifyqemu-img(如其他答案中所述)。

答案4

virt-sparsify --compress fileA fileB会减小图像的大小,但是它会将 qcow2 图像创建为另一个文件,因此您必须重命名和移动其中的内容。您不能同时使用--compress和。请参阅以下链接以了解更多信息。--in-placehttp://libguestfs.org/virt-sparsify.1.html

相关内容