news 2026/9/27 23:30:52

VMware虚拟机安全移除非系统磁盘完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
VMware虚拟机安全移除非系统磁盘完整指南

1. 项目概述:为什么在VMware里“移除主磁盘外的其他磁盘”不是个简单勾选操作

在VMware Workstation或Player里,给虚拟机挂载第二块、第三块甚至第四块硬盘,是再平常不过的操作——点几下鼠标,选个VMDK文件,分配容量,勾上“独立”或“持久”,点击完成。但真等到某天你想把其中一块非系统盘彻底拿掉时,很多人会卡在第一步:右键虚拟机设置 → 硬盘设备 → 点“移除”,结果弹出警告:“该磁盘正被操作系统使用,无法安全移除”。这时候你才意识到,VMware界面里的“移除”,只是断开虚拟硬件连接,它不处理Guest OS内部的逻辑卷管理、文件系统挂载、LVM元数据残留这些深层依赖。尤其当这台虚拟机跑的是Ubuntu、CentOS这类默认启用LVM的发行版时,“移除磁盘”四个字背后,实际是一整套从用户空间到内核层的协同清理流程。

我去年帮客户做虚拟化资源瘦身,一次性要下线17台测试环境虚拟机,每台都额外挂了2~3块用于日志归档或临时数据交换的辅助磁盘。原计划半小时一台,结果前三台全卡在“磁盘卸载失败”上,有的报device-mapper: remove ioctl on vg01-lv_data failed: Device or resource busy,有的在lvremove时提示“Logical volume is in use”,还有一台直接因为/etc/fstab里残留了UUID挂载项,重启后进不了系统。后来翻遍VMware KB文档和Red Hat LVM手册才发现:VMware的“移除”动作,只作用于hypervisor层;而Guest OS里的磁盘生命周期管理,必须由管理员手动闭环。这根本不是功能缺陷,而是分层架构的天然设计——就像你不能指望拔掉物理服务器的SATA线缆,就自动让Linux内核卸载所有基于那块盘构建的逻辑卷和文件系统。

所以这篇内容的核心,不是教你怎么在VMware界面上点几下鼠标,而是带你走完一条完整的“磁盘退役流水线”:从识别哪些磁盘属于可移除范围,到Guest OS内逐层解耦(卸载文件系统→停用逻辑卷→清除卷组→擦除PV元数据),再到VMware层执行最终硬件断连,最后验证无残留。过程中你会用到lsblk看拓扑、findmnt查挂载点、lvs/vgs/pvs分析LVM结构、lvchange -an强制停用、lvremove物理删除、pvremove擦除签名——每一个命令背后都有明确的触发条件和不可逆风险。比如pvremove /dev/sdb执行前,必须确认该PV上所有LV已清空且VG已deactivate,否则轻则LVM元数据损坏,重则整个卷组无法识别。这不是脚本一键的事,而是需要你像外科医生一样,对存储栈每一层的状态都了然于胸。

适合谁读?如果你正在做虚拟机标准化部署、自动化运维脚本开发,或者刚接手一批历史遗留虚拟机需要清理冗余存储,又或者正在备考RHCSA/RHCE需要夯实LVM实操能力——这篇文章就是为你写的。它不讲抽象理论,只呈现我在生产环境里反复验证过的步骤链、参数组合和避坑口诀。接下来,我们就从最底层的磁盘识别开始,一层层剥开这个看似简单、实则暗藏玄机的操作。

2. 磁盘识别与状态诊断:先搞清“哪些磁盘能动、哪些碰不得”

在动手删任何东西之前,必须建立一张清晰的“磁盘资产地图”。VMware虚拟机里的磁盘命名规则(如/dev/sda、/dev/sdb)和物理位置(SCSI控制器0:0、控制器1:0)之间没有固定映射关系,完全取决于添加顺序和Guest OS启动时的探测顺序。所以第一步永远是:在Guest OS内部,用原生命令反向定位每块磁盘的真实用途和当前状态。别信VMware界面显示的“硬盘1”“硬盘2”,那只是配置文件里的标签。

