我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

VMware中Ubuntu LVM根分区扩容实战:从虚拟磁盘到文件系统

VMware中Ubuntu LVM根分区扩容实战:从虚拟磁盘到文件系统 1. 场景拆解与扩容前的必读认知先说个我在群里被问过无数次的问题虚机磁盘在VMware里明明已经从100G调成了200G进Ubuntu执行df -h一看根分区还是100G剩下那100G凭空蒸发。大部分人的第一反应是重启系统或者怀疑VMware版本有问题其实都不是——问题出在你根本没把新空间“接”到系统里来。这个“接”的过程在传统分区方案下叫扩容分区在LVM方案下则是一套完整的PV、VG、LV操作链。而这篇文章要讲的正是后者当你的Ubuntu系统使用了LVM逻辑卷管理且虚拟磁盘空间不足时如何在VMware虚拟机环境下安全地扩展根分区容量。先说清楚这套操作适合谁用VMware Workstation或vSphere管理Ubuntu虚机、对LVM概念有一知半解但没完整操作过、刚装完系统发现磁盘规划太小想补救的运维和开发同学。不适合纯新手从零开始学LVM概念但如果你愿意边看边查也完全能跟着操作完成。关于LVM的优缺点我直接用一句话总结LVM最大的价值就是“动态调整不用重装系统”而最大的代价是你必须理解PV/VG/LV三层结构否则出了问题容易一头雾水。网上总有人争论LVM到底好不好我的观点很明确——在虚拟机环境里LVM几乎就是默认答案因为虚拟磁盘本身就是一层抽象再套一层LVM抽象灵活性远大于那点性能损耗。扩展容量这件事本质上分两步第一步是在VMware层把磁盘空间给够第二步是在Ubuntu系统内把空间从物理磁盘一路分配到文件系统。这两步缺一不可而且顺序不能反。很多人只做了第一步就觉得“已经扩容了”其实连入口都没找到。本文的场景设定为你的Ubuntu安装在单个虚拟磁盘上根分区用了LVM现在空间告急需要原地扩容。完整流程我将从VMware磁盘操作、系统内分区处理、LVM逻辑卷扩展、文件系统扩展四个层面依次展开每一步都会说明原理、操作命令和常见翻车点。2. 扩容前的状态确认与准备工作2.1 确认你的系统确实用了LVM动手之前先花三十秒确认一下系统到底是不是LVM管理。很多人在网上找了半天的命令一顿操作最后发现自己的系统压根没用LVM白白浪费时间。执行下面的命令查看块设备结构和挂载关系lsblk输出大概率会长这样NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 100G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 99G 0 part └─ubuntu--vg-ubuntu--lv 253:0 0 98G 0 lvm /看到sda2下面挂着ubuntu--vg-ubuntu--lv这种名字且TYPE列显示为lvm就说明你的根文件系统确实跑在LVM上。再用LVM自己的命令确认一下sudo pvs sudo vgs sudo lvs这三个命令分别查看物理卷、卷组、逻辑卷的当前状态。正常情况你会看到卷组名一般是ubuntu-vg逻辑卷名一般是ubuntu-lv不同版本可能略有差异。这里多提一句Ubuntu从18.04开始桌面版和服务器版的默认安装选项在自动分区时几乎都会采用LVM方案除非你在安装时手动选择了“整个磁盘”并且人为改成了传统分区。2.2 扩容前的必要检查与备份LVM扩展虽然支持在线操作但在动磁盘之前该做的检查一样不能少。第一件事看磁盘当前分区表和文件系统状态。sudo fdisk -l df -hTfdisk -l看的是物理磁盘的分区分布df -hT看的是文件系统实际挂载情况和格式类型。重点确认根分区文件系统是什么——如果是ext4后面用resize2fs扩展如果是xfs就得用xfs_growfs。这两个命令不能混用混用必报错。第二件事确认是否有重要数据并评估风险。理论上说LVM扩展操作比缩小操作安全得多——缩小需要移动数据块中断风险大而扩展基本是追加空间不太容易搞坏文件系统。但“不太容易”不等于“不会”特别是当你对分区表进行操作时一个误操作就可能把分区表写坏。所以有条件的建议先给虚拟机做快照。注意VMware Workstation的“快照”功能在虚机关机状态下做最安全。如果你做的是数据库服务器这类生产环境建议优先选择业务低峰期操作并且在操作前确认数据库有近期备份。第三件事记录当前状态。把pvs、vgs、lvs和df -hT的输出保存到文本里万一操作中出了岔子你可以清楚地知道原来长什么样方便倒推恢复。2.3 VMware层操作方式选择在VMware里给虚拟机增加磁盘空间有两条路一是直接扩展现有虚拟磁盘的大小二是新增一块虚拟磁盘挂载上去。两种方式在系统层面对应的操作路径完全不同直接扩展现有磁盘比如把sda从100G改成200G系统里还是只有一块物理磁盘sda但它的尾部多出了未分配空间。你需要在这个磁盘上新建分区或扩展已有分区再把新空间加入LVM。新增一块虚拟磁盘比如加了100G的新盘系统里出现sdb系统里出现了全新的物理磁盘你需要在它上面创建PV然后把它加入已有VG再扩展LV。两种方式都能达到扩展LV的目的但操作流程和风险点不同。我个人的建议是如果条件允许优先选择直接扩展现有磁盘因为这样系统里的磁盘拓扑不会变化后续操作路径更短。但如果原磁盘的剩余扩展空间有限比如你用的是精简置备但宿主物理磁盘快满了那新增一块独立虚拟磁盘对宿主的存储压力反而更小。不过两种方式在VMware层有一个共同原则务必在虚拟机处于关机状态时执行磁盘调整。虽然VMware Workstation也支持开机状态下的“热添加”磁盘但系统内对SCSI设备的重新扫描有时不可靠为了整体操作稳定我宁愿多花一分钟关机。3. VMware层磁盘扩展操作详解3.1 直接扩展虚拟磁盘在VMware Workstation中右键虚拟机 → 设置 → 硬盘 → 工具条上的“扩展”然后输入你想要的总容量。比如原来是100G想扩到200G直接输入200。关键点在于输入的是磁盘总大小而不是增加多少。假设你输错了写成300虚机里的磁盘就会直接显示成300G但分区表和文件系统都还不知道这件事——这就是为什么系统里df -h看不到任何变化的原因。在vSphere Web Client里操作类似编辑虚拟机 → 硬盘 → 重新配置 → 修改容量。什么情况下不能直接扩展如果你的虚拟磁盘是“独立持久”模式并且该磁盘打过分隔符或做过RAW设备映射在vSphere里可能无法在线扩展只能关机操作。Workstation环境则几乎不会遇到这个问题。扩容完成后启动虚拟机进入系统后先重新扫描磁盘让内核识别新的磁盘容量sudo partprobe sudo fdisk -l正常情况下fdisk -l会显示磁盘总容量已经变成新的大小但分区表的最后一个分区通常是sda2的结束位置并没有变化磁盘尾部多出了一段空白空间。3.2 新增虚拟磁盘方式如果你选择了新增磁盘的路子操作也简单虚拟机设置 → 添加 → 硬盘 → 选择SCSI → 指定大小 → 完成。这里有个小坑新添加的磁盘在系统里的设备名不一定是sdb取决于你的虚拟控制器。比如你原来的系统盘挂在SCSI 0:0上新盘如果接在SCSI 0:1上通常是sdb但如果原来的盘在0:7新盘却自动分配到了0:0那系统里的设备名排序可能会颠倒。所以系统起来后务必先lsblk看清楚哪个盘是新的别认错盘更不要把PV建到了系统盘上。在系统里确认新磁盘出现的方法lsblk sudo fdisk -l新磁盘大概率显示为/dev/sdb整块盘没有任何分区大小对应你刚才添加的大小。有人说不分区直接建PV不行吗技术上可以pvcreate /dev/sdb直接用整块盘也能建PV。但我从来不推荐这么干原因后面在系统内操作部分会详细说——简单说就是分区以后万一磁盘需要换机迁移或者做其他后续操作分区表的存在会让你更灵活。4. 系统内的LVM扩展完整流程推荐路径接下来是本文最核心的部分。我先按直接扩展现有虚拟磁盘这条路径来走这是最常用也最省事的方案。新增磁盘的方式我会在最后的补充小节里说明差异。4.1 重新扫描磁盘并确认新空间进入系统后第一件事是让内核重新读取磁盘容量sudo partprobe lsblk如果你是在关机和开机之间完成的扩容系统启动时内核会自动识别新容量其实不一定需要partprobe。但如果你使用了热添加虚拟机开机状态扩展了磁盘那partprobe就非常关键了——它能让内核刷新分区表而不需要重启。确认磁盘容量已被识别后你会看到类似这样的lsblk输出sda 8:0 0 200G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 99G 0 part └─ubuntu--vg-ubuntu--lv 253:0 0 98G 0 lvm /注意sda的总容量变成了200G但sda2分区仍然是99G后面多出来的约101G是未分配的空白区域。4.2 扩展分区表到这一步有两种做法一种是新建一个分区sda3来容纳新空间另一种是直接扩展sda2分区让sda2吃掉所有剩余空间。我的建议一定要新建分区不要扩展已有分区。原因有三第一sda2是LVM的PV所在分区它不要求连续的磁盘空间只要PV底层是完整的分区或者磁盘、能被LVM正常管理就行第二直接扩展sda2意味着要重写分区表并移动分区的结束位置一旦中途断电或操作失误分区表损坏的概率远大于新建分区第三新建分区不会影响已有分区里的任何数据心理压力和实操风险都小得多。用fdisk来新建分区sudo fdisk /dev/sda进入fdisk交互界面后依次执行p # 查看当前分区表确认sda2的结束扇区位置 n # 新建分区 # 分区类型选primary主分区 # 分区编号默认3即sda3 # First sector直接回车使用默认值紧跟现有分区之后 # Last sector直接回车使用默认值使用磁盘最末尾 t # 修改分区类型 # 选择分区3 # 输入 8e → Linux LVM类型 p # 再次查看分区表确认无误 w # 写入分区表并退出关于分区类型代码再啰嗦一句8e是Linux LVM的分区类型代码。如果不设置这个分区也能正常使用但fdisk -l看到的类型会是Linux或空白某些工具和后续管理识别会出现困惑。养成好习惯加了就完了几秒钟的事。分区完成后刷新分区表sudo partprobe lsblk此时你应该看到/dev/sda3出现了大小约等于扩展后磁盘剩余的空间。4.3 创建PV并加入VG新分区创建好后把它变成LVM的物理卷sudo pvcreate /dev/sda3执行后可以用pvs确认新PV是否创建成功sudo pvs输出应该类似PV VG Fmt Attr PSize PFree /dev/sda2 ubuntu-vg lvm2 a-- 99.00g 0 /dev/sda3 lvm2 --- 101.00g 101.00g可以看到/dev/sda3还没有加入任何卷组它的VG列是空的。接下来把新PV加入现有的卷组sudo vgextend ubuntu-vg /dev/sda3这里需要注意卷组名要跟你vgs看到的一致绝大多数的Ubuntu默认卷组名是ubuntu-vg但如果你装系统时自定义过主机名卷组名会跟着主机名走比如主机名叫myserver卷组名可能就变成了myserver-vg。用vgs看一眼再下手永远比赌记忆稳妥。扩展成功后vgs会显示卷组的总大小增加了但PV那一栏会多出一行/dev/sda3。4.4 扩展逻辑卷与文件系统卷组空间够了现在把逻辑卷ubuntu-lv在卷组内占用的空间加大sudo lvextend -l 100%FREE /dev/ubuntu-vg/ubuntu-lv这个命令的意思是把卷组里所有剩余空闲空间都分配给这个LV-l 100%FREE这种写法比直接指定容量大小更实用——你不需要提前算好要加多少G直接一把梭把剩余空间全给过去。扩展完成后用lvs确认一下LV大小已经变化sudo lvs接下来是最后一步扩展文件系统。如果文件系统是ext4大多数Ubuntu默认sudo resize2fs /dev/ubuntu-vg/ubuntu-lv如果文件系统是xfs部分自定义安装场景sudo xfs_growfs /关键在于resize2fs和xfs_growfs不能互换。resize2fs针对ext系列文件系统既可以扩大也可以缩小xfs_growfs只会扩大xfs文件系统而且挂载点就是它的参数。执行完文件系统扩展后用df -hT验证df -hT此时根分区的容量应该已经变成新的扩容后的大小可用空间也相应增加。整个过程无需重启。4.5 新增磁盘方式下的差异化操作如果你走的是新增虚拟磁盘那条路在系统里的操作会稍有不同但核心逻辑完全一致lsblk # 确认新磁盘设备名假设是sdb sudo fdisk /dev/sdb # 新建一个主分区类型设为8e sudo partprobe sudo pvcreate /dev/sdb1 # 在分区上创建PV sudo vgextend ubuntu-vg /dev/sdb1 # 把新PV加入卷组 sudo lvextend -l 100%FREE /dev/ubuntu-vg/ubuntu-lv sudo resize2fs /dev/ubuntu-vg/ubuntu-lv # 或 xfs_growfs /你可能会问为什么新增磁盘时也要先分区不在整块盘上直接建PV前面提过原因这里展开说。pvcreate /dev/sdb技术上完全可行LVM不管你是分区还是整块盘。但问题在于如果你以后想把这块盘从LVM里移除或者整机迁移到别的环境有分区表的话你可以把sdb1的PV移走之后再直接删分区让这块盘恢复成普通磁盘被其他系统使用。而没有分区表的整块盘PV想“还原”成一块普通磁盘就得用pvremove再重新格式化风险更大。这个操作其实不花几分钟但能省掉后续很多麻烦建议养成习惯。5. 实操中的典型故障与排查技巧5.1 扩容后df -h无变化这是最常见的翻车现场。操作流程从头到尾走完了lvs显示LV已经变大df -h却纹丝不动。原因十有八九是文件系统没有扩容。lvextend只扩大了逻辑卷的容量文件系统还停留在原来的大小。很多教程写到lvextend就结束了导致大量读者卡在这一步。解决方式就是执行上面提到的文件系统扩展命令。另外注意执行resize2fs之前确认LV已经是新的大小否则会提示无空间可扩展。另一个不太常见但确实存在的原因你把resize2fs跑错了设备。比如你的根分区在/dev/ubuntu-vg/ubuntu-lv但你却对/dev/sda2执行了resize2fs当然不会生效。文件系统扩展对象是LV设备节点不是底层物理分区。5.2 fdisk操作时提示分区表繁忙在执行partprobe或重启后fdisk有时会提示类似“磁盘正忙”或“内核仍然使用旧分区表”的错误。通常发生场景你对正在使用的磁盘比如挂载了根分区的sda执行了fdisk修改写完分区表后partprobe没能立即刷新。处理办法先确认没有其他进程在占用这个分区比如用lsof /dev/sda*查一下。如果确实没有进程占用但还是刷新不了最简单的做法是重启虚拟机——你是在VMware环境里重启也就几十秒的事没必要在这上面耗时间。提醒如果重启前你已经在fdisk里写了分区表重启后lsblk一定能看到新分区sda3这一步不需要担心。5.3 误操作扩展了某个不相关的LV有些系统上除了根LV之外还可能有swap的LV或者你之前手动创建过其他LV。执行lvextend时一定要明确指定LV名称。我就见过有人把lvextend -l 100%FREE执行到了swap LV上——虽然没啥严重后果但你卷组的全部空闲空间都被swap吃掉了根分区还是100G等于白操作了一遍。解决方式也不难如果已经扩到swap上了先lvreduce把swap的LV恢复原大小然后再给根LV扩展。但请注意lvreduce是有数据风险的操作务必先确认swap LV上没有重要的文件系统数据swap的pv/fs信息很明确一般不会有数据否则不要贸然缩小。如果对自己操作没把握宁愿重启回滚快照也别冒险。5.4 在线扩容后的性能波动LVM在线扩容本身不会导致明显性能下降但如果你在系统IO繁忙时比如数据库正在批量写入执行了resize2fs文件系统元数据的更新可能会导致短时间的IO卡顿。所以我的建议是尽量在业务低峰期操作并在扩容前用sync命令强制把缓存写入磁盘。另外如果虚拟机用的是精简置备磁盘VMware层扩容后宿主物理磁盘的可用空间可能并不充裕。LVM层面看到的是虚拟磁盘规格变大了但实际IO落到宿主时如果宿主物理存储满了虚拟机可能会直接卡死。建议扩容前先看一眼宿主的存储空间别把虚机空间加得比宿主的实际剩余空间还大。5.5 根分区几乎占满时的扩容注意事项如果你是在磁盘只剩几个G可用空间的情况下进行扩容流程并没有区别但有一个细节要提醒执行resize2fs时文件系统需要临时分配一些元数据空间。如果根分区已经爆满resize2fs可能因为连临时空间都腾不出来而报错。这种极端情况下建议先清理一些不必要的缓存文件腾出5%~10%的余量再操作。虽然LVM扩展大部分情况下不受影响但在极端环境里多留点余量总归是稳妥的。5.6 扩容后虚拟机无法启动的紧急恢复这种情况比较少见但一旦遇到心里要有个底。可能原因包括分区表写入过程中虚拟机异常断电、partprobe刷新后内核状态异常、fdisk里误删了已有分区等。应急思路如下用Ubuntu安装ISO启动进入Live环境试用Ubuntu挂载根文件系统检查数据是否完好用vgs、lvs确认LVM状态是否正常如果只是分区表的问题用fdisk重新补上遗漏的分区分区起始扇区可以从分区表备份或testdisk恢复如果数据盘没坏但系统起不来重点查/etc/fstab里挂载配置是否有问题。本质上的核心教训分区表和LVM元数据的风险通常只在最坏情况下暴露。平时多用pvdisplay、vgdisplay这些命令熟悉你系统的元数据布局关键时刻能救你一命。6. 扩展后的验证及日常维护建议6.1 完整验证清单扩容完成后建议按以下清单逐项验证别只看df -h一个输出就完事df -hT根分区大小和可用空间是否符合预期lsblk分区结构和LVM层级关系是否正常pvs所有PV状态是否为a--activevgsVG大小是否符合预期剩余空间是否为0如果你把全部空间都分配给了根LVlvsLV大小正确状态为-a-activemount | grep / 根分区挂载正常无报错。另外建议在扩容后重启一次虚拟机确认重启后LVM能正常激活、挂载文件系统检查无误。这次重启不是必须的但对于重要虚拟机来说早发现早处理比日后哪天突然重启才发现起不来要好得多。6.2 磁盘监控建议容量扩展是一次性操作但运维是长期的事。建议在Ubuntu上做基础的磁盘监控避免再次出现“空间耗尽后才反应过来”的情况。最简单的方式就是cron加脚本定期统计使用率超过阈值就发通知。这里给一个精简版示例把下面内容保存为/usr/local/bin/disk_check.sh#!/bin/bash THRESHOLD80 USAGE$(df -h / | awk NR2 {print $5} | sed s/%//) if [ $USAGE -gt $THRESHOLD ]; then echo $(date): Root partition usage ${USAGE}% exceeds ${THRESHOLD}% /var/log/disk_alert.log fi加了执行权限后在crontab里每半小时跑一次*/30 * * * * /usr/local/bin/disk_check.sh这个脚本非常简陋但够用。你完全可以根据自己的环境扩展成邮件提醒或者接入告警平台。核心目的不是告警本身而是让你对磁盘增长趋势心里有数哪天看到告警就知道该扩容或清理了。6.3 后续扩展方向的思考如果你做的是一次性扩容到这里就能收工了。但从长远看我建议想清楚这样几个问题第一这次扩容后你的卷组内是否还有剩余空间如果还有那下次扩展就只需要lvextend加resize2fs两步连分区都不用碰。这也是初始规划时不要把所有空间全部分配给LV的原因——留一点弹性在VG里等于给未来留了缓冲。第二你的虚拟磁盘本身是否还有扩展余地如果VMware宿主磁盘趋近饱和那下次扩容可能要考虑新增独立数据盘而不是继续放大系统盘。第三根分区和数据的存放逻辑是否合理很多人的根分区之所以不够用是因为把所有业务数据都堆在了根分区。如果条件允许把数据库目录、容器数据目录这类大体积内容挂载到独立分区或独立磁盘根分区扩容的频率会大大降低。按照我个人多年的运维习惯LVM是一次投入、长期受益的方案。首次安装系统时花五分钟规划好磁盘分区结构后面扩容基本都是标准化的四条命令pvcreate、vgextend、lvextend、resize2fs。这套流程我也会定期在测试环境里演练一遍因为某些细节比如分区类型代码、卷组名太久不碰真的会忘。文档可以帮你捡起知识点但亲手操作过的肌肉记忆才是真正的保险。希望这篇操作说明能让你在真正需要扩容的那天从容地敲下每一个命令。
返回列表