多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

VMware虚拟机磁盘空间回收实战:精简置备原理、压缩命令与避坑指南

VMware虚拟机磁盘空间回收实战:精简置备原理、压缩命令与避坑指南 简介这份文档面向 VMware 虚拟化运维人员与存储管理员聚焦 ESXi 环境下精简磁盘Thin空间无法自动释放的常见痛点给出可落地的回收思路与操作参考。资源包内仅 1 个 docx 文件约 408KB内容围绕 vmfs5 文件系统不支持自动回收空间的限制展开系统梳理了两种回收路径一是借助 SDelete 工具清理 Windows 虚拟机空闲空间后通过 SSH 登录 ESXi 主机执行 vmkfstools 命令完成空间回收二是利用 Storage VMotion 在线迁移将磁盘格式切换为厚置备延迟归零再迁回 Thin实现不停机释放空间。文中还对比了 Thin 格式的优缺点并说明精简卷管理、ESXi 主机存储功能等背景知识。目前已有 2000 人学习适合需要排查磁盘占用虚高、优化存储利用率的中高级运维人员参考。1. 精简磁盘回收这件事为什么删了文件虚拟机还是“胖”的在 VMware Workstation 里装完 Ubuntu 或 Win10用着用着就会发现一个反直觉现象虚拟机里明明删掉了几十 GB 的日志、缓存和旧镜像宿主机上的 vmdk 文件却一点没瘦甚至还在涨。这不是玄学是虚拟磁盘的分配机制决定的——厚置备磁盘一旦把块分给你就不会主动还回去即便是精简置备Guest 系统删除文件后文件系统只是把块标记为空闲底层并不知道这些块已经没用了。所谓“精简磁盘空间回收”要解决的就是让 Guest 把空闲块的信息透传给 VMware再由 VMware 把这些块真正归还给宿主机文件系统。这件事对两类人价值最大一类是笔记本 SSD 容量吃紧、靠 VMware 虚拟机安装 Ubuntu 或 Win10 做开发测试的工程师另一类是维护 ESXi 上多台虚拟机、被存储容量账单追着跑的运维。它不复杂但顺序错了、参数设偏了就会出现“回收完反而更大”或者“卡在 99% 不动”的翻车现场。下面按“先搞懂机制、再动手回收、最后避坑”的路径讲透。2. 先分清厚置备与精简置备回收到底在回收什么2.1 三种磁盘格式的差异决定了能不能回收VMware 虚拟磁盘在 Workstation 和 ESXi 上主要有三种形态回收能力完全不同。厚置备延迟置零Thick Provision Lazy Zeroed创建时按最大容量占空间但块是写时才置零厚置备立即置零Thick Provision Eager Zeroed创建时就把整块空间写零性能最好但最占地方精简置备Thin Provision按实际写入量增长是唯一“天生可回收”的格式。很多人以为只要在 Guest 里删文件就能瘦其实厚置备磁盘在 Guest 侧做任何操作都不会让 vmdk 变小因为宿主机层面这些块早就被占死了。判断当前磁盘属于哪种最直接的办法是看 vmdk 描述文件里的ddb.thinProvisioned字段或者用vmkfstools -D查。Workstation 图形界面里虚拟机设置 → 硬盘 → 磁盘实用工具能看到“压缩”按钮是否可用灰掉的基本就是厚置备。这里有个常见误解把厚置备转成精简置备不是点一下就行需要走一次存储迁移Storage vMotion或vmkfstools转换转换过程会重写整个磁盘耗时和容量成正比几百 GB 的盘要留足窗口期。2.2 回收的底层链路Guest 标记 → 驱动透传 → 宿主释放回收能成立靠的是一条完整链路。第一步Guest 文件系统把删除的块标记为空闲这一步 Windows 的 NTFS 和 Linux 的 ext4/xfs 都会做但只是逻辑标记。第二步需要 VMware Tools 里的驱动把“这些块空闲了”的信息透传给 hypervisorWindows 侧靠vmware-tools的vmwarevss和vmware physical disk辅助服务Linux 侧靠open-vm-tools配合vmware-toolbox-cmd。第三步hypervisor 收到空闲块列表后把对应块在 vmdk 里标记为可回收再通过压缩或迁移真正释放宿主机空间。这条链路任何一环断了回收都会失败。最常见的断点是 VMware Tools 没装或版本太旧——热词里“vm17之后怎么安装vmware tools”“vmware tools 启动脚本未能在虚拟机中成功运行”之所以高频就是因为 Tools 是回收的前置条件。另一个断点是 Guest 文件系统不支持透传比如某些老旧的 ext3 或未启用 discard 的挂载参数。所以动手前先确认 Tools 状态比急着点“压缩”重要得多。2.3 回收前必须做的三件准备第一件确认虚拟机没有快照。快照会把回收操作锁死因为快照链上的块被引用着压缩会直接报错或静默失败。用vmrun listSnapshots或图形界面快照管理器清空所有快照这一步没有后悔药删快照前想清楚。第二件Guest 内做一次真正的空间清理。Windows 用磁盘清理 cleanmgrLinux 清/var/log、/tmp、包管理器缓存apt clean/yum clean allDocker 环境还要docker system prune。注意清理只是让块变空闲不等于回收但不清的话回收效果会大打折扣。第三件记录回收前的 vmdk 实际占用。在宿主机上执行ls -lh *.vmdk或du -sh留个基准回收后对比才知道有没有效果。这一步很多人跳过结果回收完不知道到底省了多少也没法判断是否翻车。3. 在 Workstation 上手动回收图形界面与命令行两条路3.1 图形界面压缩适合单台、偶发场景Workstation Pro 里最省事的路径是关闭虚拟机不是挂起必须完全关机→ 虚拟机设置 → 硬盘 → 磁盘实用工具 → 压缩。这个操作会调用 VMware 的磁盘压缩逻辑把 Guest 标记为空闲的块在 vmdk 里回收。注意它只对精简置备和部分厚置备有效且要求 Tools 正常。图形界面压缩的局限很明显一次只能处理一台大磁盘耗时很长中途不能中断中断可能留下损坏的 vmdk。我一般只在临时测试机上用它生产或大容量盘一律走命令行因为命令行能看到进度、能脚本化、出问题也好排查。3.2 命令行回收vmware-vdiskmanager 的用法与参数Workstation 自带vmware-vdiskmanager路径在安装目录下Windows 默认C:\Program Files (x86)\VMware\VMware Workstation\Linux 在/usr/bin/或/usr/lib/vmware/。核心命令是压缩和碎片整理两步。# 先做碎片整理把空闲块集中压缩效率更高 vmware-vdiskmanager -d D:\VMs\ubuntu-dev\ubuntu-dev.vmdk # 再执行压缩回收空闲块 vmware-vdiskmanager -k D:\VMs\ubuntu-dev\ubuntu-dev.vmdk # 查看磁盘信息确认类型和当前大小 vmware-vdiskmanager -i D:\VMs\ubuntu-dev\ubuntu-dev.vmdk-d是 defragment把分散的块整理到一起对大磁盘能明显提升后续压缩效果但耗时也最长几百 GB 的盘可能要跑一两个小时。-k是 shrink真正执行回收。-i是 info输出磁盘类型、容量、是否精简动手前先跑一次确认格式。参数上要注意-k只能对关机状态的磁盘操作虚拟机开着会直接报错路径带空格必须加引号Windows 下反斜杠别写错。3.3 Linux Guest 侧的预处理fstrim 与 zero 填充Linux 虚拟机在压缩前最好在 Guest 内先跑一次fstrim主动把空闲块告诉底层比等压缩时被动识别更彻底。# 对根分区执行 trim需要文件系统挂载时带 discard 或支持在线 trim sudo fstrim -av # 如果 fstrim 不支持用 dd 写零填充空闲空间再删除 sudo dd if/dev/zero of/zero.fill bs1M statusprogress sudo rm -f /zero.fill sudo syncfstrim -av会对所有支持的文件系统执行 trim输出每个分区回收的字节数这个数字能直接反映有多少空闲块被透传。如果文件系统不支持在线 trim比如某些 ext4 挂载参数没开 discard退而求其次用dd写零填满再删效果类似但慢得多且会短暂占满磁盘要确保剩余空间够。sync不能省它保证写操作落盘否则压缩时可能读到未刷新的数据。3.4 Windows Guest 侧的预处理sdelete 与磁盘清理Windows 没有 fstrim 这种原生工具微软官方提供sdeleteSysinternals 套件来把空闲空间写零。# 用 sdelete 把 C 盘空闲空间写零-z 表示清理空闲块 sdelete64.exe -z C: # 先跑系统磁盘清理删掉临时文件和旧更新 cleanmgr /sagerun:1sdelete64.exe -z C:会把 C 盘所有空闲块写零这样 VMware 压缩时能识别出这些块是空的。注意-z会写满整个空闲空间磁盘剩余空间越大耗时越长SSD 上还会带来额外写入磨损别频繁跑。cleanmgr /sagerun:1需要先配置过清理项否则直接跑没反应。Windows 侧还有一个坑页面文件和休眠文件占的块不会被 sdelete 处理如果这两个文件很大回收效果会打折必要时先关掉休眠powercfg -h off。4. 在 ESXi 上回收vmkfstools 与存储迁移的正确姿势4.1 vmkfstools 的 punchzero 与 inflate 参数ESXi 上没有 Workstation 那套图形压缩主力工具是vmkfstools。回收精简置备磁盘的空闲块核心是--punchzero。# 对精简置备磁盘打孔回收空闲块 vmkfstools --punchzero /vmfs/volumes/datastore1/ubuntu-dev/ubuntu-dev.vmdk # 查看磁盘是否为精简置备 vmkfstools -D /vmfs/volumes/datastore1/ubuntu-dev/ubuntu-dev.vmdk | grep thin # 把厚置备转成精简置备需要先关机且目标存储空间足够 vmkfstools -i /vmfs/volumes/datastore1/ubuntu-dev/ubuntu-dev.vmdk -d thin /vmfs/volumes/datastore2/ubuntu-dev/ubuntu-dev-thin.vmdk--punchzero只对精简置备有效对厚置备会报错或无效。执行前虚拟机必须关机且不能有快照。-D用来确认磁盘类型输出里Thin字样是判断依据。-i加-d thin是转换命令本质是复制一份精简置备的新盘源盘保留转换完要手动切换虚拟机磁盘指向并验证启动确认无误再删源盘。这一步空间要留够因为转换期间两份盘同时存在。4.2 Storage vMotion 触发自动回收ESXi 上更省心的方式是 Storage vMotion。把虚拟机从一块存储迁到另一块如果目标存储支持精简置备迁移过程会自动丢弃空闲块相当于顺带做了一次回收。前提是虚拟机磁盘是精简置备且迁移时虚拟机可以保持开机在线迁移对业务影响小。迁移回收的注意点目标存储剩余容量必须大于虚拟机实际使用量而非配置容量否则迁移会失败迁移期间 IO 压力大对延迟敏感的业务要避开高峰迁移完成后源存储上的旧盘不会自动删要手动清理否则等于没省空间。我一般把迁移回收和存储扩容、硬件升级排在一起做一次窗口解决多个问题。4.3 回收效果验证对比 vmdk 实际占用回收做完必须验证否则不知道是真省了还是白忙。ESXi 上用du -h看 vmdk 实际占用Workstation 上用ls -lh或资源管理器看文件大小。# ESXi 上查看 vmdk 实际占用 du -h /vmfs/volumes/datastore1/ubuntu-dev/ubuntu-dev.vmdk # 查看精简置备磁盘的已用块和总块 vmkfstools -D /vmfs/volumes/datastore1/ubuntu-dev/ubuntu-dev.vmdkdu -h输出的是实际占用和配置容量对比就能算出回收了多少。vmkfstools -D会输出已分配块数回收后这个数字应该下降。如果回收后占用没变甚至变大大概率是 Guest 侧没做预处理、Tools 没装好或者磁盘根本不是精简置备。验证这一步别偷懒它是判断整条链路是否走通的唯一依据。5. 避坑与排查回收翻车的五个真实场景5.1 现象压缩卡在 99% 长时间不动原因通常是磁盘碎片过多或 Guest 侧空闲块信息不完整压缩引擎在反复扫描。解决先中断操作不要强杀进程用正常取消在 Guest 内跑一次碎片整理Windows 用defragLinux 用e4defrag再重新压缩。如果反复卡住考虑用vmware-vdiskmanager -d先整理再压缩或者干脆走存储迁移。5.2 现象回收后 vmdk 反而变大这是最典型的翻车。原因多半是磁盘本身是厚置备压缩操作触发了内部重写把原本延迟置零的块全部实写导致占用上升。解决先确认磁盘类型厚置备不要直接压缩要么转精简置备要么接受它不会变小的事实。另一个原因是 Guest 侧有大量未清理的临时文件压缩时被当成有效数据保留回收前务必彻底清理。5.3 现象提示“无法压缩磁盘正在使用”原因很直接虚拟机没完全关机或者有快照、有挂起的会话。解决确认虚拟机状态是 Powered Off 而非 Suspended清空所有快照检查是否有后台进程占用 vmdkWindows 上用资源监视器查句柄。ESXi 上还要确认没有其他主机挂载同一存储。5.4 现象Linux Guest 里 fstrim 报“不支持的操作”原因是文件系统挂载时没启用 discard或者底层存储不支持在线 trim。解决检查/etc/fstab挂载参数临时可以mount -o remount,discard /测试如果底层不支持改用dd写零填充的老办法。注意在线 trim 对某些 SSD 有性能影响生产环境要评估。5.5 现象回收后虚拟机启动报磁盘错误原因通常是压缩过程中断导致 vmdk 元数据损坏或者转换后磁盘指向没更新。解决先别慌用vmkfstools -R尝试修复或者从备份恢复。这也是为什么回收前一定要备份 vmdk 描述文件.vmdk文本部分和快照别嫌麻烦这是唯一的后悔药。6. 把回收做成例行习惯脚本化与容量监控单次回收解决一时之痛真正省心的是把它变成例行操作。我的习惯是给每台开发虚拟机配一个关机回收脚本配合宿主机的容量监控占用超过阈值就触发。Workstation 上可以用批处理或 shell 包一层#!/bin/bash # 关机状态下回收指定虚拟机磁盘 VMX/path/to/vm.vmx VMDK/path/to/vm.vmdk vmrun stop $VMX hard vmware-vdiskmanager -d $VMDK vmware-vdiskmanager -k $VMDK du -sh $VMDK这个脚本先强制关机再整理压缩最后输出实际占用。vmrun stop的hard参数是强制断电仅适合测试机生产环境要用soft走正常关机流程。ESXi 侧则更适合用 PowerCLI 批量处理遍历集群里所有精简置备虚拟机检查快照、执行 punchzero、记录回收前后容量形成报表。监控上ESXi 用esxcli storage filesystem list看各存储剩余空间Workstation 用宿主机的磁盘告警。阈值我一般设在剩余 15% 触发回收留出缓冲。回收频率别太高SSD 上频繁写零会加速磨损机械盘上频繁压缩影响 IO季度一次或容量告警时做一次就够。最后说个我踩过的坑早期我图省事在虚拟机开机状态下直接跑压缩结果 vmdk 元数据损坏整台开发机重装。从那以后我养成了两个习惯——回收前必查快照和磁盘类型回收后必对比du输出。这套流程不复杂但每一步都有它的道理跳过哪一步都可能付出代价。希望帮到你。本文还有配套的精品资源点击获取
返回列表