如何缩小原始虚拟机磁盘映像(kvm)的大小?

假设我有linux-vm-image.raw ,大小为10GB。 里面有一个主要的(使用类似MS-DOS的分区表,不是GPT) etx4分区(不使用LVM),扩展到整个卷。 而在该分区上分配的实际数据例如是3GB。

该映像准备用于某些虚拟化环境(在我的情况下为kvm + OpenStack),并且根据用户的select,从该映像创build的所有虚拟机都将调整自己的大小以指向虚拟磁盘大小。 所以没有理由在磁盘映像中保留任何空闲的磁盘空间。

我怎么能把这个原始磁盘映像的大小缩小到最小(从10GB到〜3GB)?

有一些 qcow2磁盘映像的说明,但我只能使用raw映像 – 不是qcow ,而不是OVF而不是其他。

我的猜测是有点像

  • 将此映像作为块设备挂载到某个位置
  • 做一些维护,让ext4分区内的所有文件移动到“开始”,换句话说 – 做一个自由空间碎片整理
  • 卸载图像
  • 将文件系统的大小缩小为图像(以匹配其内部数据的大小)
  • 缩小图像大小(以匹配其内部文件系统的大小)
  • 将分区表更新为映像以匹配新的分区大小

但是我不试着发明一辆自行车吗? 是否有一些单行命令或特殊软件来做我想要的?

原始图像不是真的resize友好。 然而,你可以在(卸载的)文件系统上尝试zerofree ,然后压缩生成的图像文件。

另外,请检查您的目标环境是否支持允许压缩磁盘映像的OVF容器格式。 (zerofree仍然适用)。

你在正确的轨道上。 如果你可以把它作为一个块设备(loop mount)挂载,你可能会被gparted处理。

gparted将做你想要的大部分:
1.将FS数据移动到其分区的前面(shrink FS)
2.缩小分区并调整分区表
3.当你打印更新的分区表(例如,最后一个分区的最后一个扇区等)时,甚至可以给你剩余的“磁盘”大小。

这是困难的一部分。 之后,卸载它。 你可能需要手工计算你的“磁盘”的确切大小,但是在这之后,文件上的一个简单的截断就可以完成。

更新:如果你的分区表是MBRtypes,你没事。 使用GPT,它在磁盘末尾有一个镜像副本。 所以,要小心,因为gparted可能不够聪明(除非你可以直接给它的原始图像)。 如果遇到问题,请将gdisk作为截断后的一个步骤。 截断几个额外的块,并获得gdisk / equiv重build镜像副本(可能需要循环挂载第二次)。