通过LVM给Ubuntu添加硬盘空间

最近实验室的服务器存储容量不够了,准备添加硬盘来进行扩容。服务器使用了 LVM 来存储 /home 目录的内容,而之前对 LVM 的了解较少,因此对 LVM 进行了一些了解。并通过虚拟机来模拟了硬盘的添加,实验了硬盘添加后进行扩容的操作。相关内容记录于此形成本文。

LVM 是一种可用在 Linux 内核的逻辑分卷管理器;可用于管理磁盘驱动器或其他类似的大容量存储设备。

LVM 利用 Linux 内核的 device-mapper 功能来实现存储系统的虚拟化(系统分区独立于底层硬件)。通过LVM,你可以实现存储空间的抽象化并在上面建立虚拟分区(virtual partitions),可以更简便地扩大和缩小分区,可以增删分区时无需担心某个硬盘上没有足够的连续空间,避免为正在使用的磁盘重新分区的麻烦、为调整分区而不得不移动其他分区的不便。

简单地说, LVM 可以将多个磁盘或磁盘分区组成一个逻辑硬盘(VG, Volume Group, 卷组),可以在这个逻辑硬盘上创建可动态调整的分区(LV, Logical Volume, 逻辑卷)。

通过这一层模拟,对存储的管理变得更加灵活。实现了 VG、LV的在线修改;无需考虑分区在硬盘上的位置,也不要求空间连续。提供了数据在硬盘间的迁移功能。此外,LVM还提供了诸如快照、镜像、缓存等功能。

而 LVM 的缺点在于需要额外的设置,且不支持在 Windows 系统下直接访问。另外,与使用 RAID 0 相似地,当一个磁盘损坏时会影响到整个卷组。

下面将简单地介绍 LVM 的基本组成,并对 LVM 的创建和动态扩容进行实验。

LVM基本组成

LVM 中,主要有物理卷(PV, Physical volume)、卷组(VG, Volume group)、逻辑卷(LV, Logical Volume)、物理块(Physical extent) 几个部分。

物理块:LVM 中最小的连续区域,默认为 4MiB 。

物理卷:用于存储 LVM 的设备,支持磁盘、分区、回环文件等各种块设备。设备上的空间被划分为若干个物理块,并附加了特殊的 LVM 头。

卷组:物理卷的组合,卷组中的物理卷上的物理块被映射为卷组上的逻辑块。

逻辑卷:存在于卷组上的虚拟块设备。可在上面进行文件系统的创建等操作。对逻辑卷进行读写时,将映射到卷组上的一批物理块进行读写。由于读写时进行了映射,因此可以将一个逻辑卷存放到多个物理卷上,弱化了对磁盘空间连续性的要求。

LVM

图中简单地展示了一个 LVM 的模型。其中共有两块磁盘,每块磁盘分为三个物理分区。/dev/sda1/dev/sdb2 两个分区没有使用 LVM 进行管理,可用于/boot 分区等其他用途。/dev/sda2/dev/sda3/dev/sdb1/dev/sdb3 四个分区则被处理为物理卷。图中创建了一个卷组,上面的四个物理卷全部加入了这一卷组中。卷组上共创建了两个逻辑卷,两个逻辑卷的物理块均散落到多个物理卷上。卷组的前后部分都存在一定的空闲空间,可用于对卷组进行扩容操作。

LVM创建

在Linux的安装中,可以选择使用 LVM 来让安装程序自动将系统中的存储通过 LVM 进行管理。对于安装时没有选择 LVM 技术的系统,可以在后期创建 LV 并挂载到一些目录上,后续便可通过 LVM 进行 LV 扩容等操作。本节演示从新加入的一块硬盘创建 LV 并将 /home 目录迁移到其中。

LV 的创建可以分成下面几个步骤:创建分区(partition)、创建物理卷(PV)、创建卷组(VG)、创建逻辑卷(LV)。完成 LV 的创建后,即可进行格式化和挂载等操作,并将 /home 目录内容进行迁移。