2.1 用lsblk构建磁盘拓扑快照

打开终端,第一件事就是执行:

lsblk -f -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL,UUID,TYPE,MODEL

这个命令输出的信息量极大,但关键要看四列:NAME(设备名)、FSTYPE(文件系统类型)、MOUNTPOINT(挂载点)、TYPE(设备类型)。举个典型输出示例:

NAME FSTYPE SIZE MOUNTPOINT LABEL UUID TYPE MODEL sda 50G disk ├─sda1 vfat 512M /boot/efi EFI C4A5-1234 part ├─sda2 ext4 10G / root a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8 part └─sda3 LVM2_member 39.5G lvm 98765432-1098-7654-3210-fedcba987654 part sdb 20G disk └─sdb1 LVM2_member 20G lvm abcdef12-3456-7890-abcd-ef1234567890 part sdc 100G disk ├─sdc1 ext4 100G /data data fedcba98-7654-3210-feda-cb9876543210 part └─sdc2 swap 4G [SWAP] 12345678-90ab-cdef-1234-567890abcdef part sr0 1.1G rom

这里sda是系统盘(含/boot/efi、/根分区、LVM PV),sdb是纯LVM成员盘(无直接挂载点,但TYPE为part且FSTYPE为LVM2_member),sdc是独立数据盘(直接挂载到/data)。注意sdb的MOUNTPOINT为空,但它的子设备没显示——这是因为LVM层做了抽象,真实挂载点在LV层面。此时你要立刻意识到:sdb极大概率是你想移除的目标,但它上面可能承载着LV,不能直接动。

提示:lsblk -f比单纯lsblk多出文件系统和挂载信息,是判断磁盘用途的黄金命令。如果看到某块盘(如sdb)的FSTYPE是LVM2_member且MOUNTPOINT为空,基本可以锁定它是LVM辅助盘;如果FSTYPE是ext4/xfs且有明确MOUNTPOINT(如/backup),那就是直挂盘,清理路径更简单。

2.2 用findmnt精准定位挂载源头

lsblk只能看到挂载点,但不知道是谁在用。比如/data挂载在sdc1上,但如果有进程正在往/data/logs写日志,直接卸载会失败。这时要用:

findmnt -D /data

输出类似:

TARGET SOURCE FSTYPE OPTIONS /data /dev/sdc1 ext4 rw,relatime,errors=remount-ro

再查谁在占用:

lsof +D /data | head -20 # 或更暴力的 fuser -v /data

如果输出显示/data被rsync、nginx、java等进程占用,必须先停止相关服务。这是很多新手踩坑的第一步:以为卸载挂载点就能删磁盘,结果umount /data报错“device busy”,却不知道fuser -v才是破局关键。

2.3 LVM结构深度扫描:vgs/pvs/lvs三件套

针对LVM盘(如上例中的sdb),必须用LVM专用命令穿透抽象层。先看卷组(VG):

vgs -o +vg_attr,vg_extent_count,vg_free_count

输出关键字段:

  • VG Attr:wz--n-表示可写、ZRAM禁用、正常激活;wz--nc的c代表clustered(集群模式),这种VG绝不能单独删PV;
  • VSize/VFree:卷组总大小和剩余空间,如果VFree为0且LV已满,说明这块盘是刚需,不能动;
  • VG Ext:PE(Physical Extent)总数,决定扩容上限。

再查物理卷(PV):

pvs -o +pv_attr,pv_size,pv_free,pe_count,pe_alloc

重点关注PV Attr:a-表示active且可分配,a-后面带e(如a-e-)表示exported(已导出,不可用),带x(如a-x-)表示exported且excluded(排除)。如果某PV的PV Attr是a---(四个短横),说明它已被标记为missing或failed,这种盘必须优先处理。

最后看逻辑卷(LV):

