如何“真正”减少 KVM 虚拟机映像的大小?

rom*_*omu 6 windows compression qemu kvm-virtualization

我花了很多时间在网上搜索有关如何缩小 KVM 虚拟磁盘映像的信息,尤其是对于 Windows 客户机,但没有成功。

我所发现的只是将 VM 可用空间归零,对虚拟磁盘进行碎片整理(来自 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:“刷新”这个问题,因为这里讨论的缩小 VM 的方法非常有效,但有一个主要缺点:它会删除所有 VM 快照。如果有人知道如何在保留快照的同时缩小 VM,请随时分享!

小智 11

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

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

以下是使用 QCOW2 格式的带有 100 GB 的 Windows Server 2012 客户机的 KVM 的步骤,我们希望将其缩小到 35 GB。

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

对客人的假设:

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

对主机的假设:

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

STEP 1:Windows Guest的准备,主C:分区的收缩

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

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

    注意:如果新空间太小,您可能会收到错误消息,在这种情况下,您应该将“要收缩的空间量”逐步减少 1GB,直到错误消失并发生收缩。实际上,我们喜欢保留 10 GB 的可用空间。

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

  6. 完成后,通过打开命令提示符并键入以下内容来关闭 VM: shutdown /s /t 0

  7. 您的 Windows 来宾已准备就绪。

STEP 2:VM 主机上的磁盘收缩

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

目标是创建一个总大小 = 引导分区 + 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
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    apt-get install libguestfs-tools
    
    Run Code Online (Sandbox Code Playgroud)
  8. 好的,让我们通过浏览 Windows 图像来仔细检查我们的 Windows 磁盘virt-filesystems

    virt-filesystems --long --parts --blkdevs -h -a windows.qcow2
    
    Run Code Online (Sandbox Code Playgroud)

    输出这个:

    Name       Type       MBR  Size  Parent 
    /dev/sda1  partition  07   350M  /dev/sda
    /dev/sda2  partition  07   34G   /dev/sda
    /dev/sda   device     -    100G  -
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,我们有/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
    
    Run Code Online (Sandbox Code Playgroud)

    输出:

    Formatting 'newdisk.qcow2', fmt=qcow2 size=37580963840 encryption=off cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16`
    
    Run Code Online (Sandbox Code Playgroud)
  10. 让我们通过将旧磁盘复制到新分配的磁盘来调整磁盘大小。这是绝对很棒的一点。大多数其他指南显示了一些非常复杂的东西。这只是通过这个命令完成的,之后你应该去喝更多的咖啡——这可能需要一段时间:

    virt-resize windows.qcow2 newdisk.qcow2`
    
    Run Code Online (Sandbox Code Playgroud)

    输出这个:

    [   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.
    
    Run Code Online (Sandbox Code Playgroud)

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

  11. 一旦完成。检查生成的图像:

    virt-filesystems --long --parts --blkdevs -h -a newdisk.qcow2
    
    Run Code Online (Sandbox Code Playgroud)

    输出这个:

    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  -
    
    Run Code Online (Sandbox Code Playgroud)

    注意/dev/sda3剩余空间的类型是 linux 类型。剩余的空间是可以的,除非你的数学完全正确。我们将在下面进一步处理来自 Windows 来宾的这个额外分区。现在,只需忽略它。

  12. 交换磁盘映像:

    mv windows.qcow2 backup/
    mv newdisk.qcow2 windows.qcow2
    
    Run Code Online (Sandbox Code Playgroud)
  13. 启动你的虚拟机。

第 3 步:在 Window Guest 上完成磁盘操作

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

  1. 登录到 windows 来宾

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

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

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

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

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

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

检查一切是否正常并删除您的映像备份或将它们离线移动到存储中。


rom*_*omu 5

我终于设法真正缩小了 VM 空间。一开始,W7 VM 在主机存储上吃掉了 107 GB。虚拟硬盘大小为 100 GB,目前,VM 仅占用 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!

  • 是的,但是这是我尝试过很多次但到目前为止没有成功的方法。在这里,sdelete 使用了两次(-c 然后是 -z),并且 qemu-img 命令与我读过很多次的命令有点不同。 (2认同)