如何“真正”减少 KVM VM 映像的大小?

如何“真正”减少 KVM VM 映像的大小?

我花了很多时间在网上搜索如何缩小 KVM 虚拟磁盘映像,特别是针对 Windows 客户机,但没有任何收获。

我发现只需将虚拟机可用空间归零,对虚拟磁盘进行碎片整理(从 Windows),然后运行qemu-img convert -c ...-c标志以压缩)。

我有一台 Windows 7 VM,虚拟驱动器大小为 100 GB。最初,此 VDD 在主机存储上占用了 40 GB。一旦将其归零,VDD 就会在主机上真正占用 100 GB。并qemu-img -c ...创建了 91 GB,这完全不是我所期望的。

在 modernie 网站上,我们可以下载小于 10 GB 的 W7 VM,这是怎么可能的?有没有办法“真正”压缩 VM 映像?


感谢@dyasny,我用 做了一个小测试virt-sparsity。我清理了 W7 VM 磁盘,禁用了休眠,因此 VDD 仅消耗 20 GB。再次降级磁盘,然后再次运行sdelete -zvirt-sparsity使用该--compress标志运行时会得到 80 GB 的虚拟驱动器。与我的期望相差甚远。


EDIT-2016-02-16:“刷新”这个问题,因为这里讨论的缩小虚拟机的方法非常有效,但有一个主要缺点:它会删除所有虚拟机快照。如果有人知道如何在保留快照的同时缩小虚拟机,请随时分享!

答案1

要缩小 Windows 客户操作系统,您必须缩小客户机内的分区,关闭虚拟机,创建所需大小的新较小磁盘,将数据从旧磁盘复制到新的较小磁盘,交换磁盘名称并重新启动虚拟机。

这很简单,但如果操作不当可能会导致数据丢失和头发丢失。

下面是针对 Windows Server 2012 客户机的 KVM 步骤,其中,我们想要使用 QCOW2 格式将 100 GB 的 Windows Server 2012 客户机缩小到 35 GB。

重要的:此方法涉及无需修改虚拟机定义。相反,它只需要磁盘映像操作

对客人的假设:

  • Guest 是 Windows Server 2012
  • 100 GB 的 QCOW2 格式磁盘映像
  • 两个分区:
    • 350 MB 的启动空间
    • C 盘 99.6 GB,已用空间 20 GB
  • 我们希望将 C: 从 99.6 GB 缩小到 34 GB

对主持人的假设:

  • Ubuntu 16 LTS 服务器
  • KVM(libvirt)
  • 250 GB 驱动器
  • 虚拟映像位于 /var/lib/libvirt/images

步骤 1:准备 Windows 客户机,缩小主 C:分区

在此步骤中,我们将直接从 Windows 中缩小 Windows 分区。此步骤结束时生成的磁盘映像将是启动分区、C: 驱动器(缩小)和我们将删除的剩余未使用空间(通过不将其复制到新磁盘)的总和。

  1. 登录 Windows 客户机
  2. 打开“计算机管理”实用程序,通过使用开始菜单的搜索功能来找到它。
  3. 在左侧点击“存储->磁盘管理”存储磁盘管理截图
  4. 在新屏幕上,右键单击 C: 分区,单击“压缩卷…”,这可能需要一点时间才会出现对话框。请耐心等待。
  5. 出现“压缩 C:”对话框后,在“要压缩的空间量”中输入空间量,使“压缩后的总大小(以 MB 为单位)”值接近所需的 35 GB。然后单击“压缩”。

    笔记:如果新空间太小,您可能会收到错误消息,在这种情况下,您应该逐步减少“要缩小的空间量”1GB,直到错误消失并且缩小开始。实际上,我们希望保留 10 GB 的可用空间。

    我们假设您能够将 C: 分区缩小到 34 GB。

  6. 完成后,打开命令提示符并输入以下内容关闭虚拟机:shutdown /s /t 0

  7. 您的 Windows 客户机已准备就绪。

步骤 2:缩小虚拟机主机上的磁盘空间

该过程实际上并不是缩小,而是我们将创建一个新磁盘(最终大小),我们将从原始磁盘复制两个分区,并跳过转移未使用的空间。