lvs -o +lv_attr,lv_size,lv_role,stripes,seg_pe_ranges

LV Attr字段最复杂,前两位最关键:wi-表示writeable、inactive(可写但未激活),aw-表示active、writeable(已激活),-w-表示inactive。如果目标LV的Attr是aw-,说明它正被使用,必须先lvchange -an停用;如果是wi-,说明已停用,可直接删。

实操心得:我习惯把这三条命令合成一个检查脚本,每次操作前运行一次:

echo "=== LVM STATUS SNAPSHOT ==="; vgs; echo; pvs; echo; lvs; echo; lsblk -f | grep -E "(sdb|sdc)"

把输出保存为pre_remove_check.log,操作后对比post_remove_check.log,差异常常就是问题根源。

2.4 关键禁忌:三类绝对不能动的磁盘

基于上百次虚拟机磁盘清理经验,我总结出三类“雷区磁盘”,看到就必须停手:

  1. Swap分区所在的磁盘:如上例sdc2是swap。虽然swap本身不存数据,但swapon -s显示它正被激活。强行移除会导致OOM Killer误杀进程。正确做法是swapoff /dev/sdc2后再操作。

  2. /boot或/boot/efi所在磁盘:系统启动必备。即使它只是/dev/sda1这样的小分区,也绝不能动。lsblk里看到FSTYPE为vfat且MOUNTPOINT为/boot/efi的,直接划入保护名单。

  3. LVM卷组中唯一PV的磁盘:比如某个VG只由sdb一个PV组成,且该VG里有/home或/var等关键LV。删sdb等于删整个VG,系统可能直接崩溃。必须先用pvmove把数据迁移到其他PV(如果有),或扩展VG加入新PV后再操作。

记住:VMware界面里灰色的“移除”按钮,是对Guest OS状态的被动响应;而你的任务,是主动确保Guest OS处于可安全移除的状态。下一步,我们就进入真正的清理核心——LVM层解耦。

3. LVM层解耦实战:从停用LV到擦除PV元数据的完整链路

LVM的分层结构(PV→VG→LV→FS)决定了清理必须严格遵循“自上而下、逐层解耦”的顺序。跳过任何一层,都会导致后续操作失败或数据不一致。我见过太多人直接pvremove /dev/sdb,结果报错Can't remove Physical Volume "/dev/sdb" because it contains allocated Physical Extents——这说明LV还没删干净。下面以清理上例中的sdb盘为例,演示标准操作链。

3.1 第一步:停用所有依赖该PV的LV

先确认sdb属于哪个VG:

pvs /dev/sdb # 输出:/dev/sdb my_vg lvm2 a-- 20.00g 0

说明sdb属于卷组my_vg。查my_vg下的所有LV:

lvs my_vg # 输出:lv_data my_vg -wi-ao---- 15.00g # lv_tmp my_vg -wi-ao---- 5.00g

看到lv_data和lv_tmp都依赖my_vg,而my_vg的PV是sdb,所以这两个LV必须先停用。执行:

lvchange -an my_vg/lv_data lvchange -an my_vg/lv_tmp

-an参数含义:-a表示activate/deactivate,n表示no(即deactivate)。执行后lvs my_vg应显示LV Attr变为-wi-ao----(首字母-表示inactive)。

注意:lvchange -an是软停用,不销毁数据,只是让内核停止访问该LV。如果LV正被挂载(如/data),必须先umount再执行,否则会报错Device or resource busy。这是新手最高频错误——以为lvchange能绕过挂载状态。

3.2 第二步:删除LV并验证VG空闲

停用后,物理删除LV:

lvremove my_vg/lv_data lvremove my_vg/lv_tmp

系统会二次确认,输入y。成功后lvs my_vg应无输出,vgs my_vg显示VFree等于VSize(即100%空闲)。

关键验证点:执行vgdisplay my_vg | grep "Free PE",确认Free PE / Size数值等于Total PE / Size。例如:

