
1. 动手之前的必修课虚拟机里的“硬盘”到底是什么如果你在公司里负责几台Linux虚拟机早晚会遇到同一个场景磁盘空间不够了得给虚拟机加一块新硬盘。Windows桌面上装个新硬盘插上SATA线、开机、磁盘管理里初始化一下就行虚拟机里加硬盘则要过好几道关卡——先在虚拟化平台上加虚拟磁盘再进系统里识别、分区、格式化、挂载。这套流程本身不难但坑不少。这篇文章里所有的操作我都按最常见的环境来讲宿主机用VMware Workstation或者KVM/QEMU虚拟机内系统以CentOS/Rocky Linux和Ubuntu为主。整个思路是通用的哪怕你用的是Proxmox VE、ESXi或者Windows Server上的Hyper-V原理也一致虚拟化平台负责“造一块盘”操作系统负责“认出它、格式化它、用起来”。写这篇文章的初衷是因为我见过太多人卡在中间环节在管理界面加了磁盘进系统后lsblk却看不到看得到盘但mount报wrong fs type或者重启之后挂载目录空空如也。这些问题单独看都不难但凑在一起特别容易让人怀疑是不是虚拟机平台坏了。所以这篇不只是给命令我会把每一步为什么这么做讲清楚。1.1 虚拟机里的“硬件”其实是一个文件先说一个很多人忽略的事实你在虚拟机管理界面里“添加硬盘”本质上不是真的插了一块硬盘进去而是创建了一个大文件或者一个存储卷。VMware里是.vmdk文件KVM/QEMU里是.qcow2文件Hyper-V里是.vhdx文件。虚拟机的磁盘控制器是软件模拟的或者走半虚拟化驱动它把对这个文件的读写请求包装成对“硬盘”的读写。这个认知有多重要它决定了三件事新加的虚拟硬盘在虚拟机内部看起来就是一个块设备和物理机里看到的/dev/sdb、/dev/nvme0n1没有本质区别。虚拟硬盘是“按需增长”还是“一次性占满空间”取决于你创建它时选择的磁盘类型。厚置备Thick Provision会立刻占用宿主机空间精简置备Thin Provision用多少占多少但磁盘内部的文件系统必须在创建后自己格式化。如果你做的是“直接使用物理硬盘”比如把整个物理磁盘直通给虚拟机操作流程完全一样只是不经过虚拟化层的文件封装。我见过有同事在虚拟机里加了一块20G的虚拟磁盘格式化之后挂载上去然后跑到宿主机上看发现磁盘文件还是很小以为加错了——实际上Thin Provision就是这样文件系统刚建好时基本没数据空间是“分期付”的。1.2 设备命名为什么有人看到sdb有人看到vdb虚拟机里的磁盘设备名取决于你挂磁盘时选择的控制器类型。这块知识虽然不难但搞错了容易导致后面操作时找错设备。SATA/SAS控制器VMware默认对此类兼容性较好在Linux里显示为/dev/sdX比如/dev/sda、/dev/sdb。IDE控制器老虚拟机常见同样显示为/dev/sdX但性能很受限制新项目基本不选它。VirtIOKVM/QEMU里最常见设备名是/dev/vdX比如/dev/vda、/dev/vdb。VirtIO是半虚拟化设备性能远好于纯模拟的SATA/IDE。NVMe现代平台支持设备名是/dev/nvme0n1这样的格式nvme0表示控制器编号n1表示命名空间。所以你在Linux虚拟机里新加磁盘后先别急着格式化第一件事是用命令看清设备名。1.3 挂载不是格式化两者千万别混很多人把“挂载”和“格式化”混在一起这是很容易出问题的开始。打个比方格式化相当于在一块空地上打好地基、建好仓库挂载相当于把你的货放进仓库然后在大门上挂一个牌子“3号库”以后所有往“3号库”这个地址送的货都会被存进这个仓库里。Linux的挂载就是把你的文件系统挂到一个目录挂载点上此后你读写这个目录实际就是读写那块磁盘。用命令表达就是mount /dev/sdb1 /data这里的/data就是一个“3号库”的牌子它本身不需要提前格式化只需要目录存在。如果/data不存在mount会报错你得先mkdir。搞清楚了这些基础概念下面的操作部分才不容易跑偏。2. 在虚拟机管理界面加硬盘VMware和KVM完整操作这个阶段最容易犯的错不是点错按钮而是磁盘模式选择了“独立持久化”或“独立非持久化”。如果你选了独立非持久化那么虚拟机重启后对这块盘的所有写入都会丢掉很多人挂载后重启发现数据没了就是栽在这里。默认的“持久化”模式是普通使用的最佳选择。2.1 VMware Workstation从编辑设置到SCSI控制器打开VMware Workstation版本差异不大以VMware Workstation Pro 17为例选中目标虚拟机执行以下步骤点击“编辑虚拟机设置”Edit virtual machine settings。在“硬件”选项卡里点击“添加”Add选择“硬盘”Hard Disk“下一步”。磁盘类型选择这步很关键如果你在虚拟机里看到的是/dev/sda这种SATA设备名新加的盘建议同样选SATA避免设备名混杂。如果你的虚拟机已经用了NVMe控制器而且系统是Windows 10/ Server 2016之后的版本可以直接选NVMe。“SCSI”通常用于Linux老设备或特定兼容场景一般选默认即可。指定磁盘容量。这时候要注意**“立即分配所有磁盘空间”**这个选项。你想达到“宿主机不占多余空间”的效果就不勾选“立即分配”想要性能稳定、避免运行中报错“磁盘空间不足”就勾选它。建议生产环境、物理机空间充裕时勾选“立即分配”测试环境则不勾选。关键一步在“指定磁盘文件”名称之后回到“硬件”列表选中刚才添加的硬盘展开下方的“高级”选项虚拟设备节点Virtual Device Node选哪个控制器通道通常默认即可不用折腾。点击“确定”然后启动虚拟机进入系统内操作。如果你是想给ESXi里的虚拟机加磁盘其实是两条路线要么在vCenter的“编辑设置”里给虚拟机新增一块虚拟磁盘要么在主机上先建一个数据存储Datastore再把存储映射给虚拟机用。这两条路线思路相通但网上教程大多只讲Workstation导致ESXi用户在/dev下怎么等都等不到新设备。ESXi加完磁盘后虚拟机内需要执行echo - - - /sys/class/scsi_host/host0/scan这类命令扫描新设备这个我们后面章节单独讲。2.2 KVM/QEMUvirt-manager添加流程与总线选择KVM环境下最常用的是图形管理工具virt-manager操作如下打开virt-manager双击目标虚拟机打开“详情”Detail视图。左侧选择“添加硬件”Add Hardware右侧类型选“存储”Storage。在“创建存储”Create storage里选择“文件镜像文件”或“块设备物理磁盘/LVM卷”。创建qcow2镜像时需要注意选址不要把镜像文件放在根分区否则根分区满了虚拟机会直接卡死。应放在独立的存储池比如/var/lib/libvirt/images或其他数据盘。分配大小勾选“立即分配”等于厚置备不勾选则是精简置备。总线类型选“VirtIO磁盘”还是“SATA”/“IDE”决定了系统内的显示名VirtIO →/dev/vdbSATA →/dev/sdbIDE → 同样是/dev/sdb但性能最差完成添加启动虚拟机。需要注意KVM里如果选VirtIO磁盘但虚拟机内部没有安装virtio驱动很老的Linux发行版会这样系统会根本看不到这块盘这是“加了盘但系统里找不到设备”的一种典型原因。3. Linux虚拟机内部分区、格式化、挂载一套命令走完这部分我直接给你一套能照抄的命令序列但每一条都会解释它到底在做什么遇到异常时你才好排查。3.1 先识盘怎么确认新磁盘已经到系统了进入虚拟机终端第一步永远是这个lsblk fdisk -llsblk输出类似这样NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 40G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 39G 0 part / sdb 8:16 0 20G 0 disk看到sdb、vdb这种没有任何分区的新设备MODE列显示disk而不是part说明系统已经识别到这块盘但没有被分区。如果你在虚拟机管理界面里加完盘开机后lsblk里看不到有几个常见原因需要重启虚拟机热添加未配置好时重启必定能认出来。控制器类型不匹配如KVM里选了VirtIO但系统没有virtio驱动。虚拟机平台里磁盘处于“未连接”Disconnected状态检查一下硬件列表里有没有勾选“连接”。3.2 分区fdisk还是partedGPT还是MBR现代环境优先选GPT分区表因为MBR上限是2T且对分区数量有限制。虚拟机磁盘如果大于2T必须GPT。小于2T用GPT也没问题无非是老工具不兼容。使用fdisk对/dev/sdb分区一个完整流程如下fdisk /dev/sdb交互界面里依次输入n 新建分区 p 主分区如果默认类型是p就直接回车 1 分区号1默认回车也可 回车 分区起始扇区用默认 回车 分区结束扇区用默认就是把整块盘都用掉 w 写入分区表然后执行partprobe /dev/sdb这个命令是让内核重新读取分区表。有些人分完区后lsblk看不到/dev/sdb1就是漏了这一步直接重启倒也行但没必要。如果你习惯用parted对应命令是parted /dev/sdb mklabel gpt parted /dev/sdb mkpart primary 0% 100% parted /dev/sdb name 1 data # 给分区打个标签方便识别我个人建议新环境直接parted走GPT因为它同时负责磁盘标签和分区创建一步到位不容易犯“分区表类型选错”的错。3.3 格式化文件系统类型怎么选分区创建好后格式化这一步是分水岭。文件系统选错了后面挂载融错率低性能不明显但对某些场景不兼容。常用的几类ext4最稳的选择绝大多数Linux默认都支持不需要额外工具适合大部分业务数据盘。xfsCentOS/RHEL 7及以后版本的默认文件系统适合大文件、高吞吐但不能缩减大小。btrfs功能强快照、压缩、子卷但生产环境折腾成本高个人不建议在虚拟机的普通数据盘上冒险。ntfs/fat如果这块盘以后要拔下来插到Windows上读取才需要这些虚拟机里一般不搞这种跨界盘。我的建议没有特殊需求就在ext4或xfs里选。Ubuntu和Debian用户默认ext4即可CentOS/Rocky用户习惯xfs也没错。格式化命令mkfs.ext4 /dev/sdb1如果你选了xfsmkfs.xfs /dev/sdb1格式化的时候可以顺手给卷标方便识别盘的身份mkfs.ext4 -L data /dev/sdb13.4 手动挂载与测试读写创建一个挂载目录然后挂载mkdir -p /data mount /dev/sdb1 /data验证一下df -h /data终端输出显示/dev/sdb1 20G挂在/data下就成功了。接着写入测试文件确认读写正常dd if/dev/zero of/data/test.bin bs1M count1024 oflagdirectoflagdirect强制绕过缓存直接写盘避免数据先写在内存里给你造成“成功了”的错觉。命令跑完后查看/data/test.bin的大小是否为1G左右然后删掉它。这里还有一个细节如果挂载时报错mount: /data: wrong fs type, bad option, bad superblock on /dev/sdb1通常有三种情况/dev/sdb1其实还没格式化。文件系统类型跟挂载时指定/自动匹配的不一致比如实际是xfs但系统稀里糊涂当ext4挂载。分区文件系统损坏常见于强行关机后。排查时先用blkid /dev/sdb1看文件系统类型对不对再用fsck检查。4. 开机自动挂载UUID和fstab的正确用法手动挂载有个明显的缺点虚拟机一重启挂载关系就丢了。要想每次开机都自动把新盘挂在指定目录就要在/etc/fstab里写一条记录。4.1 为什么推荐UUID而不是设备名/dev/sdb1这种设备名看着直观但它是根据检测顺序分配的名字。虚拟机一旦新增或移除磁盘、或者调整了SCSI通道设备名会改比如原来的/dev/sdb1可能变成/dev/sdc1然后你的fstab就失效了系统还可能因此直接卡在开机挂载失败的错误里。而UUID是文件系统格式化时生成的唯一标识只要不重新格式化它就不会变。无论设备在系统里叫什么名字fstab里写UUID永远能找到正确的分区。获取UUID的方式blkid输出里能看到类似/dev/sdb1: UUIDa1b2c3d4-... TYPEext4的信息把UUID复制出来。4.2 fstab的六个字段逐行拆解/etc/fstab每行格式如下设备 挂载点 文件系统类型 挂载选项 dump fsck对应我们的场景写这样一行UUIDa1b2c3d4-... /data ext4 defaults 0 2字段含义UUID...锁死设备身份。/data挂载点必须事先存在。ext4文件系统类型。defaults常用挂载选项。想启用读写权限就写rw想禁止执行文件就加noexec需要每天自动清理垃圾可以加noatime。生产数据盘我一般写defaults,noatime。0dump备份标记现在基本用不上。2fsck检查顺序。根分区一般写1其他数据分区写2不检查写0。有一个反直觉的坑我得单独提醒挂载点目录不要建在根分区根目录下面一个没有权限的路径里更不要挂在像/home、/var这类已经被其他分区占用的路径上。如果/home已经是一个独立分区你又把新盘挂到/home上原来的数据会被“遮住”——不是删了而是在这个挂载点下看不见了。等你卸载新盘原数据又回来了。初学者容易在这里被吓到。改完/etc/fstab一定要执行一次mount -a这条命令会按fstab里的配置重新挂载所有未挂载的项。如果语法有错它会当场报错而不是等你重启后才出问题。看到没有任何输出或者只是提示“已挂载”就说明配置没问题。重启前强烈建议再验证一次findmnt --verify --verbose这个命令会模拟检查fstab的正确性输出没有异常再重启。我在这一步救过不少次级事故。4.3 更现代的systemd挂载单元RHEL/CentOS 7、Ubuntu 16.04这些系统上systemd会读取/etc/fstab并自动生成对应的挂载单元所以你其实不需要手写.mount文件。凡是fstab里的配置systemd都会接管。但如果你追求更清晰的管理方式比如让挂载关系和某个服务绑定可以手写挂载单元。假设挂载点是/data对应的unit文件是/etc/systemd/system/data.mount[Unit] DescriptionMount data disk Afterlocal-fs.target [Mount] WhatUUIDa1b2c3d4-... Where/data Typeext4 Optionsdefaults,noatime [Install] WantedBymulti-user.target然后启用systemctl daemon-reload systemctl enable --now data.mount这种方式的好处是如果挂载失败你可以直接看systemctl status data.mount的错误信息比fstab报错好诊断得多。不过绝大多数场景fstab已经够用不必引入额外的维护成本。5. 不想重启虚拟机热插拔识别新磁盘的完整链路生产环境最忌讳无计划重启所以我得单独开一节讲“不重启怎么认出新磁盘”。这里的完整链路分成两步宿主机层面确认磁盘已经“接入”虚拟机内部触发SCSI设备重扫。如果你用的是VMware Workstation在“编辑虚拟机设置”里加完磁盘大多数情况下Linux虚拟机立刻就能在lsblk里看到新设备因为VMware tools会主动通知客户机重新扫描。如果没看到试试echo - - - /sys/class/scsi_host/host0/scan echo - - - /sys/class/scsi_host/host1/scan echo - - - /sys/class/scsi_host/host2/scan这个命令是让每个SCSI主机控制器扫描一遍自己通道上未识别的设备。- - -分别是host、channel、target的占位符全写减号就是“无论哪个通道都扫一遍”。执行后运行lsblk大概率能看到新盘。如果还是在看不到换一条更暴力的方法for host in /sys/class/scsi_host/host*; do echo - - - $host/scan; done这条命令自动遍历所有SCSI主机控制器效果一样只是省得手动敲好几遍。热添加场景下分区操作跟前面完全一样但需要注意fstab的UUID获取时机。如果是热插拔设备名可能不是刚才lsblk显示的那个因为内核扫描顺序有延迟所以更要坚定不移地用UUID写fstab别想当然拿/dev/vdb1写进去。5.1 在线扩容的一个额外小技巧如果新添加的磁盘容量比你预先规划的大而且你不想重新分区可以只用parted调整分区边界然后扩展文件系统。但虚拟机内如果加了盘最安全的做法是“加一块新盘而不是改原盘”因为改原盘大小需要关闭分区使用或很小心地操作。这里甩出一个经验结论单一数据盘不够用了再加一块新盘挂到新目录/替换扩容永远比在原盘上蹩脚地用LVM或growpart省心和安全。如果你已经把根分区用LVM管理起来CentOS/RHEL默认就是扩容流程反而是加新盘最容易的路线。先把新盘分区、格式化后加入PV/VG/LV然后扩展文件系统。不过LVM这块内容量太大如果读者感兴趣我后面可以单独再写一篇本文先聚焦挂载操作本身。6. 五类高频故障排查从wrong fs type到设备消失挂载出错不奇怪每个人都会遇到。下面是我在实操中遇到最多、且网上说法又比较零散的五类问题按发生频率排序附排查链路。6.1 mount时报wrong fs type, bad option报错全貌类似mount: /data: wrong fs type, bad option, bad superblock on /dev/sdb1, missing codepage or helper program, or other error.这个报错看起来吓人实际最常见的原因就是“分区没格式化”。你新加的盘从头到尾就没跑过mkfs内核读写时找不到文件系统的超级块自然报错。排查顺序blkid /dev/sdb1看有没有TYPE字段。如果有TYPEext4这类信息说明是挂载命令或选项的问题如果没有TYPE基本确认没格式化跑一遍mkfs.ext4 -f /dev/sdb1解决。如果TYPE是xfs而系统是老内核/老发行版可能内核里缺xfs驱动那就modprobe xfs加载或者在系统安装阶段确认要包含xfs支持。如果之前格式化过但中途崩溃过可以fsck.ext4 -y /dev/sdb1修复超级块。6.2 重启后挂载目录是空的这种情况基本可以断定是fstab没写对或设备名变了。排查链路blkid看UUID是否跟fstab里一致。cat /etc/fstab检查字段数量是不是6个类型跟实际文件系统是否匹配。df -h确认是不是压根没挂载。如果根本没挂载但fstab写了看systemctl status里对应挂载单元的错误。如果系统启动时报错卡住进入紧急模式emergency mode时执行mount -a看具体报错信息。注意在紧急模式下修复fstab时千万别直接删行完事要先用mount -a确认原因再决定是改UUID还是改挂载点。6.3 磁盘已存在但lsblk看不到这是我在KVM和ESXi里都遇到过的问题。磁盘在管理界面已经添加但客户机看不到。常见原因和对应解法可能原因排查手段解法SCSI控制器没触发重扫lsscsi看有没有设备执行echo - - - /sys/class/scsi_host/hostX/scanVirtIO驱动缺失lsmodgrep virtio磁盘处于未连接状态查看虚机硬件列表确认磁盘勾选“连接”勾选后保存重启虚拟机平台是ESXi且磁盘没有映射到虚拟机的控制器vCenter里看“添加新设备”是否正确选择“现有硬盘”重新编辑虚拟机配置确认磁盘类型为“新标准硬盘”或“RDM”6.4 卸载时报target is busy常见于你挂载了目录但进程里还有文件正被占用umount /data # umount: /data: target is busy.解法是用fuser和lsof找到占用进程fuser -mv /data lsof D /data然后根据业务情况杀掉相关进程再卸载。生产环境千万别无脑fuser -km /data会误杀数据库进程造成数据损坏风险。正常情况下提前通知业务停应用再安全卸载。还有一种target is busy是因为你在挂载目录内比如当前工作目录就在/data里shell占住了它。cd回到/再umount即可解决。6.5 新加磁盘后虚拟机直接无法启动这个比较冷门但很致命虚拟机开着时在管理界面直接删除了磁盘文件或者对磁盘做了“移除”操作但系统里的分区表和fstab还认识它启动时因找不到设备而进入紧急模式。这种情况下不要慌进紧急模式注释掉/etc/fstab里对应的那行然后重启。等系统恢复后再考虑是否需要把新盘加回来并重新配置挂载。7. 挂载后的日常工作卸载、扩展与习惯养成挂载不是一次性动作它涉及到长期的系统维护。这里分享一些我在实际运维中养成的习惯以及卸载数据盘的正确姿势。7.1 安全卸载的完整过程当你需要把这块盘摘掉比如迁移到别的虚拟机正确顺序是停止写入该目录的所有业务进程。执行sync把内存里的脏数据刷到磁盘。umount /data卸载。rm掉/etc/fstab里的对应行防止重启后找不到设备卡住。在虚拟化管理界面把磁盘从虚拟机分离或删除。特别提醒umount之前别依赖“看起来没有进程”就动手生产环境务必先在业务层面确认没有活动事务。如果是数据库的数据盘直接umount可能把数据文件搞坏这种场景最好走数据库自身的备份/停机流程。7.2 给后来人的几条习惯建议每次操作完都要验证加盘后先lsblk再看df -h写fstab后mount -afindmnt --verify这套验证成本只要几秒钟但能避免很多经典事故。数据盘目录单独规划建议把业务数据放在/data这类统一目录下别把数据盘挂到/root、/tmp下面否则权限和清理策略会让你很痛苦。及时记录盘的身份在物理机上给硬盘贴标签很常见虚拟机里也可以做格式化时加-L卷标或者把计划写在/etc/fstab注释里。半年后你再回去看这个系统会感谢自己当时写了这几行注释。监控磁盘空间加盘解决的是空间不足问题但如果业务增长快应该考虑周期性监控分区使用率在到达阈值前提前扩容或添加新盘而不是每次等“满了再救火”。提示如果虚拟机用的是精简置备磁盘可以在宿主机上看到磁盘文件实际占用远小于标称容量但大量删除文件后宿主机的空间不会自动回收需要执行fstrimLinux或Defragment and CompactVMware来释放空间这是另一类常见坑。我个人在给虚拟机加盘这件事上最大的体会是步骤简单但每个环节都有关键参数。你只要记住四个关键词——“设备名、UUID、挂载点、fstab”这套操作就串起来了。先在测试虚拟机里练几遍再上生产基本上不会再出问题。