VirtualBox VM 空间瘦身记(vmdk)

简介: VirtualBox VM 空间瘦身记(vmdk)

本文地址:https://www.ebpf.top/post/shrink_vbox_vmdk_size


在使用 VirtualBox( VMDK 模式)管理虚拟机的时候,我们经常会遇到一些编译安装场景(比如编译 Linux 内核),会导致磁盘空间急剧膨胀,但是在编译完成后即使我们删除了相关的文件,在 VM 虚拟机占用主机的空间却并没有减少,这时候为了腾出磁盘空间或者更方便与他人分享,我们需要给 VM 的磁盘进行瘦身操作。


1.1 虚拟磁盘格式介绍



VirtualBox 主要支持下列虚拟磁盘格式为 VMDK 和 VDI:


  • VMDK(Virtual Machine Disk) 最初是由 VMware 为其产品研发的格式。该格式技术设计文档最初是闭源的,而现在已经开源,在 VirtualBox 里完全可用。这种格式有个功能是:把一个虚拟机的镜像分割成多个 2GB 大小的文件。如果你要把虚拟机镜像放在不支持大文件的文件系统(例如 FAT32)上,那么这个功能就非常有用。在其他的虚拟磁盘格式里,能做到同样功能的只有 Parallels 的 HDD。
  • VDI(Virtual Disk Image) 格式是 VirtualBox 新建虚拟机时默认选用的格式。也是 VirtualBox 的自有开放格式。

VirtualBox 支持的虚拟磁盘格式还有 VHDXHDD 等多种格式,详细信息请参考 VirtualBox 简体中文


1.2 用零字节填充空闲空间



VirtualBox 只有在空间被设置为零的情况下才知道这是磁盘中真正的空闲空间,这与我们在一般机器上通过标准的 rm 命令删除即可释放空间有很大不同。


为了实现这个效果,我们需要登录到 VM 主机中登录到虚拟机中,使用零字节空间填充掉空闲空间,然后再把填充的文件进行删除,即可达到效果。


$ cat /dev/zero > zero.fill; sync; sleep 1; sync; rm -f zero.fill
cat: write error: No space left on device


在命令执行完成后,会出先一个 “cat: write error: No space left on device” 的错误,这个错误恰恰表明我们使用零字节填充了所有的空闲空间。


至此,我们已经在 VM 虚拟机中成功地将空闲的空间进行了零字节填充,是时候进行真正的 “ 减肥 ” 操作了。


1.3 定位 VM 虚拟磁盘文件


在 VirtualBox 运行的主界面上,我们可以通过在虚拟机上点击右键,在弹出的菜单上选择 “Setting“ 选项,会弹出本虚拟相关的设置,切换到 ”Storage“ 选项卡。


                                              图 1-1 进入 VM 的设置页面

在 ”Storage“ 选项卡的主界面中我们可以看到 VM 挂载的虚拟磁盘,点击虚拟磁盘选项,在右侧的 ”Attributes“ 信息栏中就可以在 ”Location“ 项中查询到选择虚拟磁盘所在的目录和文件名。


目录默认保存位置为 ~/VirtualBox VMs/ 目录下以 VM 名称命名的子目录下,如本例中的 ~/VirtualBox VMs/ubuntu_21_04_default_1632463892989_42055,其中 ubuntu_21_04_default_1632463892989_42055 为 VM 主机名。


                                 图 1-2 进入 VM 的设置页面中的存储项详情


确定 VM 的虚拟磁盘所在目录后,我们通过终端进入到对应的目录,进行查看:


$ cd ~/VirtualBox\ VMs/ubuntu_21_04_default_1632463892989_42055/
$ ls -lh
-rw-------  1 dwh0403  staff    35G Sep 28 13:37 ubuntu-hirsute-21.04-cloudimg.vmdk
...


这里我们可以看到该该虚拟磁盘占用了 35G 的磁盘大小。我们可以通过 vboxmanage showhdinfo 命令查看 vmdk 文件的详情(如果后续需要继续使用 vmdk 格式需要):


$ vboxmanage showhdinfo ubuntu-hirsute-21.04-cloudimg.vmdk
UUID:           6a00f1e1-a53f-4a48-9f41-4f2a96248286
Parent UUID:    base
State:          created
Type:           normal (base)
Location:       /Users/dwh0403/VirtualBox VMs/ubuntu_21_04_default_1632463892989_42055/ubuntu-hirsute-21.04-cloudimg.vmdk
Storage format: VMDK
Format variant: dynamic default
Capacity:       40960 MBytes
Size on disk:   35717 MBytes
Encryption:     disabled


为了压缩虚拟磁盘的空间,我们需要将 vmdk 格式转换成 vdi 格式。如果本机安装了

Vmware 产品,可以直接使用其提供的工具直接进行瘦身,参见 Vmware 磁盘管理样例


$ vboxmanage clonehd --format vdi ubuntu-hirsute-21.04-cloudimg.vmdk  ubuntu-hirsute-21.04-cloudimg.vdi
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Clone medium created in format 'vdi'. UUID: 46de9fce-0055-472b-aee2-128509e3685
$ ls -hl 
-rw-------  1 dwh0403  staff    11G Sep 28 13:41 ubuntu-hirsute-21.04-cloudimg.vdi
...
$ vboxmanage modifyhd ubuntu-hirsute-21.04-cloudimg.vdi --compact
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%


待转换完成后,我们可以在当前目录进行查看可以发现 vdi 的文件大小已经降低至 11G(原始 vmdk 文件为 35G 大小),表明在转换过程中已经完成了磁盘空间的缩容。


1.4 将 VDI 格式的磁盘挂载(方案一,验证,推荐)