Free PE / Size 5120 / 20.00 GiB Total PE / Size 5120 / 20.00 GiB

如果Free PE小于Total PE,说明还有LV没删干净,必须回溯。

3.3 第三步:停用并删除卷组(VG)

LV清空后,VG变成空壳,可以删除:

vgchange -an my_vg # 先停用VG vgremove my_vg # 再删除VG

vgchange -an确保VG内核模块卸载,vgremove清除VG元数据。执行后vgs不应再显示my_vg。

提示:vgremove是不可逆操作!它会永久删除VG的metadata header,但不会擦除PV上的数据块。所以如果未来想恢复,只要PV没被覆盖,用vgcfgrestore还能救回来(需提前备份/etc/lvm/cache/.cache)。

3.4 第四步:擦除PV元数据并验证

VG删除后,PV(/dev/sdb)上仍残留LVM签名,必须清除才能被系统识别为普通磁盘:

pvremove /dev/sdb

此命令会:

  • 检查/dev/sdb是否属于活动VG(已通过vgremove确保)
  • 清除LVM2 metadata area(通常在磁盘开头512字节)
  • 覆盖PV UUID和VG UUID

执行后pvs应不再显示/dev/sdb。为防万一,再用dd零填充开头扇区:

dd if=/dev/zero of=/dev/sdb bs=512 count=100

最后用file -s /dev/sdb验证:输出应为/dev/sdb: data,而非LVM2 physical volume。

3.5 直挂盘(非LVM)的清理路径

如果目标磁盘是直挂的(如sdc挂载/data),路径更短但同样关键:

  1. umount /data(必须确保无进程占用)
  2. rm -f /etc/fstab中对应UUID或设备行(用blkid /dev/sdc1查UUID)
  3. wipefs -a /dev/sdc1(清除文件系统签名)
  4. sgdisk --zap-all /dev/sdc(清空GPT分区表,比fdisk更彻底)

实操心得:我曾遇到一台Ubuntu虚拟机,/etc/fstab里用设备名/dev/sdc1硬编码挂载,结果VMware里移除磁盘后,系统启动卡在A start job is running for dev-sdc1.device。根源就是没删fstab。所以清理顺序永远是:卸载→删fstab→删文件系统→删分区表,缺一不可。

4. VMware层执行与最终验证:从虚拟硬件断连到宿主机清理

当Guest OS内部所有依赖解除、磁盘回归“裸设备”状态后,才能安全进入VMware界面操作。这一步看似简单,却是整个流程的临门一脚,稍有不慎就会前功尽弃。

4.1 VMware Workstation/Player中的标准移除流程

  1. 关机,不是挂起:必须确保虚拟机完全关机(Power Off),不能是Suspend或Hibernate状态。挂起状态下VMware会保留内存镜像,可能锁定磁盘句柄。

  2. 进入设置界面:右键虚拟机 → Settings → Hardware选项卡 → 找到目标硬盘(如Hard Disk 2)。

  3. 关键两步操作:

    • 先点击“Remove”按钮(不是“Disconnect”),弹出确认框时勾选**“Also delete the files from the disk”**(此项必须勾选!否则VMDK文件留在磁盘上浪费空间)。
    • 点击OK后,VMware会将该硬盘从.vmx配置文件中移除,并删除对应的.vmdk和.vmsd文件。

注意:如果目标磁盘是SCSI控制器上的设备(如SCSI 1:0),移除后该控制器编号可能变化,影响其他磁盘的/dev/sdX命名。这是VMware的固有行为,无需干预。

4.2 宿主机层面的磁盘文件清理验证

移除操作完成后,立即在宿主机(Windows/macOS/Linux)上验证VMDK文件是否真正删除:

  • Windows宿主机:打开虚拟机目录(如C:\Users\XXX\Documents\Virtual Machines\MyVM\),确认MyVM-000002.vmdk(假设是第二块盘)不存在。如果还在,说明VMware没执行删除,需手动删。
  • macOS/Linux宿主机:ls -lh MyVM.vmx | grep -i "vmdk",确认无新增vmdk引用。

