news 2026/10/7 7:43:57

VMWARE 占用硬盘空间只增大不减少的清理办法:用 TaoToken 统一 Key 打通 vmdk 瘦身脚本

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
VMWARE 占用硬盘空间只增大不减少的清理办法:用 TaoToken 统一 Key 打通 vmdk 瘦身脚本

1. 为什么 vmdk 只增不减:先搞懂 VMware 的磁盘账本

VMware 虚拟机用久了,宿主机硬盘空间被吃掉几十上百 GB,进系统里删文件、清缓存、卸载软件,宿主机那边却纹丝不动——这是很多人第一次遇到都会懵的问题。核心原因在于 vmdk 的分层设计:虚拟机看到的是一块“逻辑磁盘”,宿主机上真正占空间的是若干.vmdk数据文件,两者之间隔着一层映射表。

当你往虚拟机里写数据,VMware 按需分配块,写多少扩多少;但当你删除文件,Guest OS 只是把块标记为“空闲”,VMware 并不知道这些块已经没用了,它仍然认为这些块被占用,于是宿主机上的 vmdk 文件不会自动缩小。这就是“只增不减”的本质:空间回收需要显式触发,而不是自动发生。

要解决它,得先分清两种磁盘模式:

模式特点能否收缩
厚置备(Thick)创建时一次性分配全部空间不能收缩,只能迁移重建
精简置备(Thin)按需增长,用多少占多少可以收缩,需 Guest 内配合

绝大多数“只增不减”的抱怨都发生在精简置备磁盘上。收缩分两步走:先在 Guest 系统里把空闲块“归零”,再让 VMware 把这些归零的块从 vmdk 里剔除。前者靠vmware-toolbox-cmd,后者靠vmware-vdiskmanager。这两条命令是本文的主角,配合一套可复制的脚本,能把几十 GB 的浪费空间真正还回来。

适合谁看:本地跑 VMware Workstation/Player 的开发者、测试同学,以及用虚拟机做长期构建环境、数据库实验、容器宿主的人。如果你发现宿主机 C 盘或数据盘被某个虚拟机目录越吃越满,这篇就是给你的排查与瘦身手册。

排查第一步永远是定位。先别急着删东西,先看清楚空间到底被谁占了。下面从定位命令开始,一步步走到收缩验证。

2. 定位 vmdk 占用:用命令找出真正吃空间的文件

在动手收缩前,必须先确认三件事:哪个虚拟机目录最大、目录里哪些 vmdk 是数据盘、当前磁盘是不是精简置备。盲目收缩厚置备磁盘是白费功夫,所以定位环节不能省。

Windows 宿主机下,用 PowerShell 按大小列出虚拟机目录里的 vmdk:

# 进入虚拟机存放根目录,按大小降序排列所有 vmdk Get-ChildItem -Path "F:\VMs" -Recurse -Filter *.vmdk | Sort-Object Length -Descending | Select-Object FullName, @{Name="SizeGB";Expression={[math]::Round($_.Length/1GB,2)}} | Format-Table -AutoSize

输出会告诉你哪个.vmdk是几十 GB 的大头。注意区分两类文件:xxx.vmdk(描述符,很小)和xxx-s001.vmdk、xxx-s002.vmdk(真正的数据分片)。精简置备的磁盘通常是一堆-s0xx分片,收缩时要针对描述符文件操作,而不是分片。

Linux 宿主机下用du和find:

# 找出虚拟机目录下最大的 10 个 vmdk find /data/VMs -name "*.vmdk" -type f -printf "%s\t%p\n" \ | sort -rn | head -10 \ | awk '{printf "%.2f GB\t%s\n", $1/1024/1024/1024, $2}'

接着确认磁盘模式。打开虚拟机的.vmx配置文件,搜索scsi0:0.mode或nvme0:0.mode:

grep -i "mode" /data/VMs/MyVM/MyVM.vmx

如果看到independent或没有mode行,多半是厚置备;如果看到thin相关配置或磁盘文件明显小于配置容量,就是精简置备。另一种判断方式:在 VMware 界面里看虚拟机设置,磁盘类型标注为“精简置备”即可收缩。

