1. 扩容前先做三个确认:这决定了你后面是三个命令还是四个小时
先说一个我自己的经历。有次给一台 Ubuntu 虚拟机扩磁盘,VMware 里硬盘容量从 50GB 拉到 200GB,整个过程一路绿灯,重启系统后我满怀期待地去敲df -h,结果根分区还是 50GB。当时第一反应是 VMware 那边没操作成功,后来排查了半天才发现:VMware 只负责把“虚拟磁盘文件”变大,Ubuntu 里还有分区表和文件系统两层结构等着你去改。这个教训让我之后再遇到扩容需求,都会先逼自己回答三个问题,省下后面的冤枉路。
1.1 先弄清“缺空间”缺在哪一层
磁盘空间在虚拟机里其实是四层结构,从上到下依次是:
- 虚拟磁盘文件层:就是
.vmdk文件有多大,VMware 图形界面里显示的“硬盘大小”就是指这一层。 - 磁盘设备层:Ubuntu 内核识别到的
/dev/sda、/dev/nvme0n1等块设备大小,用lsblk或fdisk -l能看到。 - 分区层:块设备被划分出的
/dev/sda1、/dev/sda2等分区,大小由分区表决定。 - 文件系统层:分区上格式化的 ext4、xfs 等文件系统,
df -h看到的就是这一层。
常见误区是大家觉得“虚拟机磁盘扩容”就是一次性把上面四层全部搞定,实际上 VMware 只能修改第一层,后面三层需要你在 Ubuntu 里依次处理。如果你只是发现/根分区空间告急,其他分区还有很多余量,那么有些情况下根本不用动第一层,直接把其他分区的空闲空间挪过来就行——这就是典型的“分区层和文件系统层问题”,用 LVM 或者 GParted 就能解决,压根不需要碰 VMware 的东西。
所以动手之前,先执行lsblk、df -hT、fdisk -l三连,把当前磁盘、分区、文件系统使用情况摸清楚。我见过不少新手一上来就把 VMware 磁盘调到巨大,结果发现系统里全是 ext4 裸分区,还得折腾分区表,反而把简单问题复杂化了。
1.2 快照链必须提前处理,否则 VMware 扩展按钮会跟你“打太极”
第二个确认点是虚拟机有没有快照。VMware Workstation 里如果你给虚拟机建过快照,并且快照链没有清理,那么打开“虚拟机设置 — 硬盘 — 扩展”的时候,有很大概率遇到两种情况:一是扩展按钮是灰色的点不动,二是能点但提示需要关闭虚拟机或提示快照会影响操作。
快照的本质是保存磁盘某个时刻的状态,它会让虚拟磁盘在逻辑上多出一个“差异层”。在这个基础上继续扩大磁盘,VMware 需要处理的就不只是单纯的扩容,还会牵扯到快照链的一致性。生产环境里我最推荐的做法是:扩容之前先把不需要的快照删除,让快照链合并完成,再去做扩容操作。如果你确实需要保留一个回滚点,那就在扩容前先创建一个完整快照,扩容结束、系统验证没问题之后,再把这个临时快照删掉。注意这里说的“删除快照”是合并快照数据,不是简单丢弃,合并过程可能需要一些时间和磁盘空间,建议提前确认宿主机剩余空间足够。
如果是 VMware vSphere/ESXi 环境,快照对在线扩展磁盘的影响相对小一些,但同样建议在变更窗口内先处理掉多余快照。这个习惯我吃了好几次亏之后才养成的,有一次在 vSphere 上对一个带快照的虚拟机磁盘做热扩展,操作虽然成功了,但后续虚拟机性能明显下降,查了半天才发现是快照合并和扩容同时在进行,IO 压力巨大。
1.3 不同 VMware 产品线的操作方式差异很大
还有一个经常被忽略的确认点:你用的是 VMware Workstation/Fusion,还是 vSphere/ESXi?
- VMware Workstation/Fusion:操作在“虚拟机设置”里完成,大多数版本需要虚拟机处于关机状态才能修改磁盘大小。少数场景下虚拟机开机时扩展按钮是灰的,得关机后才能调整。
- VMware vSphere/ESXi:通过 vCenter 或 Web Client 编辑虚拟机设置,支持在线热扩展,不需要关机。但是注意,这里热扩展的只是虚拟磁盘大小,分区和文件系统层面仍然需要进入系统内操作,不过好消息是 Ubuntu 的
resize2fs、xfs_growfs、growpart这些命令也支持在线执行,所以整个流程可以做到不停机,只是操作时需要更加小心。
此外还要看一下虚拟机兼容性版本。比较老的虚拟机硬件版本,磁盘最大值上限比较低,如果你想把磁盘扩到非常大(比如单个虚拟磁盘超过 2TB 甚至更大),可能需要先升级虚拟机硬件版本。这个在 VMware 的“虚拟机设置 — 选项 — 高级 — 配置参数”里能查到一些信息,但最直接的判断方法是:如果扩展时输入的容量上限明显不合理,十有八九是硬件版本太老。
把上面三个问题想清楚之后,才算真正具备了开工条件。下面我按照实际操作的顺序,分别讲 VMware 层、分区层、文件系统层分别该怎么做。
2. VMware 层操作:把虚拟磁盘文件的物理容量真正撑大
这一步对应我们前面说的第一层——虚拟磁盘文件层。操作的目标是让 VMware 认为这台虚拟机的硬盘“长胖了”,但 Ubuntu 此刻还完全不知情。
2.1 图形界面路径与关机要求
VMware Workstation 的常规路径是:
- 选中虚拟机,点击“编辑虚拟机设置”(或右键选择“设置”)。
- 在“硬件”选项卡里选中“硬盘”。
- 右侧可以看到“磁盘文件”(
.vmdk路径)和“最大大小”之类的信息,点击下方的“扩展”或“磁盘实用程序”相关按钮。 - 输入新的磁盘大小,点击“扩展”确认。
需要注意的关键点:
- 关机操作建议先做。即使你的版本允许开机扩展,我也建议在关机状态下操作。原因很简单:开机状态下扩展磁盘,虽然虚拟磁盘层扩大了,但分区表操作时系统可能仍在写入磁盘,一旦顺序不对,数据一致性风险更高。关机操作之后,后续在 Ubuntu 里在线扩展文件系统反而更安全。
- 扩展的大小可以一次性给足。比如你当前是 50GB,想扩到 200GB,就直接输入 200GB,不用分多次。后面所有分区和文件系统层面的调整都建立在“虚拟磁盘总量变大”的基础上,多给一点预留空间是明智的,Linux 系统运行时日志、Docker 镜像、临时文件涨起来非常快。
- 确认扩展后的容量数字。点击扩展之后,界面上的硬盘大小会变化,但此时
.vmdk文件在宿主机上可能仍是稀疏文件,实际占用的物理空间不会立刻变大,这个属于正常现象,不要被宿主机目录下的文件大小吓到。
VMware vSphere 的操作则在 Web Client 里:编辑设置 → 硬盘 → 将“容量”字段改成目标值 → 保存。这个过程虚拟机可以保持开机状态,但同样要保证磁盘没有被配置成“独立且不支持扩展”的某些特殊模式。
2.2 命令行方式:vmware-vdiskmanager
如果你的虚拟机文件不在图形界面方便操作的位置,或者你在 Linux 宿主机上、需要通过脚本批量调整,可以使用 VMware 自带的命令行工具:
vmware-vdiskmanager -x 200GB /path/to/your-vm/disk.vmdk参数-x后面跟目标大小,单位可以是GB、MB,这个命令同样要求在虚拟机关机状态下执行。执行完之后用vmware-vdiskmanager -d disk.vmdk做一次磁盘碎片整理(可选),或者用vmware-vdiskmanager -r做磁盘收缩,但扩容场景下没必要。
需要提一句:这条命令只对非快照状态、或者快照链比较简单的虚拟磁盘有效。如果虚拟机包含快照,vmware-vdiskmanager会提示你先删除快照或使用其他参数。我一直觉得命令行方式更适合自动化运维场景,手工操作时图形界面反而更直观。
2.3 验证 VMware 层是否成功
这一层是否成功,其实不需要等进入 Ubuntu 再验证。你可以在 VMware 界面上确认容量数字已变化,也可以在 Ubuntu 里开机后执行:
lsblk如果/dev/sda的大小已经显示为 200GB,说明第一层成功;如果还是 50GB,请回到 VMware 层检查是否真的点击了“扩展”,以及是否有关机后重试。
但请记住:到这里只是万里长征第一步。很多时候我们以为扩容完成了,其实只是完成了 1/4,后面分区和文件系统才是真正的重头戏。
3. Linux 层第一步:让分区表和磁盘设备对齐
现在进入 Ubuntu 系统内部。我们的目标是让/dev/sda从 200GB 这个块设备里,把多出来的空间“划”给某个分区。这一步是最容易出问题的,很多人就是在这一层忘记操作,导致后面df -h毫无变化。
3.1 先看现状:lsblk 是万能的起点
开机后在终端执行:
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT输出大致会是这样的:
NAME SIZE TYPE FSTYPE MOUNTPOINT sda 200G disk ├─sda1 512M part vfat /boot/efi ├─sda2 1G part xfs /boot └─sda3 49G part LVM2_member └─vg-root-1 49G lvm ext4 /这里的关键信息在sda这一行:磁盘已经是 200GB,但sda3分区只有 49GB,说明多出来的 150GB 空间还没有被任何分区使用。接下来要做两种可能的分区操作,取决于你的 Ubuntu 是简单的单分区裸文件系统,还是用了 LVM。
同时我还会习惯性地执行一下:
df -hT确认当前根文件系统类型。Ubuntu 默认如果是自动分区,大概率是 LVM + ext4;如果是手工分区,很可能是 ext4 或 xfs 直接放在/dev/sdaN上。文件系统类型决定了后面该用哪条命令。
3.2 MBR 和 GPT 的分区判断与 growpart 的选择
在准备把分区扩大的时候,先确认分区表类型。执行:
sudo parted -l如果看到Partition Table: gpt,那就是 GPT;如果看到msdos,那就是 MBR。绝大多数现代 Ubuntu 装机默认是 GPT,但一些由老模板克隆出来的虚拟机可能是 MBR。
为什么这个判断如此重要?因为 MBR 对于单个磁盘最大只支持 2TB,如果你想扩容超过 2TB,MBR 表是不行的,需要转成 GPT;另外 MBR 支持的主分区数量有限,如果磁盘上已经有 4 个主分区,再去扩展某个分区时处理逻辑会复杂很多。不过对于普通的 Ubuntu 虚拟机,如果你只是把磁盘从 50GB 扩到 200GB,MBR 还是能轻松应付的。
确定分区表类型之后,扩容分区最顺手的工具是growpart。它来自cloud-guest-utils包,在多数 Ubuntu 云镜像和桌面系统里可能已经预装,没有的话安装一下:
sudo apt update sudo apt install -y cloud-guest-utils用法非常简单,第一个参数是磁盘设备名,不写/dev/前缀,第二个参数是分区号:
sudo growpart /dev/sda 3这条命令的作用是把这个分区扩展到磁盘剩余可用空间的末尾。假如/dev/sda3之后已经没有其他分区,那它就直接吃掉所有剩余空间;如果后面还有别的分区,那它只能扩展到下一个分区之前。所以做完lsblk之后,一定要确认你想要扩展的分区是磁盘上的最后一个分区。如果有分区排在它后面,比如sda3后面还有个sda4,那你在 VMware 层扩容出来的空间就落在了磁盘末段,中间隔着sda4,你就没法直接把sda3扩到磁盘末尾。这种情况比较复杂,我放到第五部分“踩坑实录”里说。
growpart执行成功后会输出类似 “partition 3 on device /dev/sda changed” 的信息。此时再看lsblk,sda3的大小应该已经变成接近 200GB 了。
如果你更喜欢用 parted,也可以这样:
sudo parted /dev/sda (parted) resizepart 3 100% quitresizepart 3 100%的意思是把 3 号分区扩展到磁盘 100% 的位置。两者效果一致,差别主要在自动化脚本场景下growpart更容易判断边界。
3.3 实操演练:从 50GB 扩到 200GB 的完整命令序列
我把最简单的裸分区场景完整写一遍,假设你的 Ubuntu 根分区是/dev/sda2,文件系统是 ext4:
# 1. 确认磁盘和分区现状 lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT df -hT # 2. 安装 growpart(如果没有的话) sudo apt update && sudo apt install -y cloud-guest-utils # 3. 扩展分区到磁盘末尾 sudo growpart /dev/sda 2 # 4. 查看分区是否变大 lsblk /dev/sda到这里还差最后一步——文件系统扩容。这一步不做,df -h依旧没有任何变化,分区虽然大了,但文件系统还不知道自己可以变胖。
4. Linux 层第二步:文件系统吸收新分配的空间
文件系统扩容是最后一道工序。做完这一步,df -h才能真正看到空间涨上去。这里根据文件系统类型分为三套完全不同的命令,别搞混。
4.1 最常见场景:ext4 直接用 resize2fs
如果你的文件系统是 ext4,扩容命令异常简单:
sudo resize2fs /dev/sda2这个命令在 ext4 上支持在线扩容,也就是说分区处于挂载状态也能执行,非常适合虚拟机不停机操作。它默认会扩展到分区大小的 100%,你不需要指定具体数值。执行完成后用df -h /验证,目标空间应该已经出现。
有几个细节值得多说一句:
- 如果系统提示“run e2fsck first”,说明文件系统可能有不一致标记,建议先执行
sudo e2fsck -f /dev/sda2,注意这里的-f是强制检查,不要在文件系统挂载在生产环境下随意执行,最好在维护窗口或备用维护模式下做。检查完之后再次运行resize2fs即可。 resize2fs可以用-p参数显示进度,比如sudo resize2fs -p /dev/sda2,扩容大分区时能看到百分比,心里更有底。- 如果是 ext3,同样可以用
resize2fs;如果是 ext2,也适用,不过现在 Ubuntu 基本都升到 ext4 了。
4.2 一不留神就报错的场景:xfs 要挂载到某个目录再扩容
如果你的根文件系统是 xfs,命令逻辑就完全不同了。xfs 不支持缩容,支持在线扩容,但方式特殊:xfs_growfs必须指定挂载点,而不是指定设备路径。
假设/dev/sda2挂载在/,那么:
sudo xfs_growfs /这个命令会让挂载在/上的文件系统扩展到分区大小。如果你的数据盘挂载在/data,那就改成sudo xfs_growfs /data。
很多人在这一步惯性思维敲了sudo xfs_growfs /dev/sda2,结果得到一个错误提示。这是 xfs 和 ext4 区别比较大、最容易踩坑的地方。xfs 在扩容前不需要执行检查命令(虽然也可以做xfs_repair,但那需要在卸载状态下执行,不建议日常操作)。
4.3 LVM 场景:pvresize 和 lvextend 的顺序不能反
现在回到 Ubuntu Server 最常见的安装方式:LVM。很多生产环境的 Ubuntu 在安装时自动分区会把根文件系统放在逻辑卷里,lsblk输出会看到类似/dev/mapper/ubuntu--vg-ubuntu--lv这样的设备。此时分区表和文件系统中间还夹着一层 LVM,扩展顺序是:
- 扩展物理卷(PV),让它知道底层分区变大了。
- 扩展逻辑卷(LV),把新空间分配给根逻辑卷。
- 扩容逻辑卷上的文件系统(ext4 或 xfs)。
具体命令如下,假设底层分区是/dev/sda3,逻辑卷是/dev/mapper/ubuntu--vg-ubuntu--lv:
# 1. 扩展物理卷 sudo pvresize /dev/sda3 # 2. 查看卷组剩余空间 sudo pvs sudo vgs # 3. 把卷组所有剩余空间分配给根逻辑卷 sudo lvextend -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv # 4. 如果逻辑卷上是 ext4 sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv # 4'. 如果逻辑卷上是 xfs sudo xfs_growfs /这里有个顺序细节值得注意:lvextend后面修饰-l是百分比,修饰-L是绝对容量。+100%FREE表示把所有剩余空间都加给逻辑卷,这个写法在日常运维里很好用,不用自己算大小。执行完lvextend后用lvs查看逻辑卷大小,确认无误再执行最后的文件系统扩容命令。
我还见过一种情况:物理卷扩容后没有pvresize,直接去lvextend,结果系统提示没有可用空间。这是因为 LVM 并不知道底层 PV 已经变大,必须先同步——这就是为什么顺序不能反。pvresize是 LVM 扩容流程的“信号灯”,你跳过了它,后面全是徒劳。
为了方便对照,我把常见场景的命令整理成一张速查表:
| 场景 | 分区扩容命令 | 文件系统扩容命令 |
|---|---|---|
| 裸分区 + ext4 | sudo growpart /dev/sda 2 | sudo resize2fs /dev/sda2 |
| 裸分区 + xfs | sudo growpart /dev/sda 2 | sudo xfs_growfs / |
| LVM + ext4 | sudo pvresize /dev/sda3 | sudo lvextend -l +100%FREE /dev/vg/lv && sudo resize2fs /dev/vg/lv |
| LVM + xfs | sudo pvresize /dev/sda3 | sudo lvextend -l +100%FREE /dev/vg/lv && sudo xfs_growfs / |
完成文件系统扩容后,df -h应该能看到目标分区容量变成预期值。到此为止,四层结构全部打通,扩容才算真正完成。
5. 踩坑实录:那些“扩完没变化、起不来、不敢扩”的现场
这部分是我最想分享的。扩容操作本身不复杂,真正费时间的是各种各样符合直觉但实际错误的情况。
5.1 重启后空间没变化:忘了分区层
这个坑我在开头提过。症状非常典型:VMware 里显示磁盘已经变大,Ubuntu 里lsblk也显示出块设备变大,但df -h一点变化都没有。原因是跳过了growpart或pvresize,分区表还停留在旧尺寸,文件系统自然无法扩展。
解决办法很简单:回头执行对应的分区扩容命令,再执行文件系统扩容命令。这里我想强调的是排查顺序,不要一上来就怀疑 VMware 那边有问题,先用lsblk看块设备大小,再用parted -l看分区表大小,最后用df -h看文件系统大小,问题马上定位到某一层。
5.2 想扩的分区不是磁盘最后一个分区
前面提到过,growpart只能在分区末尾扩展。如果你的目标分区后面还跟着别的分区,比如典型的双系统布局:sda1是/boot/efi,sda2是根分区,sda3是数据分区,而你想扩的是中间那个根分区,那么 VMware 扩容出来的空间在物理上落在磁盘末尾,中间隔着一个sda3,你没法直接把sda2扩到磁盘末尾去。
这种情况有两条路可选:
- 把
sda3的数据搬走,删除这个分区,再扩展sda2,最后重建sda3并恢复数据。操作风险高,不推荐在没有备份的情况下做。 - 用 GParted Live CD 启动虚拟机,把
sda3整体向后移动,腾出中间的空闲空间,再扩展sda2。注意分区移动比删除重建风险更大,因为要重写文件系统的块位置信息,操作时间也长,建议在虚拟机离线状态下进行,且提前备份重要数据。
大部分生产虚拟机不会遇到这种布局,但如果你手上正好有这样一台,我劝你别头铁,先把数据备份出来,然后考虑重新规划磁盘布局。
5.3 VMware 里“扩展”按钮灰色或报错
按钮灰色一般有两个原因:虚拟机处于开机状态(Workstation 里比较常见),或者快照链存在。关机后再看,如果还灰,就去快照管理器里把所有快照删除/合并,然后再试。
还有一种情况是虚拟磁盘被设置成了“独立磁盘”模式。这种模式下磁盘不参与快照,也不一定支持在线扩展,需要在磁盘的高级选项里取消独立模式,不过这通常要求关机操作。
5.4 扩容之后系统起不来了
这多半发生在你调整分区表时把引导分区弄坏了,比如growpart错误地扩展了一个包含引导信息的逻辑分区,或者 parted 操作 MB R 分区时不小心改动了启动标记。如果遇到开机进入 Grub 救援模式,不要急着重装系统,先用 Ubuntu 安装 ISO 启动到 Live 环境,挂载根分区,检查引导配置和分区表。
一种常见的修复思路是:
# 在 Live 环境中 lsblk sudo mount /dev/sda2 /mnt sudo mount /dev/sda1 /mnt/boot/efi sudo mount --bind /dev /mnt/dev sudo mount --bind /proc /mnt/proc sudo mount --bind /sys /mnt/sys sudo chroot /mnt grub-install /dev/sda update-grub exit sudo reboot不过对于普通用户来说,更稳妥的选择其实是在动手前给虚拟机做一个干净快照,出问题直接回滚,比任何修复手段都快。我在手工调整非 LVM 裸分区布局时,几乎强制自己先拍快照再干活。
5.5 “不敢扩”的心理障碍:在线还是离线、先备份还是先扩容
很多读者看完前面可能会问:我到底应该关机操作还是在线操作?生产环境要不要备份?
我的经验是:能离线就离线,不能离线就至少做一次完整快照或备份后再在线扩。虽然growpart、resize2fs都支持在线,但在线操作的每一步都有极小概率碰到 IO 错误、断电、内核锁冲突等意外,这时候哪怕损失 1% 的概率,发生在生产环境就是 100% 的事故。我自己处理测试机时经常图省事在线扩,但生产 VM 一定是先在维护窗口内关机、快照、扩展磁盘、进入系统调整分区、完成后验证再开机。
6. 我的实践笔记:一个可以照抄的扩容流程清单
这篇文章写到最后,我想把一套经过多次验证的流程完整整理出来,你可以直接存下来当操作清单。
- 确认平台:Workstation 还是 vSphere,决定是否需要关机。
- 确认数据安全:执行
sudo fdisk -l、lsblk、df -hT,把当前布局截图或记录在案。 - 备份 / 快照:VMware 层做快照,如果虚拟机关机了,也可以直接复制
.vmdk文件作为冷备份。 - VMware 层扩展:把虚拟磁盘大小改到目标值。
- 进入 Ubuntu,执行
lsblk确认块设备变大。 - 判断文件系统类型与分区布局,确定是裸分区还是 LVM。
- 裸分区:
sudo growpart /dev/sda N,然后根据文件系统执行resize2fs或xfs_growfs,命令分别对应/dev/sdaN和挂载点。 - LVM:
sudo pvresize /dev/sdaN→sudo lvextend -l +100%FREE /dev/vg/lv→ 再按文件系统执行resize2fs /dev/vg/lv或xfs_growfs /。 - 验证:
df -hT、lsblk,确认空间符合预期。 - 清理快照 / 备份:保留一段时间后,确认系统稳定再删除临时快照。
最后分享两个小习惯。第一个是我现在几乎默认给重要虚拟机用 LVM,因为 LVM 在后续扩容时不用考虑分区位置,pvresize + lvextend两条命令就能完成几乎所有操作,远比裸分区调整省心。第二个是每台虚拟机我都会在/root下留一份简单的扩容记录,写好当时执行过的命令和日期,下次再操作时直接翻记录,比重新回忆快得多。
磁盘扩容这个需求永远不会消失,尤其是跑 Docker、日志系统或数据库的 Ubuntu 虚拟机,空间增长速度往往超出预期。把这套流程吃透之后,你会发现不管是 Workstation 还是 vSphere,不管是 ext4 还是 xfs,核心思路都是一致的:先把虚拟磁盘做大,再把分区表对齐,最后让文件系统吸收空间。牢记这个顺序,你就已经超越了大多数只会点“扩展”按钮的运维新手。