更严谨的做法是检查.vmx文件:

grep -i "scsi1:0\.filename" MyVM.vmx # 应无输出;若有,说明配置未清理干净

4.3 Guest OS重启后终极验证清单

重启虚拟机,执行以下命令,确保无残留:

  1. lsblk:确认sdb(或目标设备名)已消失
  2. pvs/vgs/lvs:确认无相关PV/VG/LV
  3. cat /etc/fstab | grep -i "sdb\|sdc":确认无残留挂载项
  4. dmesg | grep -i "sdb":检查内核日志是否有ata或scsi错误(如有,说明VMware层未完全断连)
  5. df -h:确认/data等挂载点已消失

如果以上全部通过,恭喜你,磁盘已彻底退役。此时VMware虚拟机配置干净,Guest OS存储栈健康,宿主机空间释放——这才是真正的“移除完成”。

5. 常见问题与排查技巧实录:那些让我熬夜到凌晨的报错真相

在实际操作中,90%的问题都集中在LVM状态判断和命令执行顺序上。以下是我在生产环境记录的高频报错及解决方案,附带真实场景还原。

5.1 经典报错:Cannot deactivate volume group "my_vg" with 1 open logical volume(s)

场景还原:执行vgchange -an my_vg时报此错,但lvs显示所有LV都是-wi-(inactive)状态。

根因分析:LV虽inactive,但内核device-mapper表中仍有活跃映射。常见于:

  • LV曾被kpartx映射过分区(如kpartx -av /dev/my_vg/lv_data)
  • dmsetup info显示my_vg-lv_data状态为ACTIVE

解决步骤:

# 查看所有dm设备 dmsetup info | grep -A5 "my_vg" # 强制移除映射 dmsetup remove my_vg-lv_data # 再试vgchange vgchange -an my_vg

提示:dmsetup是device-mapper底层工具,比LVM命令更接近内核。当LVM命令失效时,dmsetup往往是最后的救命稻草。

5.2 隐形陷阱:pvremove报错Can't open /dev/sdb: Device or resource busy

场景还原:pvs已不显示sdb,但pvremove /dev/sdb仍报busy。

根因分析:磁盘被udev规则或lvmcache锁定。lsof /dev/sdb可能无输出,但udevadm info --query=all --name=/dev/sdb会显示E: ID_PART_TABLE_UUID等属性被缓存。

解决步骤:

# 清理udev缓存 udevadm control --reload-rules udevadm trigger --subsystem-match=block # 强制刷新LVM缓存 vgscan --cache # 再试pvremove pvremove /dev/sdb

5.3 系统级故障:移除磁盘后虚拟机无法启动,卡在GRUB

场景还原:VMware中移除sdb后,重启虚拟机卡在GRUB菜单,无法进入系统。

根因分析:/boot/grub/grub.cfg中linux行指定了root=UUID=xxx,而该UUID对应原sdb上的LV。GRUB找不到根设备,无限等待。

紧急修复(无需重装):

  1. 启动时按c进入GRUB命令行
  2. ls查看所有磁盘,找到含/boot的分区(如(hd0,gpt1))
  3. set root=(hd0,gpt1)→linux /vmlinuz-... root=UUID=yyyy(用blkid查新根分区UUID)→initrd /initramfs-...→boot
  4. 进入系统后,sudo update-grub重建配置

5.4 常见问题速查表

问题现象可能原因快速诊断命令解决方案
umount /data报device busy进程占用或子挂载fuser -v /data
findmnt /data
fuser -k /data杀进程
umount -l /data懒卸载
lvremove报LV is lockedLV被lvmetad守护进程锁住`ps auxgrep lvmetad`
vgremove后pvs仍显示PVPV未从缓存清除vgscan --cachepvscan --cache刷新缓存
移除后lsblk仍显示sdbVMware未真正断连dmesg | grep sdb关机→重新打开VMware设置→确认移除

