
写这篇东西的时候我刚从一场“磁盘告急”里缓过神来。运行的Ubuntu虚拟机里根分区可用空间只剩几十MB编译几次就报No space left on device。清理缓存、删旧包、清日志折腾了一下午撑了两天又满了。这种时候最有效的解法其实不是继续在里面抠空间而是把虚拟机的磁盘从根上做大——也就是标题里说的这个事Ubuntu虚拟机磁盘扩容。这篇文章我会把从宿主侧扩展虚拟磁盘、到用gparted调整分区、再到常见错误修复的完整流程按我实际操作过的顺序讲一遍。整个过程熟练了确实能在5分钟内完成分区调整但前提是知道哪些地方容易踩坑。1. 为什么虚拟机的“磁盘满了”比物理机更棘手三层结构决定扩容方式1.1 虚拟磁盘、分区表、文件系统的嵌套关系物理机加硬盘插上就能用大不了再挂载一块新盘。虚拟机不一样它的一切都是文件。你看到的/dev/sda在宿主机的文件系统里可能只是一个.vmdk或.vdi文件。这个文件是“第一层”相当于一块真实的物理硬盘。但光有“硬盘”不够操作系统还得知道这块盘怎么切。你装Ubuntu的时候安装器会在虚拟磁盘上创建分区表可能是传统的MBR也可能是新版默认的GPT。分区表里定义了/dev/sda1根分区、/dev/sda2扩展分区里的swap等等这是“第二层”。分区建好了还要在上面格式化出文件系统比如ext4、xfs这就是“第三层”。你日常看到的/目录、/home目录都挂载在文件系统上。问题就在这光是让宿主机把虚拟磁盘文件变大是不够的。虚拟机里的Ubuntu看到的还是旧的分区表和旧的文件系统大小。你必须按照“磁盘文件 → 分区表 → 文件系统”这个顺序从外到内一层层地调整。这就是为什么很多人试着把虚拟机设置里的硬盘容量拉大进到系统里df -h看却毫无变化——因为只完成了第一层。1.2 先诊断再动手df、lsblk、pvs三件套别一上来就关虚拟机、改配置你至少需要三分钟时间搞清楚当前系统的磁盘布局。打开终端跑这三个命令df -h lsblk sudo pvsdf -h告诉你文件系统层面的使用率哪个分区满了一目了然。lsblk展示的是分区表层面的结构你能看到sda下面挂着哪些分区每个分区多大。而sudo pvs是重点——它告诉你这个系统是不是用LVM管理的。很多Ubuntu服务器版在安装时默认就是LVM布局装好后根分区是/dev/mapper/ubuntu--vg-ubuntu--lv它落在物理分区/dev/sda3上。LVM的情况比普通分区复杂后面专门讲。对照下这两个输出你的扩容策略就清楚了如果是普通ext4分区gparted一步到位如果是LVM需要在gparted扩完分区之后再到系统里跑lvextend和resize2fs。诊断为先省得后面白折腾。1.3 什么时候不该扩根分区而是加数据盘扩容之前还要想清楚一件事你确定要扩根分区而不是挂一块新盘如果虚拟机是拿来跑数据库、存日志、放代码仓库这类数据量增长明确的应用我更推荐“加数据盘”方案。虚拟机设置里再加一块虚拟磁盘系统里fdisk建分区、mkfs.ext4格式化、mount挂载到/data完事。不动根分区不动系统风险极低以后数据盘满了再给它扩容就行。但如果问题是df -h显示/已满而且你希望编译临时文件、Docker镜像、系统日志这些能继续写到根分区那就只能扩根分区。另一个判断标准是你不想改动应用的目录结构。有些应用写死了/var/lib或者/opt的路径挂新盘就得迁移数据、改配置扩根分区则没有这些麻烦。搞清楚自己的需求再进入下一步。2. 宿主侧先把“盘子”做大VMware、VirtualBox的磁盘扩展操作与细节2.1 VMware Workstation扩展与“灰按钮”的坑先明确一个操作顺序铁律改虚拟磁盘大小前一定要把虚拟机关机而不是挂起。挂起状态下内存状态还在磁盘结构不是静止的强行扩容容易出问题。关机后在VMware Workstation里右键虚拟机 → 设置 → 硬盘 → 实用工具 → 扩展。弹出的窗口里把磁盘最大容量改成你想要的数值。比如原来是20GB这次直接填60GB虚拟磁盘文件会从20GB变成60GB但内部的分区和文件系统还是20GB这就是下一节gparted的活了。我在这一步踩过坑扩展按钮是灰的点不了。查了才知道只要虚拟机存在任何快照VMware就不允许扩展磁盘。Workstation的扩展机制依赖重做日志和快照链协同有快照时磁盘头信息被锁定。解决办法是先删除全部快照或者把当前状态提交成一个新快照再删除旧的。如果你的快照是几天前做的删除前考虑要不要保留数据——删掉快照后虚拟机就回到当前状态了。还有种情况虚拟磁盘是分成多个2GB小文件的旧格式split disk扩展时VMware会提示转换格式允许它转不转换没法扩展。这个转换过程在机械硬盘宿主上可能要几分钟别中途取消否则磁盘文件会损坏。2.2 VirtualBox的VBoxManage命令与版本差异VirtualBox走命令行在宿主机上打开终端Windows是cmd/PowerShellLinux/macOS直接用VBoxManage modifymedium disk 你的虚拟机磁盘路径/ubuntu.vdi --resize 40960注意这里单位是MB40960就是40GB。新版VirtualBox用modifymedium老版本里叫modifyhd如果你输入modifyhd提示找不到命令就换成modifymedium。磁盘路径一般可以在 管理 → 虚拟介质管理 里看到全路径拷过来最稳妥避免相对路径找不到。执行完它会打印一条成功信息没有任何“哇哦”的反馈这就算成了。VirtualBox有一点比VMware宽松它允许带快照扩容。但要注意快照会占用磁盘空间扩容后虚拟磁盘文件变大加上快照可能撑满宿主磁盘所以同样建议清理快照后再操作。2.3 扩展后不要急着开机先确认宿主侧状态扩容完先别急着开机顺手做两个检查。第一确认虚拟磁盘文件的实际大小。文件管理里看.vmdk或.vdi大小应该已经变成目标数值。如果还是原大小说明命令没生效或路径不对重新执行。第二确认宿主机的剩余磁盘空间足够。虚拟磁盘扩容不是瞬间分配空间但对稀疏文件thin provisioning来说一旦虚拟机内部开始写入新数据宿主空间会被逐渐吃掉。虚拟磁盘扩到60GB宿主机最好还剩60GB以上的空间否则虚拟机写入到一半宿主满了两边一起死救援极其痛苦。这两步确认无误再把虚拟光驱挂上gparted Live ISO准备开机。这里如果你用的是VMware可以把启动顺序临时改为“CD/DVD优先”或者开机时按F2进BIOS改VirtualBox则可以在虚拟机的存储设置里把光驱挂到SATA第一个位置。反正目的只有一个让虚拟机从gparted Live引导而不是从硬盘启动。3. gparted Live分区调整实操关键五分钟和LVM分叉处理3.1 为什么选择gparted Live而非系统自带工具有人问Ubuntu系统里不是自带gparted吗sudo apt install gparted装一个不就行了为什么非要下载Live ISO重启引导核心原因只有一个你不能对正在挂载的分区做resize。系统运行时根分区/正被内核占着文件系统处于活跃状态任何分区工具都不能安全地移动它。你试过就知道在运行中的系统里用gparted选根分区右键的“调整大小/移动”是灰色不可点的。gparted Live就是把整个分区工具做成一个独立启动环境从内存盘运行不占用硬盘分区这样就能对目标分区的所有分区自由操作。另外它自带最新版分区识别库libparted对ext4、xfs、btrfs、NTFS这些格式的支持比系统源里的老版本通常更全也不受Ubuntu版本里库依赖的牵制。前文所述的“5分钟搞定”指的就是在这个Live环境里的图形操作时间很短前提是前面的引导和识别没有出岔子。3.2 挂载ISO与启动引导设置先到gparted官网下载Live ISO大约500MB左右。用虚拟机光驱挂载这个ISOVMware虚拟机设置 → CD/DVD → 使用ISO映像文件勾选“启动时连接”。进入虚拟机的BIOS开机按F2把Boot顺序里的CD-ROM Drive挪到第一位保存退出。VirtualBox存储 → 光驱 → 选择磁盘文件挂载ISO然后在系统 → 处理器 → 启动顺序把“光驱”勾到最上面。启动后你会看到一个引导菜单直接选默认项Default settings (KVM/VMware/VirtualBox)回车。它会自动启动到图形桌面。如果卡在某个加载界面不动多半是VMware里“加速3D图形”之类的选项冲突把它关掉再试。进入桌面后桌面上有一个gparted图标双击打开。默认会打开第一个找到的磁盘按经验这里很可能不是你的目标盘务必用右上角的设备下拉框切换到/dev/sda。Live环境本身跑在内存里不会占硬盘硬盘列表里那块几十GB的盘就是你的Ubuntu系统盘。3.3 纯ext4布局一条龙resize操作为了理解整个过程先看一个最简单、最常见的非LVM布局/dev/sda1是ext4根分区可能后面跟着一个swap分区。这时操作非常顺滑选中分区条上的/dev/sda1右键 →调整大小/移动。在弹出的对话框里直接在新大小栏输入目标值比如想让根分区变成50GB那就填51200MiB。也可以拖动右侧滑块把它拉到最右边。分区后面会多出一段“未分配”空间大小就是增加的容量。点工具栏上的绿色对勾应用。gparted会弹出一个“即将执行的操作”列表显示resize2fs调整文件系统和parted调整分区表这类底层命令。确认无误后点应用。这个过程中gparted会先缩小/移动分区表里的分区边界再调用文件系统工具扩展文件系统到新边界顺序是经过优化的不用你操心。完成后会显示“所有操作成功完成”。点退出重启虚拟机记得在关机前把光驱里的ISO“断开连接”或把启动顺序改回硬盘否则又得从Live引导。重启进入系统后跑个df -h根分区已经变成新大小。整个图形界面的操作确实五分钟用不完。3.4 LVM布局gparted只做半程剩下的交给lvextend如果你一开始在系统里跑了sudo pvs发现输出里有像/dev/sda3这样的物理卷被归入一个ubuntu-vg卷组那就别指望gparted一步到位了。LVM的逻辑卷在gparted里是“看不见”的gparted只能识别到物理卷/dev/sda3。你右键它选择调整大小gparted会弹一个警告这个分区是LVM物理卷调整分区大小不会调整其内部的逻辑卷和文件系统。它的意思是gparted能帮你把物理分区扩大但它不会去操作LVM的逻辑卷那需要回到系统里用LVM命令。所以LVM布局的正确流程是在gparted里右键/dev/sda3调整大小到目标Apply。此时物理卷变大但逻辑卷和文件系统还是原样。重启进系统依次执行sudo pvresize /dev/sda3 sudo lvextend -l 100%FREE /dev/ubuntu-vg/root sudo resize2fs /dev/ubuntu-vg/root第一行让LVM感知到物理卷新空间第二行把空闲空间全部划给root逻辑卷如果你还有home逻辑卷先用lvextend分给它一部分别一股脑都给root第三行扩展文件系统。如果文件系统是xfs第三行要换成sudo xfs_growfs /。这就能解释为什么很多新手在gparted里点了resize重启后df -h还是老样子——因为他用的是LVM布局只做了一半。对照自己系统的布局选择合适的方案你才不会在最后一步前功尽弃。4. 扩容之后翻车现场grub rescue、Bad magic number、容量不变等错误的排查链路4.1 开机进入grub rescue或黑屏的排查扩完分区重启最吓人的是直接进了一个黑底白字的grub rescue提示符或者黑屏只有光标闪烁。grub rescue意味着GRUB引导加载器找不到可以识别文件系统的位置了。为什么会这样绝大多数情况是你在gparted里不小心把分区“移动”了而不是单纯“调整大小”。gparted的“调整大小/移动”是一个弹窗里两个操作拖动左侧滑块会移动分区的起始位置拖动右侧滑块才是扩展末尾位置。移动起始位置这种操作会让GRUB在MBR里记录的分区偏移失效于是它找不到/boot下的文件只能掉进rescue壳。排查思路是这样GRUB既然能跑起来说明引导器的第一段已经加载问题出在它找不到/boot所在的文件系统。在grub rescue提示符下先敲ls看看它列出了哪些磁盘和分区。如果某个分区能看到比如(hd0,msdos1)那说明还有救可以用set root(hd0,msdos1)和insmod normal、normal尝试手动引导。但多数情况下这些手动操作很难一次成功我更推荐直接用gparted Live启动打开gparted检查分区表根分区的起始位置如果和扩容前的笔记对不上那确认是起始位置被动过了需要手动把起始位置挪回原值。如果实在记不住原起始位置那就从备份恢复——这就是为什么我反复强调扩容前做快照或备份。再补充一种黑屏情况启动卡在/dev/sda1: clean, ... blocks的信息然后不动。这其实不是故障是文件系统在扩展后首次挂载时要更新超级块里的块计数磁盘大的话要跑一阵子。耐心等几分钟别急着强制重启。4.2 resize2fs报Bad magic number的根因如果你在LVM流程里执行sudo resize2fs /dev/ubuntu-vg/root时看到下面这个错误resize2fs: Bad magic number in super-block while trying to open /dev/ubuntu-vg/root先别慌这不是数据损坏而是你操作的设备路径不对。/dev/ubuntu-vg/root是逻辑卷正常它的前面应有/dev/mapper/前缀比如/dev/mapper/ubuntu--vg-root。某些系统里两个路径都可访问但如果逻辑卷名带横杠/dev/ubuntu-vg/root这种简写路径可能映射不到正确节点。排查链路是先lsblk看逻辑卷的确切名字和路径再用sudo lvs看卷组里的LV有没有成功扩容。如果lvs显示LV还是旧大小说明lvextend没生效需要先检查pvresize后物理卷大小是否更新再重新lvextend。如果LV大小已经变大只是resize2fs报错那路径写全再试一次基本能解决。还有一个相似的错误Bad magic number in super-block while trying to open /dev/sda1这种情况是你对一个不是文件系统分区的东西执行了resize2fs。比如直接对LVM物理卷/dev/sda3跑了命令而不是对逻辑卷。记住ext4的resize2fs只能作用在文件系统设备节点上不能作用在物理卷或分区条目上。4.3 重启后发现容量没变partprobe与被忽略的文件系统resize这是继grub之后第二常见的翻车现场gparted明明显示操作成功重启进系统df -h却还是旧大小而lsblk显示分区已经是新大小。两个命令的结果对不上说明文件系统层面没有真正扩大。排查链路很清楚执行lsblk看/dev/sda1大小。如果还是旧的说明分区表没刷新跑sudo partprobe强制内核重读分区表或者重启。如果lsblk已经是新大小但df -h还是旧的说明文件系统没有扩展到分区末尾。执行sudo resize2fs /dev/sda1它会根据分区新大小自动扩展文件系统。如果resize2fs提示“文件系统已是最新大小”那看一下是否用了LVM——回到3.4节的流程把lvextend和resize2fs跑完整。这类问题之所以容易让人晕就是因为df、lsblk、pvs三个命令各看一层你只看其中一个就下结论永远看不出全貌。排查时把三张输出放一起对照分层确认问题基本水落石出。4.4 swap UUID变化导致的启动失败swap区域在扩容过程中被移动过位置的话它的UUID会变但/etc/fstab里写的还是旧UUID开机就会卡在“等待挂载swap”类似的提示或者干脆进入emergency mode。排查方法启动后等它进入emergency模式输入root密码执行blkid找到现在swap分区的UUID然后编辑/etc/fstabsudo nano /etc/fstab把swap那一行的UUID改成新值保存退出reboot就好。如果没进emergency模式也可以直接在系统里检查sudo swapon --show cat /etc/fstab两者对不上就改。这个问题如果你只用gparted扩展根分区而不碰swap基本不会遇到但只要动了swap分区就一定小心。4.5 扩展途中中断或失败的数据恢复思路最糟糕的情况应用操作刚执行到一半虚拟机停电/宿主蓝屏/误操作点了取消gparted卡在“正在调整文件系统”然后整个窗口消失。这时候最重要的是别慌千万别对磁盘再执行任何其他操作。gparted的底层操作是先扩展文件系统再扩展分区如果死在扩展文件系统的半路多数情况是超级块已经更新、数据块索引还没完全建立这会在下次启动时触发文件系统自检有一定概率修复。你可以用gparted Live启动不要点任何自动修复先打开终端执行sudo fsck.ext4 -f /dev/sda1让文件系统做一次全量校验。如果校验通过就重启如果提示大量错误建议马上停止利用gparted自带的“尝试数据救援”功能Device → Attempt Data Rescue或者交给专业工具处理。说实话我见过死在半路的案例最终能完整恢复的概率不到一半所以一句话扩容前备份或快照永不嫌多。特别是对里面有数据库、代码仓库这种重要数据的虚拟机花十分钟做快照可能省下你后面一整天。5. 磁盘扩容后的收尾工作与几条实用经验5.1 数据完整性与分区对齐验证扩容完成重启进系统别急着开始干活先跑一轮基础验证。我习惯按这个顺序来df -h lsblk sudo pvs sudo lvs四张表对一遍确认分区、物理卷、逻辑卷、文件系统四个层面的容量都是一致的目标值。如果是LVM布局pvs显示的PFree应该所剩无几因为都划给了root逻辑卷或者留了一点给home。然后看一眼分区对齐sudo parted /dev/sda align-check optimal 1输出1 aligned说明分区对齐没问题。对齐这事在虚拟磁盘上不如裸金属SSD敏感但不对齐会导致随机读写性能下降确认一下没坏处。如果gparted在resize时默认开启了MiB对齐一般都会对齐这一步是保险。最后跑一次sudo fsck -f /dev/sda1注意ext4的-f是强制检查即使文件系统显示clean也会完整扫一遍数据块和inode。数据无价扫完放心。5.2 扩容后系统内的终极检查清单经过前面那些操作系统已经能正常启动了。但我觉得还差一个“终极检查清单”把容易被遗忘的小事一网打尽Docker空间如果你用Dockerdocker system df看看镜像和容器占了多少。/var/lib/docker现在有空间了可以放心拉镜像但也要注意镜像占空间的速度远比想象中快。日志轮转journalctl --disk-usage看一下systemd日志占多大。很多时候磁盘满就是日志撑的顺手设个上限journalctl --vacuum-size500M或者编辑/etc/systemd/journald.conf设SystemMaxUse500M。临时文件/tmp和/var/tmp里可能有旧文件sudo tmpreaper或者手动清理一下给新扩容的根分区一个干净的起点。重新检查fstab如果扩容过程中UUID有任何变化/etc/fstab已经改过了再确认一遍没有新的报错sudo mount -a跑一下如果无输出无报错说明挂载配置没毛病。这套检查下来你的虚拟机在很长一段时间内都不会再因为“没空间”而半路抛锚。5.3 我的几条经验快照、备份、磁盘类型选择最后分享几条实操中攒下来的经验。第一扩容前做快照还是备份快照不一定可靠特别是跨版本文件系统操作有些文件系统变更会破坏快照链里的旧状态。我的习惯是重要虚拟机先做一次完整备份导出ovf或复制vmdk再做快照。导出备份虽然慢但它是独立副本出任何问题都能退回去。快照更适合做“短期的临时保险”别指望它是长期备份方案。第二在扩容前的初始创建阶段就选对虚拟磁盘格式。VMware里可以用精简置备thin provision让磁盘文件逐步增大但精简盘的缺点是扩容时宿主机剩余空间不够会导致失败。我倾向于重要虚拟机用厚置备thick provision固定大小性能稳定、扩容也稳妥缺点是一开始就占满空间。VirtualBox的.vdi默认是动态分配但它在扩容命令里不支持“立即分配全部空间”只能在虚拟机内部写入时才慢慢变大。选型没有绝对的对错但你要知道自己选的是什么不要等到磁盘爆了才发现宿主空间被吃光了。第三别在“5分钟”里包含下载ISO的时间。gparted Live ISO约500MB下载快慢取决于网络挂载引导、启动到桌面、确认磁盘、执行resize这之后的过程确实5分钟足够。但如果你边看教程边操作第一次做最好给自己留出半小时——不排队不慌张才不容易误操作。6. 另一个容易被忽略的点分区表是MBR还是GPT决定了你能扩到多大MBR分区表是传统的BIOS引导方式GPT是UEFI时代的替代品。这两种分区表对扩容上限的影响非常直接MBR的单分区最大支持2TBGPT则支持到9.4ZB基本没有上限。如果你的虚拟磁盘要扩到超过2TB而且现有分区表还是MBR那你就不能光靠gparted做扩展得先做MBR转GPT的转换。gparted支持这个操作Device → Create Partition Table选择gpt但这一步会清空分区表所以必须在扩容前先做完整备份并且转换后GRUB引导也要重新修复。老实说如果不是有特殊需求我建议普通虚拟机在装系统时就直接选GPT分区表UEFI引导省掉后面这堆麻烦。如果你只是想扩到50GB、100GB这种量级那MBR完全不是障碍不用纠结。看看自己虚拟机用的什么分区表再决定后续怎么操作。虚拟机里通常用UEFI固件 GPT老一点的是BIOS MBR两种我都试过没做过GPT转换的MBR盘扩到2TB以下都没问题别被一些教程里的“必须用GPT”说法吓到。7. 最后的真心话磁盘扩容这事越早规划越好回到开头那个场景编译半天报“磁盘满”确实让人血压升高。但如果你早一点养成定期看磁盘使用率的习惯——比如每个月初跑一次df -h或者给监控工具配个磁盘告警——你完全可以在磁盘满之前就从容地做扩容而不是在告警声中手忙脚乱。我个人的习惯是给虚拟机留至少20%的余量空间。用到80%就想扩容方案而不是等到98%再来救火。这样做的好处是你永远有足够的临时空间来处理迁移、备份、日志这类“扩容前置操作”不至于陷入“没空间所以无法备份无法备份所以不敢扩容”的死循环。这篇文章的操作链路可以浓缩成一句话宿主侧把磁盘文件放大gparted把分区和文件系统拉长LVM用户再补一发lvextend和resize2fs最后用四张命令表确认结果。按这个思路走Ubuntu虚拟机磁盘扩容就是一件可以“从容搞定”的日常操作而不是每次都要查一遍资料、踩一遍坑的噩梦。