VMware 虚拟机磁盘扩容实战文档(Ubuntu 22.04 + LVM)

17 阅读5分钟

VMware 虚拟机磁盘扩容实战文档(Ubuntu 22.04 + LVM)

日期:2026-11-06
机器:taoserver(192.168.179.128,VMware NAT,Ubuntu 22.04 x86_64)
场景:Docker 构建/运行导致根分区 94% 满,需要在线扩容


一、任务背景

taoserver 上跑着 Docker(mysql8、portainer、jenkins),/var/lib/docker 与系统同盘。
根分区只剩 614MB(94% 已用),后续要构建 PHP 应用镜像(需 2~3GB 临时空间),必须扩容。

扩容目标:40G 硬盘 → 根分区用满,可用空间 ≥ 28G。

二、原理:为什么"扩了硬盘磁盘却没变大"

VMware 虚拟机的磁盘是一条三层结构,扩容必须逐层打通,缺一层都白做:

第 1 层  VMware 虚拟硬盘        (在 VMware 设置里扩,或开机状态下在线扩)
   ↓
第 2 层  分区 sda3              (要在系统里扩分区)
   ↓
第 3 层  LVM 逻辑卷 + 文件系统   (要 pvresize → lvextend → resize2fs)

本机初始状态(典型的「只做了第 1 层」):

层初始扩容后
sda 硬盘40G40G(不变)
sda3 分区18.2G38.2G
PV / VG 空闲18.2G / 8.22G 空闲38.2G / 0
LV(ubuntu-lv)10G38.2G
/ 文件系统9.8G(94% 用)38G(25% 用,剩 28G)

LVM 的价值就体现在这里:分区/LV 可以在线扩大,不用重启、不用停业务。
(反过来缩小则危险得多,LVM 不支持在线缩 ext4。)

三、扩容前体检命令(判断卡在哪一层)

lsblk                  # 看磁盘→分区→LV 的层级和大小
df -h /                # 看文件系统实际大小
pvs / vgs / lvs        # 看 LVM 三层:物理卷/卷组/逻辑卷
fdisk -l /dev/sda      # 看硬盘总量

判断口诀:

  • lsblk 里 sda 是 40G、sda3 还是小 → 分区没扩(本次情况)
  • sda3 扩了但 vgs 有 VFree → LV 没扩
  • lvs 扩了但 df -h 没变 → 文件系统没扩(漏了 resize2fs)

四、实施步骤(全程在线,不停机不停容器)

第 1 步:VMware 层扩硬盘

虚拟机设置 → 硬盘 → 扩展(或 vmware-vdiskmanager)。开机状态也支持在线扩。
本次用户已在 VMware 里扩到 40G。

第 2 步:扩分区(sda3 是最后一个分区才安全)

parted -s /dev/sda resizepart 3 100%
  • -s 非交互模式;100% 表示分区吃到磁盘末尾;
  • 前提:sda3 必须是该磁盘最后一个分区(本机 sda1/sda2 在前,满足);
  • 实际输出:PART_OK(无报错即成功)。

若系统没有 parted,可用 growpart /dev/sda 3(cloud-guest-utils 包,云镜像自带)。

第 3 步:刷新物理卷

pvresize /dev/sda3

实际输出:

Physical volume "/dev/sda3" changed
1 physical volume(s) resized or updated / 0 physical volume(s) not resized

第 4 步:扩展逻辑卷(吃掉 VG 全部空闲)

lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv

实际输出:

Size of logical volume ubuntu-vg/ubuntu-lv changed from 10.00 GiB (2560 extents) to 38.22 GiB (9785 extents).
Logical volume ubuntu-vg/ubuntu-lv successfully resized.

常用写法:lvextend -L +20G ...(加 20G)或 -l +100%FREE(加全部空闲,本次用)。

第 5 步:在线扩展文件系统(ext4)

resize2fs /dev/ubuntu-vg/ubuntu-lv

