AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 729110
Accepted
romu
romu
Asked: 2015-10-16 00:57:05 +0800 CST2015-10-16 00:57:05 +0800 CST 2015-10-16 00:57:05 +0800 CST

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

  • 772

我花了很多时间在网上搜索如何缩小 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 -z。virt-sparsity使用该标志运行--compress会提供 80 GB 的虚拟驱动器。远非我所希望的。


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

windows
  • 7 7 个回答
  • 29431 Views

7 个回答

  • Voted
  1. John
    2016-08-31T18:08:00+08:002016-08-31T18:08:00+08:00

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

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

    以下是带有 100 GB 的 Windows Server 2012 来宾的 KVM 的步骤,我们希望使用 QCOW2 格式缩小到 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 中的虚拟映像

    第 1 步:准备 Windows 来宾,收缩主 C: 分区

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

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

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

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

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

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

    第 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
      

      (去喝杯咖啡,因为这需要一段时间才能获得大磁盘)

    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 步:在 Window Guest 上完成磁盘操作

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

    1. 登录到 Windows 来宾

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

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

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

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

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

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

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

    • 12
  2. Best Answer
    romu
    2015-10-27T01:07:10+08:002015-10-27T01:07:10+08:00

    我终于设法真正缩小了 VM 空间。一开始,W7 VM 占用了 107 GB 的主机存储空间。虚拟 HDD 大小为 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!

    • 6
  3. dyasny
    2015-10-16T05:22:40+08:002015-10-16T05:22:40+08:00

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

    这个过程将写入一个新的转换后的图像,没有零,有效地删除驱动器上的零空间。

    当然,另一种选择是简单地使用virt-sparsify。

    • 4
  4. Aditya Iyer
    2016-09-20T01:35:51+08:002016-09-20T01:35:51+08:00

    适用于 KVM 上的 Windows VM 的方法如下。

    在 Windows 客户机上:

    1. 必要时进行碎片整理。
    2. sdelete -z c:(sdelete -z适用于虚拟机。它不会增加磁盘上的实际 QCOW2 映像大小并将空白空间清零。 sdelete -c另一方面,它不是必需的,它会增加磁盘上的 QCOW2 映像大小)

    在 Linux 主机上:

    1. qemu-img convert -O qcow2 -c inputVM.img outputVM.img(请注意,这不会保留快照并将采用当前状态)
    • 2
  5. david
    2018-07-07T12:00:37+08:002018-07-07T12:00:37+08:00

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

    • 您不必sdelete事先在来宾内部运行工具(但不会受到伤害)
    • 您可以使用该--in-place标志来释放空间而不复制文件(如果磁盘映像已经大于驱动器上的剩余可用空间,则很有用!)
    • 该工具支持 qcow2 和 raw 格式的图像
    • 2
  6. Peter
    2015-10-16T03:18:21+08:002015-10-16T03:18:21+08:00

    您只需要“打孔”或“稀疏”空白空间。为此,您需要仅包含 0 和孔的空间。文件系统的“空白空间”只是未分配,但可能包含旧的垃圾数据,而不是 0。所以第一步是将它归零。有一些工具可以做到这一点,但这里有一个简单的最小方法......

    1. 启动虚拟机。
    2. 在每个文件系统上创建一个只有 0 的文件,然后将其删除。在这里,我假设 /tmp 是您可写的,并且位于 rootfs 上。(在 Windows 中,您可以在 cygwin 中执行相同的命令,或使用其他工具。)

      dd if=/dev/zero of=/tmp/zeros bs=1M
      rm /tmp/zeros
      

      现在空白空间只是0。而且,这个磁盘现在是磁盘上的完整大小......与你最终想要的相反。因此,如果您之前空间不足,这将不起作用。

    3. 停止虚拟机。

    4. 打孔。有几种方法可以做到这一点……这是一种快速的方法,使用 python 脚本。首先停止 vm,然后在磁盘文件上运行脚本。如果它是 qcow2 文件或其他格式,它应该工作相同,但可能有一些我忘记了,或者只是一个更简单的方法。

    并且要注意没有分配一个洞,所以文件不是都在一个地方;文件系统可能会变得碎片化,从而影响性能。这在典型的 Linux/UNIX 文件系统上不应该以任何方式引起注意,除非您在写入文件时空间非常低,但请注意这种可能性。建议至少保留 10% 的可用空间以避免碎片。

    此外,还有一些工具也可以做其他事情......比如仅将非零空白空间归零(因此它们在打孔之前不会增长),也将交换归零,在线执行(可能需要虚拟机管理程序支持),等等。我尝试了这些方法,发现它们都非常不可靠,有时几乎没有像手动归零那样缩小 5%,所以我什至不会费心列出这些工具;其他人可以列出他们的最爱。

    • 1
  7. jgdaqs
    2015-10-28T11:02:35+08:002015-10-28T11:02:35+08:00

    您可能想要禁用系统还原或删除 VM 磁盘中的任何现有卷影副本。仅此一项就可能占用大量空间,并且对文件系统来说似乎是隐藏的。然后在 vm 重新启动后运行 sdelete 并将可用空间清零。

    • 0

相关问题

  • 知道任何适用于 Windows 的快速可编写脚本的 ftp 客户端吗?[关闭]

  • 如果 Windows 服务崩溃,如何自动重新启动它?

  • 无法安排任务(访问被拒绝)

  • 物理机重启时自动重启虚拟机(VMWare)

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve