简介:面向使用VMware虚拟机运行Linux系统的运维、开发与测试人员,这份文档精准解决虚拟磁盘空间耗尽导致的软件安装或服务异常问题。内容以Red Hat Enterprise Linux为环境,从VMware Workstation的编辑虚拟机设置扩展硬盘容量开始,逐步演示fdisk创建新分区、重启识别设备、mkfs格式化分区、mount临时挂载以及修改fstab实现开机自动挂载等完整流程,每个环节都给出具体命令和关键提示;同时针对磁盘无剩余空间的情况,补充了通过新增硬盘并重复分区格式化流程的备选方案,使处理思路更完整。压缩包为单个docx文档,大小324KB,步骤连续、条目清晰,便于边看边操作,也可按需标注。目前已有6500余人学习使用,对急需扩展虚拟机容量、又不想重装系统的用户来说,是一份能直接照做的操作参考。
1. 给 Linux 虚拟机加盘不是点两下就完:扩容前先把这三件事想清楚
当df -h输出显示根分区使用率已经到 98%,而业务日志还在继续写,你就知道这个周末大概率要搭进去了。很多人在 VMware Workstation 里找到虚拟机设置,把硬盘大小从 40GB 改成 80GB,点确定,进入系统后发现df -h还是原来那个死样子,甚至重启后直接掉进 grub 的 rescue 界面。标题里说的「Linux 中 VMware 虚拟机增加磁盘空间的扩容操作」,其实不是一个按钮能完成的事,它至少包含两层动作:第一层在 VMware 虚拟机层面把虚拟磁盘的容量上限放大,第二层在 Linux 系统内把新空间分配给分区、物理卷和文件系统。这篇文章写给那些自己维护 Linux 虚拟机、管测试环境,或者在公司 VMware 平台上给虚机扩盘的工程师。动手之前,先确认三件事:分区是不是 LVM、虚拟机有没有快照、文件系统是 xfs 还是 ext4。这三件事决定了你后面要敲的命令完全不同。
2. 扩容前置检查:用常用命令摸清分区类型、LVM 和快照占用
2.1 先看分区和文件系统:df、lsblk、fdisk 命令组合
不管你是给 CentOS 还是 Ubuntu 虚拟机扩容,第一步都是用 Linux 常用命令把当前磁盘和分区结构拍一张快照。注意,命令输出一定要留底,后面扩容完要拿它做对比。
# 1. 查看文件系统使用率,确定到底哪个分区满了 df -h # 2. 查看块设备层级,确认虚拟磁盘和分区的对应关系 lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT # 3. 查看分区表,确认是 MBR 还是 GPT,以及分区起始扇区 sudo fdisk -l /dev/sda逻辑说明:df -h看到的是文件系统视角,比如/dev/mapper/centos-root挂载在/下,使用率 98%。lsblk看到的是内核块设备视角,能看出/dev/sda下面挂着/dev/sda1、/dev/sda2,而/dev/mapper/centos-root是 LVM 逻辑卷,它底层的物理设备其实是/dev/sda2。fdisk -l最关键的是确认分区表类型和每个分区的起始扇区,因为后面如果你要手工调整分区大小,起始扇区必须保持不变,否则数据全毁。
参数说明:这里的/dev/sda是虚拟机的第一块 SCSI 磁盘,如果你的虚拟机配置的是 IDE 或者 NVMe 盘,设备名会变成/dev/hda或/dev/nvme0n1,后续所有命令里的盘符都要跟着变。lsblk的FSTYPE列如果显示LVM2_member,说明这个分区已经被 LVM 接管;而文件系统类型要看挂载点那一行。
2.2 确认是不是 LVM:pvs、vgs、lvs 的输出怎么读
如果你希望只调大根分区而不动数据,最理想的情况是这台 Linux 用了 LVM。确认方法用pvs、vgs、lvs这三条命令。
# 查看物理卷:确认 /dev/sda2 是不是物理卷 sudo pvs # 查看卷组:确认还有多少空闲空间 sudo vgs # 查看逻辑卷:确认根分区对应的逻辑卷路径和当前大小 sudo lvs逻辑说明:pvs输出里如果是空的,说明这个系统没有用 LVM,那扩容只能走 fdisk 改分区表的路子。如果看到PV /dev/sda2 VG centos,后面扩容会简单很多:先把虚拟磁盘调大,再用pvresize把物理卷撑大,然后把逻辑卷撑大,最后刷新文件系统。vgs里有一列VFree,这是卷组当前可用的空闲空间,但它和虚拟磁盘可扩展空间不是一回事。lvs里要记下 LV Name 和 Path,比如/dev/centos/root,因为后面lvextend要用。
参数说明:系统在安装时如果勾选了自动分区,Red Hat 系通常默认用 LVM,Ubuntu Server 默认也会用 LVM,但 Ubuntu 桌面版和部分自定义分区方案不是。另外注意VFree为 0 不代表没救,因为物理卷本身可能还有剩余空间没分配给逻辑卷,pvs里的PFree才是物理卷空闲,这两个字段要一起看。
2.3 容量不够的隐藏原因:快照和磁盘格式的坑
动手扩容前,还要检查虚拟机有没有快照。VMware Workstation 里如果虚拟机存在快照,磁盘扩容按钮是灰的,或者扩容后虚拟磁盘文件还是旧的大小,因为快照链里的子 vmdk 文件还保存着旧的分区表描述。
在宿主机上找到虚拟机的磁盘文件,用ls -lh看一下:
# 在宿主机(Windows 或 Linux)上查看虚拟磁盘文件属性 # Windows 下在资源管理器里看 .vmdk,Linux 下执行: ls -lh /data/vms/linux01/*.vmdk逻辑说明:如果看到linux01-snapshot1.vmdk这类文件,说明虚拟机有历史快照。快照会占用大量宿主机空间,继续扩容也容易把宿主机磁盘撑爆。所以扩容前需要先删除或合并所有快照,再回来调整磁盘大小。这个步骤千万不能省,我在实际项目里见过虚拟机扩容后进不去系统,查到最后就是快照链过长导致磁盘描述元数据不一致。
另外,VMware Workstation 默认创建的虚拟磁盘是精简置备(thin provisioning)类型,扩容后虚拟磁盘文件不会立刻变大,而是按需增长。这本身不是问题,但你要确认宿主机剩余空间大于扩容差值,否则虚拟机一写入新空间,宿主机就满了,虚拟机会直接卡死。
3. VMware 层扩容:图形界面与命令两种路径及参数设置
3.1 在 VMware Workstation 里把虚拟磁盘调大:需要注意的界面选项
先说最直接的图形界面操作。打开虚拟机设置,选到硬盘,点「Utilities」,再点「Expand」,输入新大小,比如从 40GB 改成 80GB。注意这里只能调大,不能调小,而且必须保证目标大小大于当前分区占用的实际数据量。点确定后,VMware Workstation 会提示 "The disk was successfully expanded"。
这里有几个界面上的坑。第一,如果虚拟机有快照,Expand 按钮是灰色的,必须先进入快照管理器删除或合并所有快照。第二,在 VMware Workstation Pro 17 以及多数较新版本里,虚拟机开机状态下也可以扩容,但我个人习惯强制关机后再做,因为 Windows 和 Linux 同时访问一个 vmdk 文件容易触发缓存不一致。第三,扩容界面里的「Allocate all disk space now」选项和扩容无关,那是置备策略,不要动。
参数说明:容量输入框的单位是 GB,输入的数字是虚拟磁盘总容量,不是新增容量。比如原来 40GB,想加 20GB,应该填 60。另外这里改的只是虚拟磁盘的上限,分区表完全没变,所以进系统后你看到的容量还是老的。
3.2 用 vmware-vdiskmanager 命令行扩容:常用参数和实测经验
如果你有多台虚拟机要批量扩盘,或者你在 Linux 宿主机上跑 VMware Workstation,图形界面反而麻烦,这时候用命令行工具vmware-vdiskmanager更顺手。它在宿主机 VMware 安装目录下,Linux 宿主上通常直接用系统 PATH 里的同名命令。
# 查看 vmware-vdiskmanager 的帮助,确认参数 vmware-vdiskmanager -h # 扩容一个 vmdk 磁盘到 120GB,注意先关闭虚拟机 vmware-vdiskmanager -x 120GB /data/vms/linux01/linux01.vmdk逻辑说明:-x参数就是 expand 的意思,后面直接跟目标大小和 vmdk 路径。这个命令会改写 vmdk 文件的描述头,把虚拟磁盘总容量改成 120GB,但分区和文件系统完全不动。执行时会有进度条,看到 "Successfully expanded the virtual disk" 就成功了。
参数说明:路径里如果只有一个 vmdk 文件,直接指定主文件就行;如果有快照产生了一串子 vmdk,必须先合并快照,否则扩容命令会报错。命令执行期间绝对不能启动虚拟机,否则 vmdk 文件头写入一半,磁盘就废了。Linux 宿主机上执行时要用sudo,Windows 宿主机上要用管理员权限的 CMD。
3.3 扩容后为什么还要重新扫描总线
调大虚拟磁盘后,Linux 内核还记着原来的总容量,这时候直接df -h肯定是老样子,甚至fdisk -l都看不到新空间。我不建议立刻重启来让内核重新识别,因为如果虚拟机在运行,重启前没有做任何系统内分区调整,重启后 grub 可能会因为磁盘元数据不一致进入救援模式。稳妥的做法是重新扫描 SCSI 总线。
# 重新扫描 SCSI 设备,路径按 lsblk 里看到的实际设备来 echo 1 > /sys/class/scsi_device/0:0:0:0/device/rescan # 让内核更新分区表 sudo partprobe /dev/sda逻辑说明:echo 1写到 scsi_device 的 rescan 节点,是让内核重新读取设备容量。路径里的0:0:0:0是 scsi 设备地址,可以用ls /sys/class/scsi_device/查到实际目录名。partprobe的作用是让内核重新读取分区表,不重启就能看到新分区。执行完用lsblk查看,如果/dev/sda的总容量已经变成 120GB,但/dev/sda2还是原来大小,说明系统已经感知到磁盘变大了,接下来要做的是分区扩容。
4. Linux 系统内分区扩容:LVM 的 pvresize 与普通分区的 fdisk 流程
4.1 LVM 扩容:新建分区后加入卷组,再扩展逻辑卷和文件系统
如果你的系统用了 LVM,有两种做法:一种是直接扩展原有 PV 所在的分区,另一种是在磁盘末尾新建一个分区并把新分区加入现有卷组。我一般在生产环境偏好第二种,因为不需要动原分区,风险小很多。扩大虚拟磁盘后,磁盘末尾会有一段未分配空间,用 fdisk 新建一个 LVM 分区。
# 用 fdisk 在空闲区域新建一个分区,例如 /dev/sda3 sudo fdisk /dev/sda # 输入 n 新建分区,分区类型默认 primary,起始扇区直接回车 # 结束扇区输入 +20G 或直接回车占满剩余空间 # 输入 t 把分区类型改成 8e(Linux LVM) # 输入 w 保存退出 # 让内核识别新分区 sudo partprobe /dev/sda # 把新分区初始化为物理卷并加入现有卷组 sudo pvcreate /dev/sda3 sudo vgextend centos /dev/sda3 # 查看卷组空间,VFree 应该已经增加 sudo vgs逻辑说明:fdisk交互模式里,n新建分区后,起始扇区最好用默认值,因为前面不存在冲突;结束扇区可以用+20G指定大小,也可以直接回车把剩余空间全给这个分区。分区类型改成8e是为了让 fdisk 明确这是 LVM 分区,虽然不是必须,但能避免很多误判。pvcreate把/dev/sda3变成物理卷,vgextend把它塞进centos这个卷组。到这一步,卷组里有了新增的可用容量,但逻辑卷还没变。
扩展逻辑卷和文件系统这一步要注意顺序:先扩展逻辑卷,再刷新文件系统。
# 将根逻辑卷扩展到占满卷组所有空闲空间 sudo lvextend -l +100%FREE /dev/centos/root # 查看文件系统类型,决定用哪个命令 df -T / # 如果是 ext4,执行: sudo resize2fs /dev/centos/root # 如果是 xfs,执行: sudo xfs_growfs /逻辑说明:lvextend -l +100%FREE表示把卷组剩下的空间全部加到根逻辑卷上。你也可以用-L +20G指定增加 20GB。resize2fs和xfs_growfs都是无损扩容文件系统的命令,但前者传设备路径,后者传挂载点。xfs 文件系统不需要卸载,但不能指定设备路径,如果写错会报 "not a mounted XFS filesystem"。ext4 如果有挂载也能扩,但resize2fs在挂载状态下也可以工作,只是我在有条件时还是先卸载再扩,减少在线操作的不确定性。
4.2 非 LVM 分区:用 fdisk 删除重建分区保留数据的步骤与风险
如果这台 Linux 没有 LVM,根分区/dev/sda1直接挂载/,那扩容必须修改分区本身,而不是新建分区。最常见的手法是 fdisk 删除原分区再重建,起始扇区保持不变,结束扇区用满。这个操作风险极高,每一步都要非常小心。
# 进入 fdisk 交互 sudo fdisk /dev/sda # 输入 p 打印分区表,记下 /dev/sda1 的 Start 扇区号 # 输入 d 删除分区 1 # 输入 n 新建分区,分区编号 1 # First sector 提示时,直接回车使用默认值(默认通常就是原起始扇区) # Last sector 提示时,直接回车占满整个磁盘 # 输入 w 保存退出 # 更新分区表 sudo partprobe /dev/sda # 检查文件系统完整性(非常重要) sudo e2fsck -f /dev/sda1 # 如果是 ext4,执行: sudo resize2fs /dev/sda1 # 如果是 xfs,需要先挂载再执行: sudo mount /dev/sda1 /mnt sudo xfs_growfs /mnt逻辑说明:删除分区再重建,关键点是起始扇区必须和原来一模一样,否则文件系统读到的超级块位置偏移,数据直接消失。所以进入 fdisk 后第一件事用p打印分区表,把 Start 扇区抄下来。删除后重建时,fdisk 通常会提示默认扇区,那个默认值一般就是原起始扇区,直接回车即可。如果不确定,先输入p对比,不要直接w。e2fsck -f是在扩容前强制检查文件系统完整性,ext4 只要有一点脏位,resize2fs都会拒绝执行。
为防万一,这里强烈建议先在宿主机上做一次虚拟磁盘快照,或者至少备份分区表头部。Linux 下可以用dd把磁盘前 64MB 备份出来,这是后悔药。
# 备份磁盘头部,包含 MBR、分区表和文件系统引导块 sudo dd if=/dev/sda of=/root/sda_mbr_backup.img bs=512 count=131072逻辑说明:bs=512是扇区大小,count=131072表示 131072 个扇区,正好 64MB。这一步能把 MBR、GPT 分区表、文件系统超级块和引导信息都包含进去。真出问题时,用dd if=/root/sda_mbr_backup.img of=/dev/sda bs=512 count=131072可以恢复,虽然不能救全部数据,但至少能让分区表回到扩容前状态。
4.3 文件系统类型决定最后的扩容命令:xfs 与 ext4 的区别
同一套扩容流程,最后一步的命令完全取决于文件系统类型。在这个题目下,最常见的两个文件系统就是 ext4 和 xfs。可以用df -T /一次性确认。
| 文件系统 | 扩容命令 | 参数是设备还是挂载点 | 是否支持在线扩容 | 是否支持缩小 |
|---|---|---|---|---|
| ext4 | resize2fs /dev/xxx | 设备路径 | 支持 | 支持,但极不推荐 |
| xfs | xfs_growfs / | 挂载点 | 支持,但必须挂载 | 不支持,永远只能扩大 |
| btrfs | btrfs filesystem resize | 挂载点 | 支持 | 支持,但需要额外步骤 |
注意,CentOS 7 和 RHEL 7 之后默认根文件系统是 xfs,Ubuntu 默认是 ext4。很多人在网上复制了resize2fs /dev/centos/root,结果自己的系统是 xfs,报错后就以为没扩容成功。实际命令用反了。遇到这种情况,先执行df -T /看类型再决定。
另外,如果你在 4.1 节用的是lvextend -r参数,这个-r会自动调用合适的扩容命令,相当于帮你规避了文件系统类型判断。但我不建议新手完全依赖它,因为线上系统可能挂着其他逻辑卷,自动扩容的策略不一定符合你的预期,手动确认容错率更高。
5. 避坑指南:扩容后启动不了、数据丢失、识别不到新空间的 5 个真实案例
5.1 现象:扩容后虚拟机无法启动,报 "not found" 错误
现象描述:在 VMware Workstation 里把虚拟磁盘从 40GB 调到 80GB,重启 Linux 虚拟机,结果停在 grub 命令行或进入 dracut rescue,屏幕上出现root device not found或者UUID=xxxx does not exist。
原因分析:最常见的场景是扩容操作发生在虚拟机开机状态下,而且没有重新扫描 SCSI 总线。虚拟磁盘文件头被改动,但系统内的分区缓存还是旧的,grub 在引导时读不到正确的根分区 UUID。另外,如果你在扩容过程中把虚拟磁盘的接口类型从 IDE 改成 SCSI,或者调整了磁盘顺序,也会触发同样的症状。
解决方案:先不要盲目重装系统。关机后在 VMware Workstation 里进入虚拟机 BIOS(开机时按 F2),确认启动顺序里选中的是原来的硬盘。如果仍无法进系统,用安装镜像引导,进入救援模式,直接执行grub-install /dev/sda重建引导,再重启。我遇到过多次的情况是,救援模式里把根文件系统挂载到/mnt/sysimage后,发现分区还在,数据也没丢,就是引导器丢了,重建后就好了。记住,扩容前先关闭虚拟机、扩容后先partprobe再重启,能避开九成这种问题。
5.2 现象:df 看不到新容量,但 lsblk 能看到
现象描述:扩容完成后,lsblk已经显示/dev/sda总容量从 40GB 变成了 80GB,可是df -h里根分区还是 40GB,挂载点没有任何变化。
原因分析:这是必然的,因为lsblk看到的是块设备总大小,而df看到的是文件系统实际占用的逻辑空间。虚拟磁盘容量调大以后,块设备上限变了,但分区表和文件系统都没有动,新增的空间还是一块「蛋糕上的奶油」,没有被划分到任何分区里。很多新手在这里停下来,以为 VMware 扩容坏了。
解决方案:回到第 4 章,按系统是否 LVM 执行分区扩容。如果是 LVM,pvresize或者新建分区vgextend之后,df才会逐渐变大。如果分区是普通分区,执行 fdisk 删除重建后再resize2fs。记住,检查规律是:先lsblk确认块设备,再pvs确认物理卷,再vgs确认卷组,最后df确认文件系统,一层层排查。
5.3 现象:扩容导致分区表损坏,数据全丢
现象描述:在 fdisk 里删除分区 1 并重新创建后,重启系统提示No bootable device,用fdisk -l看到的分区大小不对,甚至整个磁盘变成空盘。
原因分析:大概率是删除分区后重建时,起始扇区没有用原来的值,而是用了 fdisk 默认提出的新扇区。比如原分区起始扇区是 2048,但你在重建时输入了 4096,分区表指向的位置就和原来文件系统超级块的位置错位,等于所有数据在第一扇区层面就「搬了家」。另一个原因是分区表写入过程中虚拟机崩溃,GPT 的备份头损坏。
解决方案:如果之前备份过磁盘头部,直接用dd恢复。没有备份的话,不要继续写任何数据,立刻把虚拟磁盘只读挂载到另一台 Linux,尝试用testdisk分析分区表和超级块。我见过一个案例,testdisk扫描后成功恢复了扩展分区,但因为中间执行过mkfs,数据覆盖了一部分,最后只找回一半。所以这条踩坑的教训就一句话:分区操作前,先备份磁盘头,或者做虚拟机快照。
5.4 现象:快照导致扩容失败或空间不变
现象描述:在 VMware Workstation 界面里,Expand 按钮是灰色,无法点击。或者命令行扩容后提示snapshot exists,处理完快照再扩容,进系统后容量还是不变。
原因分析:虚拟机存在快照时,虚拟磁盘文件被拆分成基础 vmdk 和多个-snapshot1.vmdk子文件。扩容工具无法安全处理这个快照链,所以要么锁定按钮,要么扩容命令直接拒绝执行。就算强行走完命令,由于快照里的分区表描述还是旧版本,系统读到的容量依然不对。
解决方案:打开 VMware Workstation 的快照管理器,把所有快照合并或删除。合并快照是一个写操作,需要宿主机至少预留当前虚拟磁盘文件大小的空闲空间。合并完成后,重新检查 vmdk 是否只剩一个文件,再执行扩容。行业内的一般做法是,扩容前先关闭虚拟机,合并所有快照,然后做一次全新快照,这个全新快照在扩容完成后立即删除,确保磁盘描述始终保持最新。这步操作虽然费时间,但能避免无头悬案。
5.5 现象:xfs 文件系统扩容报错 "not a mounted XFS filesystem"
现象描述:扩容逻辑卷完成后,执行xfs_growfs /dev/centos/root,系统返回xfs_growfs: /dev/centos/root is not a mounted XFS filesystem。
原因分析:xfs_growfs命令的参数要求是挂载点路径,而不是设备文件路径,这一点和 ext4 的resize2fs正好相反。很多从旧习惯了转过来的工程师会在这里翻车。另外,如果你传入的路径是/dev/centos/root,内核只会去解释设备名,不会去找挂载关系。
解决方案:先执行findmnt /确认根文件系统挂载点,或直接执行df -h | grep /$查看。然后使用sudo xfs_growfs /,注意斜杠就是挂载点。如果根分区挂载在/mnt或者别的地方,就传那个挂载点。另外,xfs 扩容前不需要卸载,所以不用慌,它支持在线扩容。即便如此,仍建议在执行扩容前把mount输出保存下来,确认没有多挂载点混淆的问题。
6. 扩容后的验证与习惯:把一次扩容变成可复用的操作模板
扩容完成后,不要急着关机或者交给业务,先把验证做透。执行下面这组命令,并把输出保存到文件,方便后续排查问题。
# 查看当前文件系统容量 df -h # 查看块设备分区 lsblk # 查看 LVM 物理卷、卷组、逻辑卷状态 sudo pvs && sudo vgs && sudo lvs逻辑说明:df -h确认根分区已经变成新容量,lsblk确认块设备总容量和分区大小匹配,pvs/vgs/lvs确认物理卷和逻辑卷的分配没有异常。如果扩容后这些命令输出和预期一致,再启动业务应用也不迟。
我这边长期养成的习惯是,每一次扩容都做一个简单的变更记录文件,里面存扩盘前df -h和lsblk的输出、VMware 层调整前后的磁盘大小、系统内执行过的命令序列、最后验证结果。这个文件不用特别正式,一个文本文件就够,但下次遇到类似问题时,翻出来比对就非常快。
还有一个细节:如果虚拟机是 xfs 根分区,扩容后顺手执行xfs_info /确认data块数已经更新。如果是 ext4,用tune2fs -l /dev/xxx | grep Block count检查。这些指标比df -h更底层,能发现df显示的虚高或偏差。
说一个我自己的翻车经历吧。早几年给一台 CentOS 7 虚拟机扩根分区,没有做快照,直接在 fdisk 里删除了重建分区,手滑把起始扇区从 2048 输成了 2056。重启后文件系统直接变成 raw,最后靠 diskgenius 分区恢复软件在 Windows 宿主机上扫描虚拟磁盘才救回大半数据。从那以后,我给自己定了条铁规矩:所有涉及分区表修改的操作,必须先备份磁盘头部 64MB,或者做一次虚拟机快照,二选其一,没有后悔药之前不动手。希望帮到你。
本文还有配套的精品资源,点击获取