在转换 vdi 格式后,已经完成了空间的调整,如果我们并去强烈使用 vmdk 格式,我们可以直接将原来的 vmdk 格式虚拟磁盘从 VM 中卸载,然后将 vdi 格式的磁盘挂载即可。同时记得删除 vmdk 格式的虚拟磁盘。


在保持 VM 虚拟机关闭的情况下,进入到 VM 的存储设置页面,步骤与图 1-2 一致。

首先,在移除老的 vmdk 格式的虚拟磁盘上点击右键,在右键菜单属性中选择 ”Remove Attachment“:


然后鼠标选择磁盘控制器,选择添加磁盘按钮:


在弹出的添加磁盘文件的窗口中选择 ”Add“ 按钮,进入到选择文件窗口,选择我们新的 vdi 格式文件即可。


然后将 VM 虚拟机启动验证,如果一切顺利则完成了整个瘦身过程。

这里推荐使用 vdi 格式的虚拟磁盘格式,后续在磁盘空间吃紧的情况还可以使用下述命令调整大小:


$ VBoxManage modifyhd xxx.vdi --resize the_new_size


1.5 使用 VMDK 格式的磁盘挂载(方案二,未验证)


如果由于特殊原因必须使用 vmdk 格式的虚拟磁盘,我们需要将瘦身后的 vdi 格式文件重新转换为 vmdk 格式:


$ VBoxManage clonehd ubuntu-hirsute-21.04-cloudimg.vdi ubuntu-hirsute-21.04-cloudimg_new.vmdk --format vmdk


这里可以选择如上述方案相同的方式,通过去除虚拟磁盘再添加新的磁盘,如果使用原有的文件名字覆盖的话,由于转换过程中生成了新的 UUID,则会导致 VirtualBox 不能够识别新的虚拟磁盘,这里需要重新设置 UUID。


$ vboxmanage internalcommands sethduuid ./ubuntu-hirsute-21.04-cloudimg <原 UUID 在此>


1.5.1 错误解决:


$ VBoxManage clonehd ubuntu_21_04_default_1632463892989_42055/ubuntu-hirsute-21.04-cloudimg.vdi  ubuntu-hirsute-21.04-cloudimg.vmdk --format vmdk
VBoxManage: error: UUID {6438d068-ae7b-467d-ab30-6e1228c30bd9} of the medium '/Users/dwh0403/VirtualBox VMs/ubuntu_21_04_default_1632463892989_42055/ubuntu-hirsute-21.04-cloudimg.vdi' does not match the value {46de9fce-0055-472b-aee2-128509e3685d} stored in the media registry ('/Users/dwh0403/Library/VirtualBox/VirtualBox.xml')
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component MediumWrap, interface IMedium, callee nsISupports
VBoxManage: error: Context: "CloneTo(pDstMedium, ComSafeArrayAsInParam(l_variants), NULL, pProgress.asOutParam())" at line 1068 of file VBoxManageDisk.cpp


如果有上述报错,建议修改 vmdk 生成的文件名重试。


1.6 总结


最后,我们可以已经成功完成了 VM 虚拟空间的瘦身,这对于我们在某些场景下进行功能测试还是非常有帮助。


1.7 参考


目录
相关文章
|
21天前
|
安全 物联网 API
Windows 11 25H2 中文版、英文版 (x64、ARM64) 下载 (2025 年 9 月发布)
Windows 11 25H2 中文版、英文版 (x64、ARM64) 下载 (2025 年 9 月发布)
745 15
Windows 11 25H2 中文版、英文版 (x64、ARM64) 下载 (2025 年 9 月发布)
|
网络协议 Unix Android开发
android emulator虚拟设备分析第五篇之pipe上的opengles
一、概述 据说qemu的gpu的实现,运行起来非常慢。所以android emulator提供了一种use host gpu的方式,guest os可以使用host机器的opengl库去画图,速度快很多。
3396 0
|
编解码
Jetson 学习笔记(十四):降低远程操控延时-修改屏幕分辨率
这篇文章是关于如何通过修改屏幕分辨率来降低Jetson Nano在远程操控时的延时。
401 3
Jetson 学习笔记(十四):降低远程操控延时-修改屏幕分辨率
|
11月前
|
人工智能 安全 Linux
|
Android开发
基于android-11.0.0_r39,系统应用的手动签名方法和过程
本文介绍了基于Android 11.0.0_r39版本进行系统应用手动签名的方法和解决签名过程中遇到的错误,包括处理`no conscrypt_openjdk_jni-linux-x86_64`和`RegisterNatives failed`的问题。
587 2
|
8月前
|
存储 开发框架 Devops
eino — 基于go语言的大模型应用开发框架(一)
Eino 是一个受开源社区优秀LLM应用开发框架(如LangChain和LlamaIndex)启发的Go语言框架,强调简洁性、可扩展性和可靠性。它提供了易于复用的组件、强大的编排框架、简洁明了的API、最佳实践集合及实用的DevOps工具,支持快速构建和部署LLM应用。Eino不仅兼容多种模型库(如OpenAI、Ollama、Ark),还提供详细的官方文档和活跃的社区支持,便于开发者上手使用。
1840 8
|
人工智能 达摩院 算法
什么是优化技术?给算法小白同学的快速讲解和上手文
本文作者用一个曾经小白学习的视角,来讲解什么是优化问题,以及要如何用这个优化技术。
48358 59
|
测试技术 API Python
Python中requests、aiohttp、httpx性能对比
这篇文章对比了Python中三个流行的HTTP客户端库:requests、aiohttp和httpx,在发送HTTP请求时的性能,并提供了测试代码和结果,以帮助选择适合不同应用场景的库。
1097 2
|
安全 网络协议 Shell
|
网络安全 数据安全/隐私保护 Windows
freeSSHd工具安装使用
【5月更文挑战第21天】freeSSHd工具安装使用
2883 2