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

bma*_*ser 31 disk-image qemu qcow2 kvm-virtualization

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

qcow2 有一个很好的特性,镜像文件只分配虚拟机实际需要的空间。但是,如果虚拟机的分配空间变小,我如何缩小映像文件?

例子:

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

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

3.) 我用大约 40 GB 的附加数据填充了图像。图像文件增长到 50GB。我没问题:-)

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

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

提前致谢,伯尼

dya*_*sny 30

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

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

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

  • 如果您有 Windows 来宾运行 [SDelete](https://technet.microsoft.com/en-us/sysinternals/sdelete.aspx) -z 将所有可用空间清零(上面的步骤 1,2) (3认同)

小智 20

virt-sparsify 可以轻松完成所有这些工作:http ://libguestfs.org/virt-sparsify.1.html

  • @dyasny如果有人想花精力写一个新的高质量答案,每次旧答案过时时,都应该鼓励他们这样做。关于如何处理过时答案的更彻底的讨论更适合元。 (5认同)
  • @dyasny 如果旧问题的现有答案随着时间的推移已经过时,那么值得写一个新答案。然而,这个特定的新答案可能不符合本网站的标准。 (4认同)

nde*_*mou 9

您可以使用virt-sparsify来实现此目的。它会自动对源磁盘映像中找到的大多数文件系统上的可用空间进行清零和稀疏化(支持 ext2/3/4、btrfs、NTFS 等)。

就地转换的分步说明

  1. 关闭虚拟机

  2. 保留备份

  3. 转变:virt-sparsify --in-place disk.img

转换为另一个文件的分步说明(这更安全,但需要更多可用空间):

  1. 关闭虚拟机

  2. 转变:virt-sparsify disk.img new-file.img

  3. 将旧图像文件替换为新图像文件:mv disk.img disk.img.bak && mv new-file.img disk.img

  4. 如果虚拟机正常启动,您可以删除备份:rm disk.img.bak

PS:使用 virt-sparsify 时还可以在格式之间进行转换:

virt-sparsify disk.raw --convert qcow2 disk.qcow2
Run Code Online (Sandbox Code Playgroud)


sho*_*hok 8

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

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

注意:qemu 4.x 也添加了discard对 Trim 的支持virtio-blk,不再需要virtio-scsiTrim 来工作。

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

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