我已经花了很多时间在网上search关于如何缩小KVM虚拟磁盘映像,特别是Windows客户端,没有运气。
我发现的所有是虚拟机可用空间归零,虚拟磁盘碎片整理(从Windows),然后运行qemu-img convert -c ... (- -c标志压缩)。
我有一个Windows 7虚拟机,具有100 GB的虚拟驱动器大小。 最初,这个VDD在主机存储上花费了40GB。 一旦它被归零,VDD就会在主机上达到真正的100GB。 而qemu-img -c ...创build了91 GB,这完全不符合我的预期。
在modernie网站上,我们可以下载less于10GB的W7虚拟机,这怎么可能? 有没有办法“真正”压缩VM镜像?
感谢@dyasny,我做了一个很稀有的小testing。 我清理了W7 VM磁盘,禁用了hibernate,所以VDD只消耗20 GB。 再次降级,再次运行sdelete -z 。 使用--compress标志运行virt-sparsity可以获得80 GB的虚拟驱动器。 远非我所希望的。
EDIT-2016-02-16:“刷新”这个问题,因为这里讨论的缩小虚拟机的方法是非常有效的,但有一个主要的缺点:它删除所有的虚拟机快照。 如果有人知道如何在保留快照的同时缩小虚拟机,请随时分享!
要缩小Windows客户操作系统,必须缩小客户机内的分区,closures虚拟机,创build一个所需大小的新小磁盘,将数据从旧磁盘复制到新的较小磁盘,交换磁盘名称并重新启动VM。
这很简单,但如果做得不恰当,可能会导致数据丢失和头发丢失。
以下是使用QCOW2格式将100 GB的Windows Server 2012 guest虚拟机与我们希望缩小为35 GB的KVM的步骤。
重要提示 :此方法不涉及虚拟机定义的修改 。 相反,它只需要磁盘映像操作 。
客人的假设:
主机假设:
步骤1:准备Windows客户机,收缩主C:分区
在这一步中,我们将直接从Windows中减less我们的Windows分区。 在这个步骤结束后得到的磁盘映像将是启动分区,C:驱动器(减less的)和我们将删除的剩余未使用空间(通过不复制到新磁盘)的总和。
出现“收缩C:”对话窗口后,input“缩小后的总大小”值接近所需的35 GB的“收缩空间量”中的空间量。 然后点击“收缩”。
注 :如果新空间太小,您可能会收到错误消息,在这种情况下,您应该逐渐减less“缩小空间量”1GB,直到错误消失并收缩。 实际上,我们希望保留10 GB的可用空间。
假设您可以将C:分区缩小到34 GB。
完成后,通过打开命令提示符并键入: shutdown /s /t 0虚拟机
步骤2:VM主机上的磁盘收缩
这个过程并不是真正的收缩,而是我们将创build一个新的磁盘(最终的大小),我们将从原始磁盘复制两个分区,并跳过未使用的空间。
目标是创build一个总大小=启动分区+ C:分区的磁盘。 我们还会得到一些小小的剩余空间(除非你的math是完美的),不要担心,因为我们会在最后一步处理。
sudo su cd /var/lib/libvirt/images ls -l 我们做一个备份:
mkdir backup cp windows.qcow2 backup/windows.qcow2.bak
(去喝咖啡,因为这将需要一段时间的大磁盘)
安装你可能会丢失的guestfs包:
apt-get install libguestfs-tools
好的,让我们通过使用virt-filesystems探索windows映像来检查我们的Windows磁盘:
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/sda1这是我们的Windows启动分区为350 MB, /dev/sda2这是我们的C:分区现在34 GB,并且总磁盘映像/dev/sda/是100 G留给我们一堆修剪的空间。
所以这里是重要的一步:做你的math:34 G + 350M适合35 G,因此我们要创build一个35 GB的图像。 我们不可避免地会留下一些剩余空间 – 除非你的math是完美的 – 但不要担心,我们将在下面处理。
让我们创build一个新的虚拟QCOW2磁盘,我们称newdisk.qcow2磁盘为总容量为newdisk.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`
让我们通过将旧磁盘复制到新分配的磁盘来调整磁盘大小。 这是绝对可怕的一点。 大多数其他指南显示一些非常复杂的东西。 这只是通过这个命令完成后,你应该去喝更多的咖啡 – 这可能需要一段时间:
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.
注意这个工具发现了空间的剩余……回想一下关于math的评论…所以你可以取消这个并重新创build磁盘,或者像我们这样做,继续扩展sda2分区,就像在STEP3上做的那样。
一旦完成。 检查产生的图像:
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的types对于剩余空间而言是types为linux的types。 剩下的空间是可以的,除非你的math完全正确。 我们将在下面的Windows客户端处理这个额外的分区。 现在,只要忽略它。
交换磁盘映像:
mv windows.qcow2 backup/ mv newdisk.qcow2 windows.qcow2
启动您的VM。
第3步:完成Window Guest上的磁盘操作
在这一步中,我们正在确认Windows靴子,我们将把我们的C分区扩展到额外的空间位置。
login到Windows客户
打开“计算机pipe理”实用程序,使用开始菜单searchfunctionfind它。
在左侧,点击“存储 – >磁盘pipe理”
您应该看到3个分区:引导,C:和一个小的439 MB分区(在最右边)。 计算机pipe理显示3个分区的屏幕截图
通过右键单击 – >删除卷来删除Linux分区。 (点击是以提示)
右键单击C:分区,然后单击“扩展”,然后在对话框中单击下一步并确定。 它应该只提供延长最后一个分区的数量。 一旦完成,你已经调整了C:并留下只有两个分区。
而已。 您的Windows客户现在只使用35 GB左右。 请记住,由于所有开销等原因,实际的磁盘映像可能会更大(可能接近38 GB)
检查一切工作正常,删除您的映像备份或脱机移动到存储。
当你运行qemu-img -c ,你压缩的图像,虽然能够减less一些空间,真的会伤害性能。 如果你想重复删除磁盘上的零,你需要运行qemu-img convert ,基本上就像你试图将图像从一种格式转换成另一种格式(即使src和dst格式相同)。
这个过程将写入一个新的转换后的图像,消除零点,有效地消除驱动器上的零点空间。
另一个select是简单地使用virt-sparsify 。
我终于设法真正缩小了虚拟机的空间。 一开始,W7 VM在主机存储上吃了107 GB。 虚拟硬盘大小为100 GB,目前该虚拟机只有18 GB的虚拟存储空间。
这是我做的:
sdelete -cc: sdelete -zc: qemu-img convert -c -f qcow2 w7-64.qcow2 -O qcow2 w7-64-compressed.qcow2 这样,qcow2文件从107 GB缩小到… 7 GB!
你只需要“打洞”或“疏散”空的空间。 要做到这一点,你需要的空间只包含0和洞。 文件系统的“空白空间”只是未分配,但可能包含旧的垃圾数据,而不是0。 所以第一步是将其归零。 有工具可以做到这一点,但这是一个简单的方法来做到这一点…
在每个文件系统上只创build一个文件,然后删除它。 在这里,我假设/ tmp是可写的,并在rootfs上。 (在Windows中,您可以在cygwin中执行相同的命令,或使用其他工具。)
dd if=/dev/zero of=/tmp/zeros bs=1M rm /tmp/zeros
现在空的空间只是0。 而且,这个磁盘现在是磁盘上的完整大小了 ……与你想要的相反。 所以如果你之前没有空间的话,这将不起作用。
停止虚拟机。
打孔。 有几种方法可以做到这一点… 这是一个快速的方式,使用Python脚本 。 首先停止虚拟机,然后在磁盘文件上运行脚本。 如果它是一个qcow2文件或其他格式,它应该工作相同,但可能有一些我忘了,或者简单的方法。
而且请注意,一个洞没有被分配,所以这个文件并不是在一个地方。 文件系统可能变得分散,损害性能。 在典型的Linux / UNIX文件系统中,这不应该以任何方式引人注目,除非在编写文件的时候空间不足,而只是意识到可能性。 build议保留至less10%的可用空间以避免碎片。
另外,还有一些工具也可以做其他的工作,例如只调零非空的空间(所以它们不会在你打孔之前增长),也可以调零,也可以在线时进行(可能需要pipe理程序支持),等等。我尝试了这些方法,发现它们都非常不可靠,有时几乎不像手动调零那样缩小5%,所以我甚至不打算列出工具。 别人可以列出他们的最爱。
您可能需要禁用系统还原或删除VM磁盘中的所有现有卷影副本。 那样会占用大量的空间,并且会隐藏到文件系统中。 然后运行sdelete并在vm重新引导后将可用空间清零。
在KVM上用于Windows VM的方法如下。
在Windows客户端上:
sdelete -zc: ( sdelete -z是虚拟机,它不会增加磁盘上实际的QCOW2镜像大小,也不会占用空间,另一方面sdelete -c不需要,并且会增加磁盘上的QCOW2镜像大小) 在Linux主机上:
qemu-img convert -O qcow2 -c inputVM.img outputVM.img (注意,这不会保留快照并将采取当前状态)