下面是详细的创建和迁移步骤:

  1. 在磁盘上创建物理分区。创建分区时需要注意将分区类型设置为 LVM 类型。在 MBR 分区表上,LVM 分区的类型为 8e ;在 GPT 分区表上, LVM 分区的类型为 8e00 。LVM支持在裸硬盘等各类块设备上创建 PV 。这里为了避免对齐等问题,没有直接使用裸硬盘。

    image-20211030170448764

  2. 在物理分区上创建 PV 。创建完成后可以通过 pvdisplay 命令查看系统中 PV 的信息。

    image-20211030171948187

  3. 在上一步创建的 PV 上创建 VG 。创建完成后可以通过 vgdisplay 命令查看系统中 VG 的信息。如果后续需要向 VG 添加 PV ,可以通过 vgextend 命令来完成。

    Note: 如果参数中指定的 PV 未创建,将会自动创建。因此可以略过上一步创建 PV 的过程。

    image-20211030172149694

  4. 在上一步创建的 VG 上创建 LV 。创建完成后可以通过 lvdisplay 命令时查看系统中 LV 的信息。创建 LV 的命令中,也可以通过调整一些参数让 LV 使用 VG 的所有未使用的空间。

    image-20211030172633642

    现在 LV 应该会出现在 /dev/mapper/vg0-lv0/dev/vg0/lv0 中。后续的格式化、挂载等内容就和传统硬盘相似了。

  5. 在上一步创建的 LV 上创建 ext4 文件系统。并将其挂载到一个空目录上。

    1
    2
    sudo mkfs.ext4 /dev/vg0/lv0
    sudo mount /dev/vg0/lv0 /mnt
  6. /home 中的所有文件复制或移动到挂载点上,注意保留权限等信息。完成后取消挂载。这一步和下一步可以在 LiveCD 中完成以避免运行中的程序对 /home 目录的影响。

    1
    2
    sudo cp -rp /home/* /mnt/
    sudo umount /mnt
  7. 将 LV 重新挂载到目标目录上,即 /home 。在 /etc/fstab 中配置自动挂载。通过 blkid 命令可找到 LV 的 UUID 等信息,配置自动挂载时可以通过 UUID 来识别 LV 。

    1
    2
    sudo mount /dev/vg0/lv0 /home
    sudo vim /etc/fstab

    image-20211030200812568

  8. 到这里便完成了 /home 目录向新硬盘上创建的 LV 的迁移。可以通过 df 命令检查分区的挂载情况,确认挂载是否成功。后续使用中可通过 LVM 快速进行大小的调整。

    image-20211030202030440

LVM动态添加磁盘

使用 LVM 技术后,可以方便地对各 LV 大小进行调整。在支持硬盘热插拔的环境中,可以在系统运行过程中加入新硬盘。二者结合即可无缝地对系统中的存储进行扩充。

下面实验了以热插拔方式加入新硬盘,并将硬盘容量加入 /dev/vg0/lv0 中,实现 /home 目录的扩容的过程。

其整体流程可概括为:插入硬盘、加入 VG 、LV扩容。实验中使用虚拟机进行模拟,通过虚拟机管理工具向运行中的 Ubuntu Server 虚拟机添加硬盘。系统中检测到硬盘后将硬盘处理为 PV 并加入 VG 。完成后对 LV 和其上的文件系统进行扩容。

详细步骤如下:

  1. 通过虚拟机管理工具向运行中的虚拟机添加硬盘。这里使用 Hyper-V 虚拟机平台进行实验。通过虚拟机的设置页即可添加新的虚拟硬盘。通过 lsblk 命令即可查看系统中的磁盘信息。

    image-20211030203828357

    图中展示了系统中磁盘情况的变化。在第一次查看磁盘信息时系统中共有两块虚拟磁盘。通过虚拟机管理工具添加新的硬盘驱动器后,可以发现第二次查看的磁盘信息显示已经添加了一块虚拟磁盘。

  2. 系统中发现新插入的硬盘后即可在磁盘上进行 PV 的创建工作。

    image-20211030204244582

  3. PV 创建完成后即可将其加入 VG 中。通过 vgextend 命令即可将 PV 加入现有的 VG 中实现对 VG 容量的扩充。

    image-20211030204522049

    图中展示了 VG 扩展的过程和扩展前后的情况,可以看到扩展后 VG 扩大了约 500GiB ,即证明新硬盘的容量已经加入到了 VG 中,可供 LV 使用。

  4. 通过 lvresize 命令对 LV 大小进行调整。调整完成后再使用 resizie2fs 命令将文件系统调整至 LV 大小即可。另外,lvresize 命令也提供了 --resizefs 参数在调整 LV 大小的同时调整文件系统大小。

    image-20211030205442501

  5. 到这里就完成了将动态加入系统的硬盘容量添加到 LV 的工作。通过 df 命令再次查看系统中挂载点的情况,与上一章对比可以发现容量已经发生了一些变化。其容量的变化情况与上面的命令中进行的调整有一些差距可能是由于单位的不一致,此处不进行深究。

    image-20211030205828075

参考资料

LVM (简体中文) - ArchWiki

Linux 下文件完全复制(属性不变)_iamplane的博客-CSDN博客_cp保留文件属性