目标是创建一个总大小 = 启动分区 + C: 分区的磁盘。我们最终还会剩下一些微小的空间(除非您的数学计算非常完美),不用担心,因为我们会在最后一步处理。

  1. 登录linux主机
  2. 切换到超级用户:sudo su
  3. 前往存储虚拟图像的位置:cd /var/lib/libvirt/images
  4. 列出文件:ls -l
  5. 找到您的客户机映像(其他地方有很多关于此内容的教程)。假设我们的 Windows 客户机映像名为“windows.qcow2”
  6. 我们进行备份:

    mkdir backup
    cp windows.qcow2 backup/windows.qcow2.bak
    

    (去喝咖啡,因为处理大磁盘需要一段时间)

  7. 安装您可能缺少的 guestfs 软件包:

    apt-get install libguestfs-tools
    
  8. 好吧,让我们通过以下方法探索 Windows 映像来仔细检查我们的 Windows 磁盘virt-filesystems

    virt-filesystems --long --parts --blkdevs -h -a windows.qcow2
    

    输出如下内容:

    Name       Type       MBR  Size  Parent 
    /dev/sda1  partition  07   350M  /dev/sda
    /dev/sda2  partition  07   34G   /dev/sda
    /dev/sda   device     -    100G  -
    

    请注意,我们有/dev/sda1350 MB 的 Windows 启动分区,/dev/sda2现在是 34 GB 的 C:分区,而总磁盘映像/dev/sda/为 100 G,为我们留下了大量可以修剪的空间。

    因此,重要的一步是:算一下:34 G + 350M 等于 35 G,因此我们将创建一个 35 GB 的映像。我们不可避免地会剩下一些空间 - 除非您的计算非常准确 - 但不用担心,我们将在下面处理它。

  9. 让我们创建称为newdisk.qcow2总大小为 35 GB 的新虚拟 QCOW2 磁盘:

    qemu-img create -f qcow2 -o preallocation=metadata newdisk.qcow2 35G
    

    输出:

    Formatting 'newdisk.qcow2', fmt=qcow2 size=37580963840 encryption=off cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16`
    
  10. 让我们通过将旧磁盘复制到新分配的磁盘来调整磁盘大小。这是绝对棒极了的部分。大多数其他指南都展示了一些非常复杂的东西。这可以通过以下命令轻松完成,之后您应该去喝杯咖啡——这可能需要一段时间:

    virt-resize windows.qcow2 newdisk.qcow2`
    

    输出如下内容:

    [   0.0] Examining windows.qcow2
    100% ?¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦? --:--
    **********
    Summary of changes:
    /dev/sda1: This partition will be left alone.
    /dev/sda2: This partition will be left alone.
    There is a surplus of 439.8M.  An extra partition will be created for the surplus.
    **********
    [   8.8] Setting up initial partition table on newdisk.qcow2
    [   9.9] Copying /dev/sda1
    100% ?¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦? 00:00
    [  15.1] Copying /dev/sda2
    100% ?¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦? 00:00
    Resize operation completed with no errors.  Before deleting the old disk, carefully check that the resized disk boots and works correctly.
    

    注意,该工具发现了剩余的空间...回想一下关于数学的评论...所以你可以取消它并重新创建磁盘,或者像我们在这里所做的那样继续前进,并sda2按照步骤 3 中所做的那样扩展分区。

  11. 完成后,检查生成的图像:

    virt-filesystems --long --parts --blkdevs -h -a newdisk.qcow2
    

    输出如下内容:

    Name       Type       MBR  Size  Parent
    /dev/sda1  partition  07   350M  /dev/sda
    /dev/sda2  partition  07   34G   /dev/sda
    /dev/sda3  partition  83  439.8M   /dev/sda
    /dev/sda   device     -    35G  -
    

    请注意,剩余空间的类型/dev/sda3为 linux。剩余空间是可以的,除非您的计算完全正确。我们将在下面处理来自 Windows 客户机的这个额外分区。现在,请忽略它。

  12. 交换磁盘映像:

    mv windows.qcow2 backup/
    mv newdisk.qcow2 windows.qcow2
    
  13. 启动您的虚拟机。

步骤 3:在 Windows 客户机上完成磁盘操作

在此步骤中,我们确认 Windows 启动正常,并且我们将把 C 分区扩展到额外的空间。

  1. 登录到 Windows 客户机

  2. 打开“计算机管理”实用程序,通过使用开始菜单的搜索功能来找到它。

  3. 在左侧点击“存储->磁盘管理”

  4. 您应该看到 3 个分区:启动分区、C: 分区和一个 439 MB 的小分区(最右边)。显示 3 个分区的计算机管理屏幕截图

  5. 通过右键单击->删除卷来删除 Linux 分区。(对于任何提示单击“是”)

  6. 右键单击 C: 分区,然后单击“扩展”,然后在对话框中单击下一步和确定。它应该只提供最后一个分区的扩展量。完成后,您已调整 C: 的大小,并且只剩下两个分区。

  7. 就是这样。您的 Windows 客户机现在仅使用 35 GB 左右。请记住,由于所有开销等原因,实际磁盘映像可能更大(可能更接近 38 GB)。

检查一切是否正常,然后删除您的图像备份或将其离线移至存储。

答案2

我终于设法真正缩小了虚拟机空间。一开始,W7 VM 在主机存储上占用了 107 GB。虚拟硬盘大小为 100 GB,目前,虚拟机仅占用了 18 GB 的虚拟存储。

这是我所做的:

  1. 清理虚拟驱动器(删除临时文件等)
  2. 使用“全面优化”的开源 UltraDefrag 软件进行碎片整理
  3. 跑步sdelete -c c:
  4. 跑步sdelete -z c:
  5. 跑步qemu-img convert -c -f qcow2 w7-64.qcow2 -O qcow2 w7-64-compressed.qcow2

这样,qcow2 文件就从 107 GB 缩小到了...7 GB!

答案3

运行 时qemu-img -c,会压缩图像,虽然可以减少一些空间,但实际上会损害性能。如果要对磁盘上的零进行重复数据删除,则需要运行qemu-img convert,基本上就像尝试将图像从一种格式转换为另一种格式一样(即使 src 和 dst 格式相同)。

此过程将写入一个新的转换图像(不带零),从而有效地对驱动器上的零空间进行重复数据删除。

另一个选择是简单地使用virt-sparsify课程。

答案4

virt-sparsify在 Xenial 和 Bionic 中,包中的实用程序libguestfs 工具应该可以工作。请注意:

  • 您不必事先sdelete在客户机内部运行类似工具(但这不会造成任何损害)
  • 您可以使用该--in-place标志来释放空间而不复制文件(如果磁盘映像已经大于驱动器上剩余的可用空间,则很有用!)
  • 该工具支持qcow2和raw格式的图片

相关内容