实际输出:

Filesystem at /dev/ubuntu-vg/ubuntu-lv is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 5
The filesystem on /dev/ubuntu-vg/ubuntu-lv is now 10019840 (4k) blocks long.

on-line resizing required = 在线扩展,挂载状态下直接生效,无需重启。

五、验证

df -h /
lsblk /dev/sda
vgs

最终结果:

Filesystem                         Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv   38G  8.7G   28G  25% /

sda                    40G
└─sda3                 38.2G
  └─ubuntu--vg-ubuntu--lv  38.2G

VG        VSize   VFree
ubuntu-vg 38.22g  0

业务验证:mysql8 / portainer 容器全程未受影响(docker ps 状态不变)。

六、命令速查表

命令作用关键点
lsblk树状看块设备层级判断卡在哪一层的第一工具
parted -s /dev/sda resizepart N 100%扩分区到磁盘末尾仅限最后一个分区;-s 免交互
growpart /dev/sda N同上(cloud 工具)云镜像常用
pvresize /dev/sda3PV 认领分区新空间必须在 lvextend 之前
lvextend -l +100%FREE /dev/vg/lvLV 吃掉 VG 全部空闲-L +20G 按容量加
resize2fs /dev/vg/lv在线扩 ext4 文件系统挂载状态可执行;最后一步,漏了 df 不变
xfs_growfs /若是 xfs 用这条(不是 resize2fs)Ubuntu 默认 ext4,RHEL/CentOS 默认 xfs
vgs / pvs / lvsLVM 三层状态VFree=0 说明 VG 空间用尽

七、踩坑与注意

  1. 只扩 VMware 硬盘不够——三层结构,少扩一层 df 都不会变。最常见就是只做第 1 层。
  2. parted resizepart 只能扩最后一个分区——如果 sda3 后面还有分区,方案完全不同(需删分区重建或加新盘)。
  3. 文件系统类型决定最后一步命令——df -T / 看类型:ext4 用 resize2fs,xfs 用 xfs_growfs /(参数是挂载点不是设备名)。
  4. LVM 缩容不支持在线——扩容随意,缩容要卸载+离线,规划时尽量一步到位。
  5. 引导分区 sda2(/boot)不在 LVM 里——扩根分区不影响 /boot,别动 sda2。
  6. 操作前 mysql 等容器无需停止——全部操作在线,但属于磁盘级变更,仍建议避开业务高峰。

八、SOP 模板(下次直接照抄)

# 前提:VMware 层已扩容,目标分区是磁盘最后一个分区
lsblk && df -T /                          # 体检:确认层级与文件系统类型
parted -s /dev/sda resizepart <N> 100%    # 1. 扩分区
pvresize /dev/sda<N>                      # 2. 刷 PV
lvextend -l +100%FREE /dev/<vg>/<lv>      # 3. 扩 LV
resize2fs /dev/<vg>/<lv>                  # 4. 扩文件系统(ext4)
df -h /                                   # 5. 验证

九、FAQ

Q1:扩容后 df -h 没变化?
九成是漏了第 5 步 resize2fs(LV 扩了文件系统没扩)。lvs 看大小对不对,再看 df -T 确认文件系统类型。

Q2:VMware 里"扩展"按钮是灰的?
说明虚拟机有快照。先删掉所有快照再扩(快照链会锁定磁盘)。

Q3:不想动系统盘,能不能加一块新盘给 Docker?
可以,而且更干净:加盘 → 整盘做 PV → 建 VG/LV → 格式化挂到 /data → 改 Docker 的 data-root 指过去。适合后续还要持续膨胀的场景。

Q4:resize2fs 中途断了会不会坏数据?
不会。在线 resize 是原子的元数据操作,中断则自动回退到原大小,不会损坏已写入数据。


本次扩容:10G → 38.2G,在线完成,全程约 1 分钟,业务无感知。