家里使用的NAS是DIY的All In One主机,母鸡是PVE(Proxmox Virtual Environment)。

为便于管理和维持良好的独立性,我把主要的Docker服务部署在基于PVE虚拟机的开源NAS系统OMV(openmediavault)上。由于计划赶不上变化,原先给OMV预分配的磁盘空间已经耗尽,以致web管理页面也无法登录,只能通过ssh方式管理。为解决这个问题,在保数据的前提下,从母鸡分配磁盘空间进行扩容已是唯一选择。

原本以为扩容操作可以直接通过PVE的web管理页面便能轻松实现(我部分虚拟机确实是这样)。但是,OMV这个情况和我预想的还是有点偏差,扩容后的空间无法合并到根目录上。具体原因是部署OMV时,我使用安装方式为虚拟机IOS镜像直读模式。从win32开始遗传的电脑使用习惯(安装直接点“下一步”)安装的OMV,自然自带swap分区。由于swap分区的存在,导致pve扩容的空间无法和原来OMV磁盘组成连贯分区,无法实现根目录扩容的目的。网上清一色的教程均为简单的独立分区无损扩容,并没有提及这种带其他分区的磁盘该如何扩容。因此,我写下这个笔记供后续遇到类似需求的朋友作为参考,避免踩坑。

存在swap分区的PVE虚拟机磁盘如何扩容?

母鸡扩容

母鸡扩容的方法很简单,可通过PVE的Web管理系统->目标主机->硬件->选定目标磁盘->操作菜单:磁盘操作->调整大小,给你目标的主机设置需扩容的磁盘空间。

扩容操作
扩容操作

信息确认

通过ssh工具访问OMV,查看磁盘的基本情况。

PS:本例子使用的磁盘均为sda

$sudo parted /dev/sda 'unit s print' free
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 14336000s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start      End        Size       Type      File system     Flags
        63s        2047s      1985s                Free Space
 1      2048s      10485759s  10483712s  primary   ext4            boot
        10485760s  10487805s  2046s                Free Space
 2      10487806s  12580863s  2093058s   extended
 5      10487808s  12580863s  2093056s   logical   linux-swap(v1)
        12580864s  14335999s  1755136s             Free Space

如上面shell信息所示,sda1被扩容的空间在磁盘分区的最后,中间隔着一个swap分区,这样扩容的空间是无法直接分配到sda1上。

如果要实现无损扩容必须把swap分区删除,然后把sda1扩容后再重建swap分区。

第一步,关闭swap分区

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           992M         52M        464M        3.2M        475M        784M
Swap:          1.0G          0B        1.0G

通过free命令查看swap是否存在占用,如果没有,直接关掉;如果有,可以尝试重启下该虚拟机。

$sudo swapoff /dev/sda5

第二步,重新配置分区列表

$sudo fdisk /dev/sda

(注意: 假如你的虚拟机磁盘初始扇区是63而不是2048, 你需要在fdisk命令后面增加一个参数 -c=dos)

参考下面的操作步骤删除swap分区和重建分区列表。

PS:本操作虽然是无损扩容,但数据无价建议有条件的一定要先备份数据!!!

Welcome to fdisk (util-linux 2.27.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help): p
Disk /dev/sda: 6.9 GiB, 7340032000 bytes, 14336000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x9e11c6df

Device     Boot    Start      End  Sectors  Size Id Type
/dev/sda1  *        2048 10485759 10483712    5G 83 Linux
/dev/sda2       10487806 12580863  2093058 1022M  5 Extended
/dev/sda5       10487808 12580863  2093056 1022M 82 Linux swap / Solaris

Command (m for help): d
Partition number (1,2,5, default 5): 2

Partition 2 has been deleted.

Command (m for help): d
Selected partition 1
Partition 1 has been deleted.

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-14335999, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-14335999, default 14335999): 12242941

Created a new partition 1 of type 'Linux' and of size 5.9 GiB.

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2): 2
First sector (12242942-14335999, default 12242944):
Last sector, +sectors or +size{K,M,G,T,P} (12242944-14335999, default 14335999):

Created a new partition 2 of type 'Linux' and of size 1022 MiB.

Command (m for help): a
Partition number (1,2, default 2): 1

The bootable flag on partition 1 is enabled now.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Re-reading the partition table failed.: Device or resource busy

The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8).

这部分有两个地方需要注意的:

1、sda1扩容后的总大小必须是整个磁盘减去swap分区的大小,我上面的例子sda1就是: 14335999-2093058=12242941

2、fdisk分区使用‘a’命令是用来激活主分区,这个一定要重新激活。

第三步,重载分区列表

这里使用到的是partprobe,OMV是基于Debian的,默认应该安装了,如果没有安装请自行搜索安装方法.

$ sudo partprobe

第四步,重新扫描磁盘容量

使用resize2fs命令对sda1进行扩容有重扫描容量。

$ sudo resize2fs /dev/sda1
resize2fs 1.42.12 (29-Aug-2014)
Filesystem at /dev/sda1 is mounted on /; on-line resizing required
old_desc_blocks = 3, new_desc_blocks = 10
The filesystem on /dev/sda1 is now 38833617 (4k) blocks long.

第五步,重新配置swap分区

因为fdisk对ext4扩展分区支持不足,建议使用cfdisk进行重新配置swap分区。

$ sudo cfdisk
            

选择sda2分区,转换成82 Linux swap / Solaris类型并保存。

第六步,重新激活swap分区

$ mkswap /dev/sda2
/dev/sda2
UUID=d58bf1cb-d27a-487d-b337-056767fd5ad6 none swap sw 0 0

记下上面的UUID。

用命令行重新激活swap分区。

$ swapon /dev/sda2

通过命令把上面的UUID修改到fstab中

$ sudo nano /etc/fstab
# swap was on /dev/sda5 during installation
UUID=d58bf1cb-d27a-487d-b337-056767fd5ad6 none            swap    sw              0       0

确保没有问题后,重启虚拟机。

至此,无损扩容工作便全部完成。

祝你好运!