定位阶段还要记录一个关键数字:Guest 系统内的实际使用量。进虚拟机执行:

df -h

假设 Guest 里/只用了 20 GB,但宿主机上对应 vmdk 占了 60 GB,那中间 40 GB 就是可回收的浪费。这个差值就是收缩的目标收益,也是后面验证的基准。

把这三个信息记下来:vmdk 路径、磁盘模式、Guest 使用量 vs 宿主机占用。有了它们,才能判断该不该收缩、能收回多少。

3. 可复制配置:vmware-toolbox 归零 + vdiskmanager 收缩

收缩分两阶段,顺序不能反。第一阶段在 Guest 内把空闲块归零,第二阶段在宿主机上把归零块剔除。跳过第一阶段直接收缩,效果会大打折扣。

3.1 Guest 内归零:vmware-toolbox-cmd

先确认 Guest 里装了 open-vm-tools(现代 Linux 发行版基本自带):

# Debian/Ubuntu sudo apt-get install -y open-vm-tools # RHEL/CentOS/Rocky sudo dnf install -y open-vm-tools

然后查看磁盘挂载点:

sudo vmware-toolbox-cmd disk list

输出类似:

/ /boot /home

对每个挂载点执行归零(也叫 wipe):

sudo vmware-toolbox-cmd disk wipe / sudo vmware-toolbox-cmd disk wipe /home

如果只想一次性处理所有挂载点,用:

sudo vmware-toolbox-cmd disk shrinkonly

shrinkonly会依次对每个挂载点做归零并触发收缩,适合懒人。但要注意:执行时宿主机当前盘剩余空间必须大于等于虚拟机配置的总容量,否则中途会失败。空间不够时,先把部分-s0xx.vmdk分片临时剪切到其他盘,收缩完再移回来。

归零过程可能很慢,几十 GB 的盘跑十几分钟到半小时都正常,进度条会显示Shrinking disk "F:\FC\FC.vmdk"。耐心等它跑完,中途别关虚拟机。

3.2 宿主机收缩:vmware-vdiskmanager

如果 Guest 内归零已经触发收缩,这一步可以跳过。但很多时候归零只做了 wipe,没做 shrink,这时需要在宿主机上手动执行vmware-vdiskmanager。

Windows 下进入 VMware 安装目录:

cd "C:\Program Files (x86)\VMware\VMware Workstation" .\vmware-vdiskmanager.exe -k "F:\VMs\MyVM\MyVM.vmdk"

Linux 下路径通常是/usr/bin/vmware-vdiskmanager:

sudo vmware-vdiskmanager -k /data/VMs/MyVM/MyVM.vmdk

-k就是 shrink 参数。执行前必须关闭虚拟机,否则文件被占用会报错。输出会显示进度:

Shrink: 100% done. Shrink completed successfully.

看到这行就说明宿主机侧的 vmdk 已经真正缩小了。

3.3 用 TaoToken 统一 Key 管理收缩脚本

如果你有多台虚拟机、多个环境要定期收缩,手动敲命令容易漏。可以把收缩逻辑写成一个脚本,用 TaoToken 的统一 Key 调用 API 做记录和调度。TaoToken 提供兼容 OpenAI 风格的接口,一个 Key 就能打通多个模型调用,适合把“收缩日志分析”“异常告警”这类轻量任务接进来。

先在控制台创建 API Key,拿到形如sk-xxxx的凭证。然后写一个配置文件,把 Base URL、Key、Model ID 三件套固定下来:

{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的Key", "model": "claude-3-5-sonnet", "shrink_targets": [ {"vmx": "F:\\VMs\\MyVM\\MyVM.vmdk", "guest_used_gb": 20}, {"vmx": "F:\\VMs\\BuildVM\\BuildVM.vmdk", "guest_used_gb": 45} ] }

对应的 Python 调用片段,用来在收缩后把结果发给模型做摘要:

import json, subprocess, requests with open("shrink_config.json", encoding="utf-8") as f: cfg = json.load(f) def shrink(vmdk): result = subprocess.run( ["vmware-vdiskmanager.exe", "-k", vmdk], capture_output=True, text=True ) return result.stdout logs = [] for t in cfg["shrink_targets"]: logs.append(f"{t['vmx']}: {shrink(t['vmx'])}") resp = requests.post( f"{cfg['base_url']}/v1/chat/completions", headers={"Authorization": f"Bearer {cfg['api_key']}"}, json={ "model": cfg["model"], "messages": [{"role": "user", "content": "总结以下 vmdk 收缩结果:\n" + "\n".join(logs)}] }, timeout=60 ) print(resp.json()["choices"][0]["message"]["content"])

这样每次收缩完,日志自动汇总成一段可读报告,省去人工翻输出。Base URL 用https://taotoken.net/api,Key 从控制台生成,Model ID 按你实际开通的填。三件套对齐后,脚本就能稳定跑起来。

4. 验证请求与成功结果:收缩前后对比脚本

收缩做完不算完,得用数据证明空间真的降了。写一个对比脚本,在收缩前后各跑一次,把宿主机占用和 Guest 使用量都记下来。

#!/bin/bash # shrink_compare.sh —— 收缩前后对比 VMDK="/data/VMs/MyVM/MyVM.vmdk" GUEST_USED=$(ssh user@vm "df -h / | tail -1 | awk '{print \$3}'") HOST_SIZE=$(du -h "$VMDK" | awk '{print $1}') echo "=== 收缩前 ===" echo "Guest 使用量: $GUEST_USED" echo "宿主机 vmdk 占用: $HOST_SIZE" # 执行收缩 sudo vmware-vdiskmanager -k "$VMDK" HOST_SIZE_AFTER=$(du -h "$VMDK" | awk '{print $1}') echo "=== 收缩后 ===" echo "宿主机 vmdk 占用: $HOST_SIZE_AFTER"

Windows 下用 PowerShell 版本:

$vmdk = "F:\VMs\MyVM\MyVM.vmdk" $before = (Get-Item $vmdk).Length / 1GB Write-Host "收缩前: $([math]::Round($before,2)) GB" & "C:\Program Files (x86)\VMware\VMware Workstation\vmware-vdiskmanager.exe" -k $vmdk $after = (Get-Item $vmdk).Length / 1GB Write-Host "收缩后: $([math]::Round($after,2)) GB" Write-Host "回收: $([math]::Round($before - $after,2)) GB"

一次真实的结果参考:某 Debian 虚拟机 Guest 内df显示用了 18 GB,宿主机 vmdk 占 52 GB。执行vmware-toolbox-cmd disk shrinkonly加vmware-vdiskmanager -k后,宿主机占用降到 21 GB,回收约 31 GB。这个差值接近 Guest 使用量,说明收缩到位了。

验证清单:

  • 宿主机 vmdk 文件大小明显下降,接近 Guest 实际使用量
  • vmware-vdiskmanager -k输出Shrink completed successfully
  • 虚拟机重新启动后系统正常,文件无损坏
  • df -h在 Guest 内显示的使用量不变(收缩不影响 Guest 数据)

如果收缩后宿主机占用没降,八成是归零阶段没做,或者磁盘是厚置备模式。回到第 2 节重新确认磁盘模式。

5. 常见报错排查:401、local proxy failed、reading choices

收缩脚本接上 API 后,最容易撞的几类报错集中在这里。逐个对照排查。

401 Unauthorized:Key 无效或没带上。检查请求头是不是Authorization: Bearer sk-xxxx,注意 Bearer 后面有空格。Key 从控制台重新复制一次,别用带省略号的显示值。如果 Key 刚创建,等几秒生效再试。

local proxy failed / connection refused:本地网络到https://taotoken.net/api不通。先curl -I https://taotoken.net/api看能否返回状态码。如果是公司网络限制,换网络环境或检查防火墙出站规则。注意 Base URL 不要多加/v1之外的路径,/v1/chat/completions是完整端点。

reading choices 报错 / KeyError: 'choices':说明返回体里没有choices字段,通常是请求体格式不对。确认messages是数组、model字段拼写正确。打印完整resp.text看服务端返回的错误信息,比只看异常更直接。

OAuth 相关报错:如果你用的是需要 OAuth 的客户端(比如某些 IDE 插件),别把 OAuth token 和 API Key 混用。TaoToken 的 API Key 走 Bearer 认证,OAuth 流程是另一套。两者分开配置,别塞进同一个字段。

vmware-vdiskmanager 报文件被占用:虚拟机没关干净。确认 VMware 进程全部退出,Windows 下检查任务管理器里有没有残留的vmware-vmx.exe。Linux 下lsof | grep vmdk看谁占着文件。

收缩中途失败、空间不足:宿主机当前盘剩余空间小于虚拟机配置容量。按第 3 节的办法,先把部分-s0xx.vmdk分片临时移到其他盘,收缩完再移回。移动时保持文件名和相对路径不变,否则描述符找不到分片。

Guest 内 vmware-toolbox-cmd 找不到命令:open-vm-tools 没装或没启动。systemctl status open-vm-tools看服务状态,没装就按 3.1 节安装。装完重启虚拟机再试。

排查顺序建议:先确认 Key 和 Base URL 三件套对齐,再看网络连通性,最后看请求体格式。大部分 401 和 choices 报错都是配置字段写错,不是服务本身的问题。

6. 把收缩接进日常:用统一 Key 做长期维护

单次收缩解决的是眼前的空间危机,但虚拟机用久了还会再涨。与其每次手动救火,不如把收缩做成定期任务,用 TaoToken 的统一 Key 把日志和告警串起来。

思路很简单:写一个定时脚本,每周检查各虚拟机 vmdk 的宿主机占用与 Guest 使用量差值,超过阈值就自动触发收缩,并把结果通过 API 汇总成报告。这样你不用天天盯盘,空间也不会突然爆掉。

配置上继续沿用第 3 节的三件套:Base URL 用https://taotoken.net/api,Key 从控制台生成,Model ID 按需选。把收缩目标写进 JSON,脚本读取后批量处理。定时任务用 Windows 任务计划或 Linux cron 都行:

# 每周日凌晨 3 点执行收缩检查 0 3 * * 0 /usr/local/bin/shrink_check.sh >> /var/log/vmdk_shrink.log 2>&1

长期维护还有几个实用习惯:给虚拟机目录单独放一个盘,别和系统盘混用,避免空间告急时影响宿主机;定期清理 Guest 内的日志和缓存,减少归零工作量;对不再用的虚拟机直接删除整个目录,比收缩更彻底。

如果你同时管多台机器、多个环境,统一 Key 的价值就体现出来了——不用为每个脚本单独配凭证,一个 Key 打通所有调用,日志汇总、异常告警、报告生成都能接进同一条链路。收缩本身是本地操作,但围绕它的记录和调度可以交给 API 来做,省下的是反复排查的时间。

最后提醒一句:收缩前一定确认磁盘是精简置备,厚置备磁盘收缩无效,只能通过迁移重建来回收空间。这个判断在第 2 节已经给过方法,动手前花两分钟确认,能避免白忙一场。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 7:43:57

大模型刷题服务可观测性实战:用TaoToken把异常调用看清楚

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/7 7:43:35

【愚公系列】《OpenClaw实战指南》024-短视频工厂:OpenClaw+Seedance2.0批量获客实战(从文案到分镜,TaoToken统一Key打通脚本自动化流水线)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/7 7:42:46

Superpowers实战:浏览器里的多人实时协作开源游戏开发环境

我先不按老套的“教程”写法来,直接以一个折腾过的过来人口吻聊聊。如果你在 GitHub、独立游戏社区、或者某个深夜的技术论坛里刷到过 “Superpowers” 这个词,大概率看到的不是一个夸夸其谈的励志概念,而是一个能真正跑起来、能多人实时一起…

作者头像 李华
网站建设 2026/10/7 7:42:29

RA8P1选型实战:Cortex-M85与NPU边缘AI性能深度解析

1. 从一颗芯片的命名说起:RA8P1到底是个什么定位第一次看到 R7KA8P1KFLCAC 这串型号的时候,我下意识地把它拆成了几段来读。这是我在选型阶段养成的习惯——瑞萨的命名规则里藏着不少信息,读懂了型号,基本就能判断这颗芯片能不能进…

作者头像 李华