这事得从一台跑了快五年的 CentOS 7 虚拟机说起。公司在 Windows Server 2012 上用 Hyper-V 虚拟了一批 Linux 业务机,其中一台跑内部数据归集脚本的机器,磁盘空间告急到只剩几个 GB,内存也偶尔被任务顶满。要给它扩展存储和内存,本来以为在 Hyper-V 管理器里把数字改大就完事,结果发现整个链路里全是细节:内存有静态和动态两种模式,磁盘扩展还牵扯到虚拟盘格式、快照、分区表、LVM、文件系统类型。更坑的是,就算 Hyper-V 这边扩展成功了,Linux 系统里 df -h 一看还是老容量,很多人卡在这一步就不知道怎么办了。
这篇文章把我实际操作和踩坑的过程完整写一遍,从 Server 2012 的 Hyper-V 管理器操作,到进入 Linux 虚拟机后处理分区、LVM、文件系统扩容,一条链路全部跑通。适合正在用老版本 Windows Server 跑 Hyper-V、手底下 Linux 虚拟机空间不够又不敢乱动手的运维同行,也适合自学虚拟化想搞明白“扩展磁盘后为什么系统里没变化”的新手。
1. 扩展前的摸底与准备
1.1 先分清“存储”和“内存”,再决定操作路径
很多人把“扩展存储内存”当成一个操作,其实这是两件事:存储指的是虚拟磁盘的容量,内存指的是虚拟机的 RAM。两者在 Hyper-V 管理器里的操作位置不同、生效条件不同、进入虚拟机后要做的处理也不同。
存储这块,简单说就是虚拟磁盘文件(VHD 或 VHDX)对应的“硬盘”变大了,但虚拟机内部的操作系统不会自动知道这个变化,需要登录 Linux 后手动扩展分区、物理卷、逻辑卷和文件系统。内存这块,如果虚拟机配置的是固定内存,改完通常要重启才生效;如果开了动态内存,情况会复杂一些,后面单独说。
我的建议是操作前先分清自己到底要解决哪个问题:如果是业务数据把磁盘写满了,走存储扩容链路;如果是跑批任务 Out Of Memory 导致进程被杀,走内存调整链路。两件事可以一起做,但不要混在一起处理,出问题的时候不好定位。
1.2 内存分配方式:静态内存与动态内存
Server 2012 的 Hyper-V 管理器里,虚拟机的“内存”设置项主要分两种状态:勾选了“启用动态内存”和没勾选。
没勾选动态内存时,内存是按固定值分配的。比如原来设置 2048 MB,虚拟机启动就占 2 GB 物理内存,改大小后必须重启虚拟机才生效。
勾选动态内存后,会出现“启动内存”“最小内存”“最大内存”三个值。Hyper-V 会根据客户机负载在最小和最大之间自动调整内存分配。问题在于,Linux 客户机对动态内存的支持依赖内核里的 Hyper-V 集成服务,也就是 hv_balloon 等驱动。内核太老或没装集成服务,就算 Hyper-V 这边把“最大内存”调大了,Linux 里也未必能在线感知到新增的内存。
这里补一个背景知识:Hyper-V 的动态内存是靠气球(balloon)机制实现的,虚拟机监控程序把内存“塞”给客户机或者从客户机“收回来”。Windows 客户机对这个机制支持得很好,Linux 客户机则要看内核版本和发行版,CentOS 6 及更早的版本经常需要手动安装 Linux Integration Services 才能正常工作,CentOS 7 之后的内核基本都内置了 Hyper-V 驱动。
所以我的建议是:不折腾,直接关机,把内存改成目标值,再开机。这样最稳妥,也不会被“改了没生效”坑到。
1.3 磁盘格式和控制器的选择
给 Linux 虚拟机扩展磁盘前,先看一眼这块虚拟磁盘是什么格式、挂在哪个控制器下。
Server 2012 支持 VHD 和 VHDX 两种虚拟磁盘格式。VHD 最大只能到 2 TB,而且不支持在线扩展;VHDX 上限 64 TB,可靠性更好,断电恢复能力也更强。如果你手里还是 VHD 格式的老磁盘,建议先用“编辑磁盘 -> 转换”把它转成 VHDX,再做后续扩容。
控制器方面,Server 2012 里的虚拟机默认支持 IDE 和 SCSI 两类控制器。系统盘如果是 IDE,性能和功能都会受限;SCSI 控制器下的虚拟磁盘支持更灵活的扩展方式。Windows Server 2012 的 Hyper-V 虚拟机默认是第一代虚拟机,第一代虚拟机里 IDE 控制器接了 SCSI 控制器的驱动是另外一回事。我的经验是:生产环境里的 Linux 虚拟机,系统盘和数据盘都尽量放在 SCSI 控制器下,性能和扩展性都好一些。
还有一个非常关键的前提:如果虚拟机存在检查点(快照),直接扩展磁盘经常会失败,或者扩展出来的空间在某个还原点之后才可见,乱成一团。扩展磁盘之前,确