最后分享一个小技巧:对于批量清理,我写了一个安全检查脚本safe_disk_remove.sh,它会自动执行lsblk→findmnt→lvs/vgs/pvs→fuser四重校验,只有全部通过才允许执行lvremove。脚本核心逻辑是:

if [[ $(lvs -o lv_name,vg_name --noheadings \| grep "$VG_NAME" \| wc -l) -eq 0 ]] && \ [[ $(fuser -s "$MOUNT_POINT" 2>/dev/null \| wc -l) -eq 0 ]]; then echo "Safe to remove" else echo "Blocked: LV or process active" fi

这种防御性编程思维,比任何教程都管用。

我个人在实际操作中发现,最可靠的“移除完成”标志,不是VMware界面变灰,也不是lsblk消失,而是宿主机磁盘空间增长+Guest OSdmesg无SCSI错误+df -h无异常挂载点三者同时满足。这个组合验证法,帮我避开了95%的返工。现在,你可以放心地把那些闲置的VMDK从虚拟机里请出去了——它们完成了自己的使命,该退场了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 23:30:53

建设的访问网站需要密码?3步搞定完整流程不慌

建设的访问网站需要密码?3步搞定完整流程不慌 自己不会代码想做网站,却卡在访问需要密码这一步,其实并非技术难题,而是流程认知偏差。很多新手误以为“密码”是技术壁垒,实则是权限配置缺失。本文拆解【建设的访问网站需要密码】背后的完整流程,从原理到落地,用真实案例帮你避开90%的坑。…

作者头像 李华
网站建设 2026/9/27 23:30:39

3个实战案例教你搞懂如何调用wordpress函数防挂马

3个实战案例教你搞懂如何调用wordpress函数防挂马 上周刚帮一个福建的老哥搞定官网被黑挂马的烂摊子,他急得直拍桌子,问到底咋回事。其实很多新手站长都栽在这,网站突然跳出博彩广告,后台登录不上,这时候光哭没用,得动手查。我复盘了三个真实的 实战案例 ,发现根源都在底层逻辑没搞清,特别是…

作者头像 李华
网站建设 2026/9/27 23:30:23

从点灯到 STM32 GPIO 底层:寄存器、8种工作模式与电路逻辑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/27 23:30:24

网站域名申请避坑指南:新手防黑与源码下载实战

网站域名申请避坑指南:新手防黑与源码下载实战 网站被黑挂马不知道怎么办?别慌,先别急着删库重装,90%的新手在遇到这种情况时,第一反应是重装系统,这往往导致证据丢失,甚至让攻击者留下更深的后门。如果你刚做完网站域名申请,发现首页出现奇怪的弹窗或者跳转,这时候去GitHub开源仓库找对应的安全扫描工具…

作者头像 李华
网站建设 2026/9/27 23:30:19

物流网站系统php源码哪家好用?3步搞定零代码上线

物流网站系统php源码哪家好用?3步搞定零代码上线 自己不会代码想做网站,却找不到靠谱的物流网站系统php源码?别慌,选对工具能省80%的时间。我见过太多创业团队负责人卡在技术选型上,要么被低价源码坑得服务器天天崩,要么为了找“哪家好”的成品系统耗掉半个月。其实物流行业的建站逻辑很清晰:核心是运单管…

作者头像 李华
网站建设 2026/9/27 23:30:18

营销型网站成功案例揭秘:域名服务器避坑完整流程

营销型网站成功案例揭秘:域名服务器避坑完整流程 域名买错、服务器选错,这是无数中小企业做营销型网站时最大的痛点。很多老板以为只要页面好看就行,结果上线后访问慢、备案被驳回、甚至因为配置问题导致整站瘫痪。我做了十年建站,见过太多企业因为不懂底层逻辑,在“域名”和“服务器”这两个基础环节上反复折腾,浪费…

作者头像 李华