Linux 基础学习训练教材 - RockyLinux 9.x

第 14 堂课:高端文件系统管理

文件系统是个迷人又磨人的东西~管理的好,你的系统会很稳定,管理不好,扩充容量又会产生大问题~加油吧!

最近更新时间: 2023/05/29

基础的文件系统管理中,通常一个 partition 只能作为一个 filesystem。但实际上,我们可以通过 RAID 的技术以及 LVM 的技术将不同的 partition/disk 集成成为一个大的文件系统,而这些文件系统又能具有硬件容错的功能在,对于关注保存设备物理安全性的管理员来说,这些技术相当的重要!

14.1:软件磁盘数组 (Software RAID)

数组 (RAID) 的目的主要在『加大磁盘容量』、『具有磁盘容错』、『增加读写性能』等方面,而根据你着重的面向就得要使用不同的磁盘数组等级了。

14.1.1:什么是 RAID

磁盘数组全名是『 Redundant Arrays of Independent Disks, RAID 』,英翻中的意思为:独立容错式磁盘数组,旧称为容错式廉价磁盘数组, 反正就称为磁盘数组即可!RAID 可以通过一个技术(软件或硬件),将多个较小的磁盘集成成为一个较大的磁盘设备; 而这个较大的磁盘功能可不止是保存而已,他还具有数据保护的功能。 整个 RAID 由于选择的等级 (level) 不同,而使得集成后的磁盘具有不同的功能,基本常见的 level 有这几种:

  • RAID-0 (等量模式, stripe, 性能最佳):两颗以上的磁盘组成 RAID-0 时,当有 100MB 的数据要写入,则会将该数据以固定的 chunk 拆解后, 分散写入到两颗磁盘,因此每颗磁盘只要负责 50MB 的容量读写而已。如果有 8 颗组成时,则每颗仅须写入 12.5MB ,速度会更快。此种磁盘数组性能最佳, 容量为所有磁盘的总和,但是不具容错功能。
  • RAID-1 (映射模式, mirror, 完整备份):大多为 2 的倍数所组成的磁盘数组等级。若有两颗磁盘组成 RAID-1 时,当有 100MB 的数据要写入, 每颗均会写入 100MB,两颗写入的数据一模一样 (磁盘映射 mirror 功能),因此被称为最完整备份的磁盘数组等级。但因为每颗磁盘均须写入完整的数据, 因此写入性能不会有明显的提升,但读取的性能会有进步。同时容错能力最佳,但总体容量会少一半。
  • RAID 1+0:此种模式至少需要 4 颗磁盘组成,先两两组成 RAID1,因此会有两组 RAID1,再将两组 RAID1 组成最后一组 RAID0,整体数据有点像底下的图标:
    图 14.1.1-1、RAID-1+0 的磁盘写入示意图
    图 14.1.1-1、RAID-1+0 的磁盘写入示意图
    因此性能会有提升,同时具备容错,虽然容量会少一半。
  • RAID 5, RAID 6 (性能与数据备份的均衡考量):RAID 5 至少需要 3 颗磁盘组成,在每一层的 chunk 当中,选择一个进行备份, 将备份的数据平均分散在每颗磁盘上,因此任何一颗磁盘损毁时,都能够重建出原本的磁盘数据,原理图标有点像底下这样:
    图 14.1.1-2、RAID-5 的磁盘写入示意图
    图 14.1.1-2、RAID-5 的磁盘写入示意图
    因为有一颗容量会用在备份上,因此总体容量少一颗,而为了计算备份的同位检查码 (partity),因此性能较难评估,原则上,性能比起单颗磁盘还是会稍微提升。 不过还是具备有容错功能,在越多颗磁盘组成时,比 RAID-1 要节省很多的容量。不过为了担心单颗备份还是不太足够,因此有 RAID 6 可以使用两个 partity 来备份, 因此会占用两颗容量就是了。
例题:尝试完成底下的表格
项目RAID0RAID1RAID10RAID5RAID6
最少磁盘数2
最大容错磁盘数(1)n-1
数据安全性(1)完全没有
理论写入性能(2)n1n/2<n-1<n-2
理论读出性能(2)nnn<n-1<n-2
可用容量(3)n1
一般应用强调性能但数据不重要的环境数据与备份服务器、云系统常用数据与备份数据与备份

而达成磁盘数组功能的,主要有硬件 RAID 与软件 RAID。

  • 硬件磁盘数组:中高端硬件 RAID 为独立的 RAID 芯片,内含 CPU 运算功能,可以运算类似 RAID 5/6 的 parity 数据,据以写入磁盘当中。 越高端的 RAID 还具有更多的缓存 (cache memory),可以加速读/写的性能。由于是硬件磁盘数组组成的『大容量磁盘』,因此 Linux 会将他视为一颗独立的物理磁盘,文件名通常就是 /dev/sd[abcd..]。
  • 软件磁盘数组:由操作系统提供仿真,通过 CPU 与 mdadm 软件仿真出中高端磁盘数组卡的功能,以达到磁盘数组所需要的性能、容错、容量增大的功能。 因为是操作系统仿真的,因此文件名会是 /dev/md[0123..]。这种作法很常见于 NAS 文件服务器环境中。
例题 14.1.1-1:
根据上述的内容,简易说明磁盘数组对于服务器的重要性在哪里?

14.1.2:Software RAID 的使用

Software RAID 主要通过 mdadm 这个软件的协助,因此需要先确认 mdadm 是否安装妥当。而 mdadm 的指令也相当简单,范例如下:

  • 创建磁盘数组
[root@localhost ~]# mdadm --create /dev/md[0-9] --auto=yes --level=[015] --chunk=NK \
> --raid-devices=N --spare-devices=N /dev/sdx 

--create          :为创建 RAID 的选项;
--auto=yes        :决定创建后面接的软件磁盘数组设备,亦即 /dev/md0, /dev/md1...
--level=[015]     :设置这组磁盘数组的等级。支持很多,不过建议只要用 0, 1, 5 即可
--chunk=Nk        :决定这个设备的 chunk 大小,也可以当成 stripe 大小,一般是 64K 或 512K。
--raid-devices=N  :使用几个磁盘 (partition) 作为磁盘数组的设备
--spare-devices=N :使用几个磁盘作为备用 (spare) 设备
例题 14.1.2-1:使用 mdadm 创建软件磁盘数组,缺省用到 5 个完全一样的分区来测试!
  1. 先检查 mdadm 是否存在于你的系统内?一般来说是存在的,若不存在,请自行安装。
  2. 进行磁盘分割,需要用到 5 个容量皆为 300M 的分区,注意 partition ID 喔!
  3. 使用底下的数据来创建好你的磁盘数组:
    • 创建的磁盘数组先使用 /dev/md0 作为设备的文件名 (这个设备文件名系统可能会自己调整)
    • 利用 4 个 partition 组成 RAID 5;
    • 利用 1 个 partition 设置为 spare disk
    • chunk 设置为 256K 这么大即可!
  4. 使用优化参数处理 XFS 文件系统格式化:
    • su 为指定 stripe 宽度,所以可以指定为 256K
    • sw 为指定多少个 stripe,因为 4 个组成 RAID5,所以只有提供 (4-1)=3 个数据,因此 sw 为 3 才对。
    • 格式化 mkfs.xfs 要带入上述参数才好
  5. 将此 RAID 5 设备挂载到 /srv/raid 目录下
  • 观察磁盘数组

磁盘数组建置妥当后,应该观察一下运作的状况比较妥当。主要的观察方式为:

[root@localhost ~]# mdadm --detail /dev/md[0-9]
[root@localhost ~]# cat /proc/mdstat

需要注意到是否有磁盘在损毁的状况才行。

  • 磁盘数组的救援功能

假设 (1)磁盘数组有某颗磁盘损毁了,或 (2)磁盘使用寿命也差不多,预计要整批换掉时,使用抽换的方式一颗一颗替换,如此则不用重新创建磁盘数组。

在此情况下,管理员应该要将磁盘数组设置为损毁,然后将之抽离后,换插新的硬盘才可以。基本的指令需求如下:

[root@localhost ~]# mdadm --manage /dev/md[0-9] [--add 设备] [--remove 设备] [--fail 设备] 

--add    :会将后面的设备加入到这个 md 中!
--remove :会将后面的设备由这个 md 中移除
--fail   :会将后面的设备设置成为出错的状态
例题 14.1.2-2: 练习将坏掉设备抽换的行为
  1. 先观察刚刚创建的磁盘数组是否正常运作,同时观察文件系统是否正常 (/srv/raid 是否可读写)
  2. 将某颗运作中的磁盘 (例如 /dev/vda7) 设置为错误 (--fail),再观察磁盘数组与文件系统
  3. 将错误的磁盘抽离 (--remove) 之后,假设修理完毕,再加入该磁盘数组 (--add),然后再次观察磁盘数组与文件系统

14.2:逻辑滚动条管理员 (Logical Volume Manager)

虽然 RAID 可以将文件系统容量增加,也有性能增加与容错的机制,但是就是没有办法在既有的文件系统架构下,直接将容量放大的机制。 此时,可以弹性放大与缩小的 LVM 辅助,就很有帮助了。不过 LVM 主要是在弹性的管理文件系统,不在于性能与容错上。 因此,若需要容错与性能,可以将 LVM 放置到 RAID 设备上即可。

14.2.1:LVM 基础: PV, PE, VG, LV 的意义

LVM 的全名是 Logical Volume Manager,中文可以翻译作逻辑滚动条管理员。之所以称为『滚动条』可能是因为可以将 filesystem 像滚动条一样伸长或缩短之故!LVM 的作法是将几个实体的 partitions (或 disk) 通过软件组合成为一块看起来是独立的大磁盘 (VG) , 然后将这块大磁盘再经过分割成为可使用分区 (LV), 最终就能够挂载使用了。

  • Physical Volume, PV, 实体滚动条:作为 LVM 最基础的物理滚动条,可以是 partition 也可以是整颗 disk。
  • Volume Group, VG, 滚动条群组:将许多的 PV 集成成为一个滚动条群组 (VG),这就是所谓的最大的主要大磁盘。 读者应该知道磁盘的最小保存单位为 sector,目前主流 sector 为 512bytes 或 4K。而 LVM 也有最小保存单位, 那就是 Physical Extent (PE),所有的数据都是通过 PE 在 VG 当中进行交换的。
  • Physical Extent, PE, 实体范围区块:PE 是整个 LVM 最小的保存区块,系统的文件数据都是借由写入 PE 来处理的。 简单的说,这个 PE 就有点像文件系统里面的 block 。PE 缺省需要是 2 的次方量,且最小为 4M 才行。
  • Logical Volume, LV, 逻辑滚动条:最终将 VG 再切割出类似 partition 的 LV 即是可使用的设备了。 LV 是借由『分配数个 PE 所组成的设备』,因此 LV 的容量与 PE 的容量大小有关。

上述谈到的数据,可使用下图来解释彼此的关系:

图 14.2.1-1、LVM 各组件的实现流程图标
图 14.2.1-1、LVM 各组件的实现流程图标
例题 14.2.1-1: 查阅 LVM 的 Systemid
使用 fdisk 指令查找一下,若需要将 partition 指定为 LVM 时,其 system ID (文件系统识别码) 应该指定为什么?

14.2.2:LVM 实做流程

如前一小节所述,管理员若想要处理 LVM 的功能,应该从 partition --> PV --> VG --> LV --> filesystem 的角度来处理。 请读者以底下的设置来实做出一组 LVM 来使用:

  • 使用 4 个 partition ,每个 partition 的容量均为 300MB 左右,且 system ID 需要为 8e;
  • 全部的 partition 集成成为一个 VG,VG 名称设置为 myvg ;且 PE 的大小为 16MB;
  • 创建一个名为 mylv 的 LV,容量大约设置为 500MB 左右
  • 最终这个 LV 格式化为 xfs 的文件系统,且挂载在 /srv/lvm 中

先使用 fdisk 分割出本案例所需要的 4 个分割,假设分割完成的磁盘文件名为 /dev/vda{9,10,11,12} 四个。 接下来即可使用 LVM 提供的指令来处理后续工作。一般来说, LVM 的三个阶段 (PV/VG/LV) 均可分为『创建』、『扫描』与『详细查阅』等步骤, 其相关指令可以汇整如下表:

任务PV 阶段VG 阶段LV 阶段filesystem
(XFS / EXT4)
搜索(scan)pvscanvgscanlvscanlsblk, blkid
创建(create)pvcreatevgcreatelvcreatemkfs.xfsmkfs.ext4
列出(display)pvdisplayvgdisplaylvdisplaydf, mount
增加(extend) vgextendlvextend (lvresize)xfs_growfsresize2fs
减少(reduce) vgreducelvreduce (lvresize)不支持resize2fs
删除(remove)pvremovevgremovelvremoveumount, 重新格式化
改变容量(resize)  lvresizexfs_growfsresize2fs
改变属性(attribute)pvchangevgchangelvchange/etc/fstab, remount
例题 14.2.2-1: 如上说明,请创建 4 个 300M 的分区喔!
  • PV 阶段

所有的 partition 或 disk 均需要做成 LVM 最底层的实体滚动条,直接使用 pvcreate /device/name 即可。实做完成后,记得使用 pvscan 查阅是否成功。

[root@localhost ~]# pvcreate /dev/vda{9,10,11,12}
[root@localhost ~]# pvscan
  PV /dev/vda3    VG rocky           lvm2 [20.00 GiB / 6.00 GiB free]
  PV /dev/vda9                       lvm2 [300.00 MiB]
  PV /dev/vda10                      lvm2 [300.00 MiB]
  PV /dev/vda11                      lvm2 [300.00 MiB]
  PV /dev/vda12                      lvm2 [300.00 MiB]
  Total: 5 [21.17 GiB] / in use: 1 [20.00 GiB] / in no VG: 4 [1.17 GiB]
  • VG 阶段

VG 比较需要注意的有三个项目:

  • VG 内的 PE 数值需要是 2 的倍数,如果没有设置,缺省会是 4MB
  • VG 需要给名字
  • 需要指定哪几个 PV 加入这个 VG 中。

根据上述的数据,使用 vgcreate --help 可以找到相对应的选项与参数,于是使用如下的指令来完成 VG 的任务:

[root@localhost ~]# vgcreate -s 16M myvg /dev/vda{9,10,11,12}
[root@localhost ~]# vgdisplay myvg
  --- Volume group ---
  VG Name               myvg
  System ID
  Format                lvm2
  Metadata Areas        4
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                4
  Act PV                4
  VG Size               1.12 GiB
  PE Size               16.00 MiB
  Total PE              72
  Alloc PE / Size       0 / 0
  Free  PE / Size       72 / 1.12 GiB
  VG UUID               oHncDF-aYkB-Qunj-E448-m9g1-n01H-aFnDWV
  • LV 阶段

LV 为实际被使用在文件系统内的设备,建置时需要考量的项目大概有:

  • 使用哪一个 VG 来进行 LV 的建置
  • 使用多大的容量或多少个 PE 来建置
  • 亦需要有 LV 的名字

同样使用 lvcreate --help 查阅,之后可以得到如下的选项与参数之设置:

[root@localhost ~]# lvcreate -n mylv -L 500M myvg
  Rounding up size to full physical extent 512.00 MiB
  Logical volume "mylv" created.

[root@localhost ~]# lvdisplay /dev/myvg/mylv
  --- Logical volume ---
  LV Path                /dev/myvg/mylv
  LV Name                mylv
  VG Name                myvg
  LV UUID                k3sqy3-11Je-sgss-RXhJ-b331-5yTt-viUUPL
  LV Write Access        read/write
  LV Creation host, time station200.rockylinux, 2023-05-28 21:55:52 +0800
  LV Status              available
  # open                 0
  LV Size                512.00 MiB
  Current LE             32
  Segments               2
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:3

由于实际创建的 LV 大小是由 PE 的数量来决定,因为本案例中使用 16MB 的 PE,因此不会刚好等于 500MB,故 LV 自动选择接近 500MB 的数值来创建, 因此上表中会得到使用 512MB 的容量。

另外,最终实际可用的 LV 设备名称为 /dev/myvg/mylv ,而因为 LVM 又是由 device mapper 的服务所管理的, 因此最终的名称也会指向到 /dev/mapper/myvg-mylv 当中。无论如何,读者仅需要记忆 /dev/myvg/mylv 这种格式的设备文件名即可。

例题 14.2.2-2: LVM 的文件系统建置与挂载
  1. 请将上述的 /dev/myvg/mylv 实际格式化为 xfs 文件系统,且此 fileysytem 可以开机后自动挂载于 /srv/lvm 目录下。
  2. 再创建一个名为 /dev/myvg/mylvm2 的 LV 设备,容量约为 300MB 左右,格式化为 ext4 文件系统,开机后自动挂载于 /srv/lvm2 目录下。

14.2.3:弹性化处理 LVM 文件系统

LVM 最重要的任务就是进行设备的容量放大与缩小,不过,前提是在该设备下的文件系统能够支持放大与缩小才行。 目前在 RockyLinux 9 上面主要的两款文件系统中, ext4 可以放大与缩小,但是 xfs 文件系统则仅能放大而已。因此使用上需要特别注意。

  • 将 myvg 所有剩余容量分配给 /dev/myvg/mylvm2

从上面的案例中,读者可以知道 myvg 这个 VG 的总容量 1.1G 当中,有 500M 给 /dev/myvg/mylv 而 300M 给 /dev/myvg/mylvm2, 因此剩下大约 300MB 左右,读者可以使用『 vgdisplay myvg 』来查找剩余的容量。若需要将文件系统放大,则需要进行:

  • 先将 mylvm2 放大
  • 再将上面的文件系统放大

上述两个步骤的顺序不可错乱。将 mylvm2 放大的方式为:

[root@localhost ~]# vgdisplay myvg
  --- Volume group ---
  VG Name               myvg
  System ID
  Format                lvm2
  Metadata Areas        4
  Metadata Sequence No  3
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                2
  Open LV               2
  Max PV                0
  Cur PV                4
  Act PV                4
  VG Size               1.12 GiB
  PE Size               16.00 MiB
  Total PE              72
  Alloc PE / Size       51 / 816.00 MiB
  Free  PE / Size       21 / 336.00 MiB
  VG UUID               oHncDF-aYkB-Qunj-E448-m9g1-n01H-aFnDWV

[root@localhost ~]# lvscan
  ACTIVE            '/dev/myvg/mylv' [512.00 MiB] inherit
  ACTIVE            '/dev/myvg/mylvm2' [304.00 MiB] inherit
  ACTIVE            '/dev/rocky/home' [3.00 GiB] inherit
  ACTIVE            '/dev/rocky/root' [10.00 GiB] inherit
  ACTIVE            '/dev/rocky/swap' [1.00 GiB] inherit

如上所示,读者可以发现剩余 21 个 PE,而目前 mylvm2 拥有 304MB 的容量。因此,我们可以使用:

  • 不考虑原本的,额外加上 21 个 PE 在 mylvm2 上面,或;
  • 原有的 304MB + 336MB 最终给予 640MB 的容量。

这两种方式都可以!主要都是通过 lvresize 这个指令来达成。要额外增加时,使用『 lvresize -l +21 ... 』的方式, 若要给予固定的容量,则使用『 lvresize -L 640M ... 』的方式,底下为额外增加容量的范例。

[root@localhost ~]# lvresize -l +21 /dev/myvg/mylvm2
  Size of logical volume myvg/mylvm2 changed from 304.00 MiB (19 extents) to 640.00 MiB (40 extents).
  Logical volume myvg/mylvm2 successfully resized.

[root@localhost ~]# lvscan
  ACTIVE            '/dev/myvg/mylv' [512.00 MiB] inherit
  ACTIVE            '/dev/myvg/mylvm2' [640.00 MiB] inherit
  ACTIVE            '/dev/rocky/home' [3.00 GiB] inherit
  ACTIVE            '/dev/rocky/root' [10.00 GiB] inherit
  ACTIVE            '/dev/rocky/swap' [1.00 GiB] inherit

完成了 LV 容量的增加,再来将文件系统放大。EXT 家族的文件系统通过 resize2fs 这个指令来完成文件系统的放大与缩小。

[root@localhost ~]# df -T /srv/lvm2
文件系统                类型 1K-区块  已用   可用 已用% 挂载点
/dev/mapper/myvg-mylvm2 ext4  281491    14 261817    1% /srv/lvm2

[root@localhost ~]# resize2fs /dev/myvg/mylvm2
resize2fs 1.46.5 (30-Dec-2021)
Filesystem at /dev/myvg/mylvm2 is mounted on /srv/lvm2; on-line resizing required
old_desc_blocks = 3, new_desc_blocks = 5
The filesystem on /dev/myvg/mylvm2 is now 655360 (1k) blocks long.

[root@localhost ~]# df -T /srv/lvm2
文件系统                类型 1K-区段  已用   可用 已用% 挂载点
/dev/mapper/myvg-mylvm2 ext4  603707    14 570273    1% /srv/lvm2
  • VG 的容量不足,可增加额外磁盘的方式

假设读者因为某些特殊需求,所以需要将 /dev/myvg/mylv 文件系统放大一倍,亦即再加 500MB 时,该如何处理?此时 myvg 已经没有剩余容量了。 此时可以通过额外给予磁盘的方式来增加。此案例也是最常见到的情况,亦即在原有的文件系统当中已无容量可用,所以管理员需要额外加入新购置的磁盘的手段。 假设管理员已经通过 fdisk /dev/vda 添加一个 /dev/vda13 的 500MB 分区,此时可以这样做:

[root@localhost ~]# fdisk /dev/vda
......
命令 (m 以获得说明):n
分割区编号 (13-128, default 13):
First sector (51681280-62914526, default 51681280):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (51681280-62914526, default 62914526): +500M

命令 (m 以获得说明):t
分割区编号 (1-13, default 13):
Partition type or alias (type L to list all): 30

命令 (m 以获得说明):p
.....
所用设备      Start     结束     磁区  Size 类型
.....
/dev/vda13 51681280 52705279  1024000  500M Linux LVM

命令 (m 以获得说明):w
The partition table has been altered.
Syncing disks.

[root@localhost ~]# lsblk -i
NAME            MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINTS
vda             252:0    0   30G  0 disk
|-vda9          252:9    0  300M  0 part
| `-myvg-mylv   253:3    0  512M  0 lvm   /srv/lvm
|-vda10         252:10   0  300M  0 part
| |-myvg-mylv   253:3    0  512M  0 lvm   /srv/lvm
| `-myvg-mylvm2 253:4    0  640M  0 lvm   /srv/lvm2
|-vda11         252:11   0  300M  0 part
| `-myvg-mylvm2 253:4    0  640M  0 lvm   /srv/lvm2
|-vda12         252:12   0  300M  0 part
| `-myvg-mylvm2 253:4    0  640M  0 lvm   /srv/lvm2
`-vda13         252:13   0  500M  0 part  <==刚刚管理员添加的部份

[root@localhost ~]# pvcreate /dev/vda13
  Physical volume "/dev/vda13" successfully created

[root@localhost ~]# vgextend myvg /dev/vda13
  Volume group "myvg" successfully extended

[root@localhost ~]# vgdisplay myvg
  --- Volume group ---
  VG Name               myvg
  System ID
  Format                lvm2
  Metadata Areas        5
  Metadata Sequence No  5
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                2
  Open LV               2
  Max PV                0
  Cur PV                5
  Act PV                5
  VG Size               <1.61 GiB
  PE Size               16.00 MiB
  Total PE              103
  Alloc PE / Size       72 / 1.12 GiB
  Free  PE / Size       31 / 496.00 MiB
  VG UUID               oHncDF-aYkB-Qunj-E448-m9g1-n01H-aFnDWV

此时系统即可多出将近 500MB 的容量给 myvg。

例题 14.2.3-1:
  1. 请将 myvg 的所有剩余的容量分配给 /dev/myvg/mylv
  2. 通过 xfs_growfs 来放大 /dev/myvg/mylv 这个文件系统 (请自行 man xfs_growfs)
  3. 你目前的系统中,根目录所在 filesystem 能否放大加入额外的 2GB 容量?若可以,请实做,若不行,请说明原因。

14.3:Software RAID 与 LVM 综合管理

RAID 主要的目的在性能与容错 (容量只是附加的),而 LVM 重点在弹性管理文件系统 (最好不要考量 LVM 内置的容错机制)。 若需要两者的优点,则可以在 RAID 上面建置 LVM。但以目前管理员的测试机而言,建议先关闭原有的测试流程,然后再重新创建为宜。

14.3.1:关闭与取消 software RAID 与 LVM 的方式

在本练习册中,我们并没有给予 RAID 的设置档,因此删除掉分区后,系统应该会自动舍弃 software RAID (/dev/md0)。 不过,如果没有将每个分区的档头数据删除,那未来重新开机时, mdadm 还是会尝试抓取 /dev/md0,这将造成些许困扰。 因此,建议删除掉 software RAID 的手段如下:

  1. 先将 /etc/fstab 当中,关于 /dev/md0 的纪录删除或注解;
  2. 将 /dev/md0 完整的卸载
  3. 使用 mdadm --stop /dev/md0 将 md0 停止使用
  4. 使用 dd if=/dev/zero of=/dev/vda4 bs=1M count=10 强制删除掉每个 partition 前面的 software RAID 标记
  5. 重复前一个步骤,将其他的 /dev/vda{5,6,7,8} 通通删除标记
例题 14.3.1-1: 将 software raid 取消:
  1. 将 /dev/md0 卸载,并且停止使用
  2. 将 /dev/vda{4,5,6,7,8} 这几个设备的表头数据 (有点类似 superblock) 删除
  3. 将这 5 个 partition 删除

LVM 的管理是很严格的,因此管理员不可在 LVM 活动中的情况下删除掉任何一个属于 LVM 的 partition/disk 才对。 例如目前 /dev/vda{9,10,11,12,13} 属于 myvg 这个 VG,因此如果 myvg 没有停止,那么管理员不应该也尽量避免更动到上述的分区。 若需要停止与回收这个 VG 的分区,应该要这样处理。

  1. 先将 /etc/fstab 当中与 myvg 有关的项目删除或注解
  2. 将 myvg 有关的文件系统卸载 (本案例中为 /srv/lvm 与 /srv/lvm2)
  3. 使用 vgchange -a n myvg 将此 VG 禁用
  4. 使用 lvscan 确认一下 myvg 所属的所有 LV 是否已经禁用 (inactive)
  5. 使用 vgremove myvg 移除掉 myvg 这个 VG 的所有内容
  6. 使用 pvremove /dev/vda{9,10,11,12,13} 移除这些 PV
  7. 最终使用 pvscan 侦测是否顺利移除
例题 14.3.1-2:删除 LVM 的方法
  1. 卸载所有与 /dev/myvg/mylv, /dev/myvg/mylvm2 的设备,并将 myvg 设置为禁用
  2. 移除 myvg
  3. 移除 /dev/vda{9,10,11,12,13} 这几个 PV
  4. 将上述的 partition 删除

14.3.2:在 Software RAID 上面建置 LVM

我们现在的练习机上面,还没有分割的容量应该有 8G 才对。现在,请以 1.5G (1500M) 为单位,切割出 5 个分区, 分割完毕之后,就假设有 5 颗磁盘的意思。将这五颗磁盘汇整成为一个软件磁盘数组,名称就为 /dev/md0,使用 raid 5,且没有 spare disk。 然后将整个 /dev/md0 制作成为一个 PV,然后创建名为 raidvg 的 VG 以及 raidlv 的 LV。 最终这个 LV 应该会有 6G 左右的容量才对喔 ( 1.5G * (5-1) = 6G )

例题 14.3.2-1:创建 5 个 1500MB 的分区,用于 software raid 之用,最后一个剩下大约 500M 的分割同样创建起来,使用缺省的 system id 即可。

完成基础分割以创建假想的 5 颗实际不同的磁盘后,再来组成磁盘数组才会有意义!然后开始处理软件磁盘数组与 LVM 吧!

实际练习:处理 RAID 上面的 LVM 流程:
  1. 创建 RAID 5 的软件磁盘数组,使用到全部的 5 颗分区:
    [root@localhost ~]# mdadm --create /dev/md0 --level=5 --raid-devices=5 --chunk=256K /dev/vda{4..8}
    mdadm: Defaulting to version 1.2 metadata
    mdadm: array /dev/md0 started.
    
    [root@localhost ~]# cat /proc/mdstat
    Personalities : [raid6] [raid5] [raid4]
    md0 : active raid5 vda8[5] vda7[3] vda6[2] vda5[1] vda4[0]
          6283264 blocks super 1.2 level 5, 256k chunk, algorithm 2 [5/4] [UUUU_]
          [=======>.............]  recovery = 35.1% (552832/1570816) finish=0.3min speed=55283K/sec
    
    [root@localhost ~]# mdadm --detail /dev/md0
    /dev/md0:
               Version : 1.2
         Creation Time : Sun May 28 22:46:00 2023
            Raid Level : raid5
            Array Size : 6283264 (5.99 GiB 6.43 GB)
         Used Dev Size : 1570816 (1534.00 MiB 1608.52 MB)
          Raid Devices : 5
         Total Devices : 5
           Persistence : Superblock is persistent
    
           Update Time : Sun May 28 22:46:32 2023
                 State : clean
        Active Devices : 5
       Working Devices : 5
        Failed Devices : 0
         Spare Devices : 0
    
                Layout : left-symmetric
            Chunk Size : 256K
    
    Consistency Policy : resync
    
                  Name : station200.rockylinux:0  (local to host station200.rockylinux)
                  UUID : 5003361e:f8f69aaf:895d6269:ae11a577
                Events : 18
    
        Number   Major   Minor   RaidDevice State
           0     252        4        0      active sync   /dev/vda4
           1     252        5        1      active sync   /dev/vda5
           2     252        6        2      active sync   /dev/vda6
           3     252        7        3      active sync   /dev/vda7
           5     252        8        4      active sync   /dev/vda8
    
  2. 创建 PV 以及创建 raidvg 的流程:
    [root@localhost ~]# pvcreate /dev/md0
      Physical volume "/dev/md0" successfully created.
    
    [root@localhost ~]# vgcreate raidvg /dev/md0
      Volume group "raidvg" successfully created
    
    [root@localhost ~]# vgdisplay raidvg
      --- Volume group ---
      VG Name               raidvg
      System ID
      Format                lvm2
      Metadata Areas        1
      Metadata Sequence No  1
      VG Access             read/write
      VG Status             resizable
      MAX LV                0
      Cur LV                0
      Open LV               0
      Max PV                0
      Cur PV                1
      Act PV                1
      VG Size               <5.99 GiB
      PE Size               4.00 MiB
      Total PE              1533
      Alloc PE / Size       0 / 0
      Free  PE / Size       1533 / <5.99 GiB
      VG UUID               P01WGp-vYzi-QVM0-zolR-UGa6-uK4M-FLS14g
    
  3. 最终创建需要的 /dev/raidvg/raidlv 设备
    [root@localhost ~]# lvcreate -l 1533 -n raidlv raidvg
    [root@localhost ~]# lvscan
      ACTIVE            '/dev/rocky/home' [3.00 GiB] inherit
      ACTIVE            '/dev/rocky/root' [12.00 GiB] inherit
      ACTIVE            '/dev/rocky/swap' [1.00 GiB] inherit
      ACTIVE            '/dev/raidvg/raidlv' [<5.99 GiB] inherit
    
    [root@localhost ~]# lvdisplay /dev/raidvg/raidlv
      --- Logical volume ---
      LV Path                /dev/raidvg/raidlv
      LV Name                raidlv
      VG Name                raidvg
      LV UUID                4WYbOt-9peY-XaLS-rmrS-0Rdf-pJJv-csdKQL
      LV Write Access        read/write
      LV Creation host, time station200.rockylinux, 2023-05-28 22:49:01 +0800
      LV Status              available
      # open                 0
      LV Size                <5.99 GiB
      Current LE             1533
      Segments               1
      Allocation             inherit
      Read ahead sectors     auto
      - currently set to     4096
      Block device           253:3
    

这样就完成了在 RAID 上面创建 LVM 的功能了!这个 LVM 暂时不要使用他,我们在下个小节来玩一些比较有趣的项目!

14.4:特殊的文件系统处理模式

近年来包括自动化布署、虚拟机的盛行等,传统的文件系统容量再大,也无法持续提供大量的本地端容量,即使已经使用了 LVM。 因此,就有很多计划在处理磁盘与文件系统对应的机制,其中两个很有趣的计划,一个是 Stratis ,另一个则是 VDO 机制, 这两个东西都可以仔细瞧瞧,挺有趣的!

14.4.1:使用 stratis 滚动条管理文件系统 (VMF)

目前的本地端保存设备与文件系统的应用中,包括了 device mapper (dm), LVM, RAID, Multipath, XFS 等等机制, 这些机制各有各的好处。不过,还是经常需要进行文件系统分割、格式化等行为。为了方便用户的应用,于是有了 stratis 这个机制的产生。

Stratis 通过滚动条管理文件系统的概念 (volume managing filesystem, VMF) ,简单的将整个设备、文件系统分为几个小阶层,有点类似底下的图标:

图 14.4.1-1、 Stratis 分层的示意图 (图标来源请参考文末参考数据)
图 14.4.1-1、 Stratis 分层的示意图 (图标来源请参考文末参考数据)

简单的来说,可以简化为底下的样式:

图 14.4.1-2、 Stratis 分层的示意图 (图标来源请参考文末参考数据)
图 14.4.1-2、 Stratis 分层的示意图 (图标来源请参考文末参考数据)
  • blockdev: 区块设备,除了磁盘之外,也可以是 LVM 喔!
  • pool: 保存池,可以自由配置设备与文件系统,是一个很抽象的管理层
  • filesystem: 文件系统,可以直接丢给系统使用于文件管理!

简单的来说,stratis 大致应用了目前的 LVM 与 XFS 机制,stratis 提供了一个名为保存池 (pool) 的概念,其实就有点类似 LVM 里面的 VG 的概念, 然后,你可以简单的将任何的区块设备 (传统磁盘、SSD、插卡式磁盘、iSCSI、LVM等) 加入这个保存池,然后在直接挂载到目录树底下, 就可以直接应用了。此外,由于挂载时的文件系统是在用户层,因此,可以随便你设置容量为多少,即使该容量目前并不存在这么大。

  • stratis 的管理:通过 stratisd 服务

要达成 stratis 的功能,你的系统得要安装 stratisd 服务才行。同时,如果想要管理 stratisd 的话,就得要安装 stratis-cli 软件才行! 先来安装软件后,启动该项目吧:

[root@localhost ~]# yum install stratisd stratis-cli
[root@localhost ~]# systemctl start stratisd
[root@localhost ~]# systemctl enable stratisd

简单的依据『安装』、『启动』、『开机启动』的口诀来处理即可!不过因为 stratis 并不是网络服务,而是本机的保存系统, 因此不需要防火墙啰!很快速的就处理好 stratisd 服务。

  • 创建观察保存池: 通过 stratis 指令处理

服务启动之后,接下来就可以直接创建保存池 (pool) 与设备 (blockdev) 之间的关系!我们在之前的练习里面, 创建过 /dev/raidvg/raidlv 与 /dev/vda9 这两个剩余的设备,现在,先将 raidlv 加入到名为 vbirdpool 的保存池去, 看看情况会如何。记得,我们先使用 stratis [tab][tab] 看看有什么选项可以利用喔!

[root@localhost ~]# stratis --help
usage: stratis [-h] [--version] [--propagate] [--unhyphenated-uuids] \
  {pool,blockdev,filesystem,fs,report,key,debug,daemon} ...

Stratis Storage Manager

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --propagate           Allow exceptions to propagate
  --unhyphenated-uuids  Display UUIDs in unhyphenated format

subcommands:
  {pool,blockdev,filesystem,fs,report,key,debug,daemon}
    pool                Perform General Pool Actions
    blockdev            Commands related to block devices that make up the pool
    filesystem (fs)     Commands related to filesystems allocated from a pool
    report              Commands related to reports of the daemon state
    key                 Commands related to key operations for encrypted pools
    debug               Commands for debugging operations.
    daemon              Stratis daemon information

很明显的看到了 blockdev, filesystem, pool 这三个关键字!所以,想要创建保存池的话,当然就使用 pool 这个指令即可!

[root@localhost ~]# stratis pool create vbirdpool /dev/raidvg/raidlv
[root@localhost ~]# stratis pool list
Name                     Total / Used / Free    Properties                                   UUID   Alerts
vbirdpool   5.99 GiB / 525.31 MiB / 5.48 GiB   ~Ca,~Cr, Op   e9d1df7a-d93e-4409-a3d8-d7a144872452   WS001
# 所以有个 vbirdpool 的保存池,里面实际有 5.99G,用掉了 525M 容量了。

[root@localhost ~]# stratis blockdev list
Pool Name   Device Node   Physical Size   Tier
vbirdpool   /dev/dm-3          5.99 GiB   DATA
# 所有 vbirdpool 实际上用到 /dev/dm-3 这个设备,且用于数据保存 (Data)

stratis 比较特别的地方是,我们可以持续加进 blockdev 设备,不过无法移出 blockdev!希望未来可以提供移除 blockdev 的功能。 那加入的 block 设备有什么限制呢?让我们将不到 1G 的 /dev/vda9 丢进去 vbirdpool 看看就知道了:

[root@localhost ~]# stratis pool add-data vbirdpool /dev/vda9
Execution failed:
stratisd failed to perform the operation that you requested. It returned the following 
  information via the D-Bus: ERROR: At least one of the devices specified was unsuitable 
  for initialization: Device /dev/vda9 is 529513984 bytes which is smaller than the 
  minimum required size for a Stratis blockdev, 1073741824 bytes.

因为我们的练习机文件容量较小,所以 /dev/vda9 不够大于 1G 以上,导致增加失败!由错误消息就能知道, stratis 的限制就是需要大于 1G 以上的区块设备, 才能够加入到我们的保存池喔!那怎么练习加入额外的设备呢?没关系,我们还有个 rocky 的 VG 可以使用! 现在让我们创建 /dev/rocky/lvm 这个 1.5G 的设备,然后再加入 vbirdpool 一下!

[root@localhost ~]# lvcreate -L 1.5G -n lvm rocky
[root@localhost ~]# lvscan
  ACTIVE            '/dev/rocky/home' [3.00 GiB] inherit
  ACTIVE            '/dev/rocky/root' [12.00 GiB] inherit
  ACTIVE            '/dev/rocky/swap' [1.00 GiB] inherit
  ACTIVE            '/dev/rocky/lvm' [1.50 GiB] inherit
  ACTIVE            '/dev/raidvg/raidlv' [<5.99 GiB] inherit

[root@localhost ~]# stratis pool add-data vbirdpool /dev/rocky/lvm
[root@localhost ~]# stratis pool list
Name                     Total / Used / Free    Properties                                   UUID   Alerts
vbirdpool   7.49 GiB / 530.06 MiB / 6.97 GiB   ~Ca,~Cr, Op   e9d1df7a-d93e-4409-a3d8-d7a144872452

[root@localhost ~]# stratis blockdev list
Pool Name   Device Node   Physical Size   Tier
vbirdpool   /dev/dm-3          5.99 GiB   DATA
vbirdpool   /dev/dm-9          1.50 GiB   DATA

你会发现到 Tier 这个地方,这里很有趣喔!基本上 Tier 大致上有两种情境,一个是用于传统数据存放,就是『 Data 』的效果, 如果你有比较快速、较小的 SSD / NVMe 等设备,可以将他设置为缓存 (cache) 喔!如此一来,你甚至可能会有好几个 T 的缓存! 而且不用任何奇怪的设置,直接加入成为缓存即可!相当有趣吧!底下为练习机不存在的指令,看看就好:

# 假设 /dev/vdc 为 SSD,可加入成为缓存的功能为:
[root@localhost ~]# stratis pool add-cache vbirdpool /dev/vdc
# 因为系统不存在 /dev/vdc 啦!这里单纯给大家瞧瞧!
  • 创建观察与挂载文件系统: 通过 stratis 指令处理

所有以 stratisd 创建的文件系统,其设备文件名缺省都会以底下的方式存在:

  • 说明:/dev/stratis/保存池名称/文件系统名称
  • 范例:/dev/stratis/vbirdpool/fs1

如上,我们先设置一个 fs1 的文件系统来使用看看:

[root@localhost ~]# stratis filesystem create vbirdpool fs1
[root@localhost ~]# stratis filesystem list
Pool        Filesystem   Total / Used / Free             Created             Device                       UUID
vbirdpool   fs1          1 TiB / 545 MiB / 1023.47 GiB   May 28 2023 23:01   /dev/stratis/vbirdpool/fs1   b56bab2e-e6cd-4200-b13b-44e676d6fbdd

这时设备名称就创建起来了!你可以很明显的看到该设备!只是,建议不要使用设备来进行挂载,如果需要挂载, 就用 UUID 吧!查找 UUID 的方法可以这样做:

[root@localhost ~]# blkid /dev/stratis/vbirdpool/*
/dev/stratis/vbirdpool/fs1: UUID="b56bab2e-e6cd-4200-b13b-44e676d6fbdd" TYPE="xfs"

[root@localhost ~]# mkdir /srv/pool1
[root@localhost ~]# mount UUID="b56bab2e-e6cd-4200-b13b-44e676d6fbdd" /srv/pool1
[root@localhost ~]# df -Th /srv/pool1
文件系统                  ..... 类型  容量  已用  可用 已用% 挂载点
/dev/mapper/stratis-1-e9d1..... xfs   1.0T  7.2G 1017G    1% /srv/pool1

这样就可以挂载使用了!不过要注意的是,使用 df 去显示时,文件容量会显示为 1TB,那个是错误的显示容量! 略过不要理会!要查阅时,请使用『 stratis filesystem list 』去查看才是对的!

  • 开机就挂载的方式

虽然 stratis 的文件系统可以直接将挂载项目写入到 /etc/fstab 里面,不过要注意的是,这些文件系统毕竟是经由 stratisd 管理的, 但是本机文件系统的挂载其实是在启动 stratisd 之前,因此如果没有加上特别的注意,该挂载在开机过程当中是会失败的! 特别留意这个问题!

实际练习:让刚刚创建的 stratis 文件系统于开机时挂载:
  1. 编辑 /etc/fstab,加入底下这一行:
    UUID="7430f67c-671e-4c5c-9e98-a77ccbbc8574" /srv/pool1 xfs defaults,x-systemd.requires=stratisd.service 0 0
    
  2. 卸载既有的挂载后, mount -a 测试,测试成功之后,记得 reboot 看看有没有生效!
    [root@localhost ~]# umount /srv/pool1
    [root@localhost ~]# mount -a
    [root@localhost ~]# reboot
    
  • 移除 stratis 的方法

要移除 stratis 的话,就跟移除一般文件系统类似,从 /etc/fstab 的编辑以及卸载后,再以 stratis 删除掉文件系统与保存池即可。

实际练习:取消 stratis 的使用
  1. 将 /etc/fstab 添加那一行删除或注解:
  2. 将挂载于 /srv/pool1 的设备卸载
  3. 开始删除 fs1
  4. 开始删除 vbirdpool
  5. 停止 stratisd 服务
[root@localhost ~]# vim /etc/fstab
#UUID="7430f67c-671e-4c5c-9e98-a77ccbbc8574" /srv/pool1 xfs defaults,x-systemd.requires=stratisd.service 0 0

[root@localhost ~]# umount /srv/pool1
[root@localhost ~]# stratis filesystem destroy vbirdpool fs1
[root@localhost ~]# stratis pool destroy vbirdpool
[root@localhost ~]# systemctl stop stratisd.service
[root@localhost ~]# systemctl disable stratisd.service

14.4.2:使用于虚拟机磁盘应用的 VDO 机制

身为现代人,你应该、绝对听过所谓的虚拟化,我们现在上课使用的系统就是虚拟机啊!使用到虚拟机的原因,当然是由于硬件资源大幅提升的缘故, 因此一部主机可以做成虚拟机的本机 (host),然后再将资源如 CPU、内存、磁盘、网络等分享给虚拟机 (VM) 使用, 最后在 VM 上面安装好操作系统 (guest) 之后,就可以提供给客户进行操作了。

许多硬件资源都可以通过共享。如 4 核 8 绪的主机,可以提供给 8 台 2 内核的虚拟机(VM),虚拟机的总 CPU 个数(16)超出实体 CPU(4), 也是没问题的!所有的虚拟机可以轮流共用实体CPU内核。同理,内存也一样,甚至如果具有相同内容的VM群,其共有的记忆资源还能仅保留共有的一份。

不过虚拟机的磁盘怎么来?一般来说,虚拟机的磁盘大多使用大型文件来提供,当然也能使用 LVM!不过,当 VM 的量很大的时候, 使用大型文件并通过快照拷贝的效果,会比较好一些,不用通过持续的 device mapper (dm) 去管理,耗用的资源较少。 只是,你得要自己手动进行快照、自己进行压缩与各项系统处置,管理方面比较不方便。

虚拟数据优化系统 (Virtual Data Optimizer, VOD) 就是为了处理虚拟机的磁盘设备而设计的!VDO可以让你的数据直接在VDO的挂载点里面, 直接通过VDO系统的管理,自己进行数据同步、数据压缩。此外,你的1TB实体磁盘,也能通过VDO的功能,假装成为5TB的容量, 因为VDO会进行压缩等行为,也就让你的系统可以进行更多文件的保存!

不过,从 RHEL 9 以后,VDO 支持 LVM 了,因此,要使用 VDO 的话,得要通过 LVM 的相关 lvcreate 来创建才行喔! 相关的 VDO 搭配 LVM 的示意图,如下所示:

图 14.4.2-1、 VDO 的用途示意 (图标来源请参考文末参考数据)
图 14.4.2-1、 VDO 的用途示意 (图标来源请参考文末参考数据)
  • VDO 的组件与使用

VDO 的使用需要通过 vdo 以及 kmod-kvdo 模块的支持,因此得要安装这两个软件才行。由于 vdo 在 RockyLinux 9 底下是通过 LVM 支持, 因此,不需要启动任何服务喔!

[root@localhost ~]# yum install vdo kmod-kvdo lvm2

接下来我们就可以通过 lvm 来处理 vdo 了!不过,我们得要将刚刚创建的 /dev/raidvg/raidlv 删除并且重新创建成为 vdo 支持的样式才行!基本上,使用的状态就跟 lvm 没两样~现在,我们将 raidvg 的所有容量都给 raidlv, 同时假装该磁盘容量具有 10G 的容量效果,可以这样做看看:

[root@localhost ~]# lvremove /dev/raidvg/raidlv
Do you really want to remove active logical volume raidvg/raidlv? [y/n]: y
  Logical volume "raidlv" successfully removed.

[root@localhost ~]# lvcreate --help
.....
  Create a LV that returns VDO when used.
  lvcreate --type vdo -L|--size Size[m|UNIT] VG
        [ -l|--extents Number[PERCENT] ]
        [ -i|--stripes Number ]
        [ -I|--stripesize Size[k|UNIT] ]
        [ -V|--virtualsize Size[m|UNIT] ]
        [    --vdo ]
        [    --vdopool LV_new ]
        [    --compression y|n ]
        [    --deduplication y|n ]
        [    --vdosettings String ]
        [ COMMON_OPTIONS ]
        [ PV ... ]
.....

[root@localhost ~]# lvcreate -l 1533 --vdo --name vdolv --compression y --deduplication y --virtualsize 10G raidvg
[root@localhost ~]# lvscan
  ACTIVE            '/dev/rocky/home' [3.00 GiB] inherit
  ACTIVE            '/dev/rocky/root' [12.00 GiB] inherit
  ACTIVE            '/dev/rocky/swap' [1.00 GiB] inherit
  ACTIVE            '/dev/rocky/lvm' [1.50 GiB] inherit
  inactive          '/dev/raidvg/vpool0' [<5.99 GiB] inherit
  ACTIVE            '/dev/raidvg/vdolv' [10.00 GiB] inherit

[root@localhost ~]# vdostats --human-readable
Device                   Size      Used Available Use% Space saving%
raidvg-vpool0-vpool      6.0G      4.0G      2.0G  67%            0%

因为 VDO 会进行许多的动作,因此一开始就会花费 4G 的容量,剩余的容量可能只剩下 2G 而已!因此,要使用 VDO 时, 设备的容量还是大一些比较妥当。我们这里只进行测试啦!接下来,请将这个设备挂载使用吧。

实际练习:将 /dev/raidvg/vdolv 格式化为 xfs 文件系统,挂载到 /srv/vdo 目录下,并且开机自动挂载
  1. 开始格式化:
    [root@localhost ~]# mkfs.xfs /dev/raidvg/vdolv
    
    [root@localhost ~]# vdostats --human-readable
    Device                   Size      Used Available Use% Space saving%
    raidvg-vpool0-vpool      6.0G      4.0G      2.0G  67%           99%
    
  2. 开始测试挂载
    [root@localhost ~]# vim /etc/fstab
    /dev/raidvg/vdolv /srv/vdo xfs defaults 0 0
    
    [root@localhost ~]# mkdir /srv/vdo
    [root@localhost ~]# mount -a
    [root@localhost ~]# df -Th /srv/vdo
    文件系统                 类型  容量  已用  可用 已用% 挂载点
    /dev/mapper/raidvg-vdolv xfs    10G  104M  9.9G    2% /srv/vdo
    
    [root@localhost ~]# reboot
    

建置完毕之后,建议立刻 reboot 测试一下 /etc/fstab 里面的设置是否为正常喔!

  • VDO 文件运作的三个阶段

VDO 在进行文件的处理时,主要会有三个阶段 ( 3 phases ),流程如下:

  1. 暂存阶段 (zero-block elimination):一开始进行类似拷贝的行为时, VDO 会依据文件的内容,先占用一个不存在的容量, 只是先处理中介数据 (metadata) 的写入,有点类似只写入 super block 信息而已的概念。 让系统以为确实存在该文件,但事实上,该文件并没有完全写入,甚至可能不用写入! 数据是否写入到实际的文件系统中,得要看下个阶段的结果而定。
  2. 重复性数据测试阶段 (deduplication elimination):VDO 会分析要写入的这个文件的特性与内容,当 VDO 发现到这个文件已经存在系统中, 那么该数据就不会实际写入到文件系统,而是通过一个『指向 (point) 』的方式,以类似快照的模式来创建该文件,因此同一个文件拷贝多个备份时, 其实只有第一个创建的文件才会实际存在,其他的备份都是通过链接到第一个文件去的方式来处理的。
  3. 压缩阶段 (compression):最终 VDO 通过 LZ4 这个压缩机制以 4KB 区块大小的形式来进行压缩,让文件容量可以降低到更小。

大家要先有个概念,VDO 的重点在于使用于虚拟机中,虚拟机通常使用大型文件作为虚拟机里面的磁盘系统,所以,丢进 VDO 管理的文件系统内的数据, 不应该是一般的文件,而是作为虚拟磁盘的文件才对!虽然 RHEL 9 以后的 VDO 使用具有多种功能,不过基础应用应该还是在虚拟机的磁盘文件上才是。 所以,我们得要先来制作虚拟磁盘机的文件才行!如下所示,我们先来创建一个大型的文件 (虽然不是专门用来进行磁盘系统的)。

[root@localhost ~]# df -Th /
文件系统               类型  容量  已用  可用 已用% 挂载点
/dev/mapper/rocky-root xfs    12G  6.0G  6.1G   50% /

[root@localhost ~]# tar -cf /vmdisk.img /etc /home /root
[root@localhost ~]# ll -h /vmdisk.img
-rw-r--r--. 1 root root 477M  5月 29 09:40 /vmdisk.img

这样就有一个没有压缩的超过数百 MB 以上的大型文件!开始进行拷贝的举动,将这个文件拷贝到 /srv/vdo 目录去:

[root@localhost ~]# vdostats --human-readable
Device                   Size      Used Available Use% Space saving%
raidvg-vpool0-vpool      6.0G      4.0G      2.0G  67%           98%

[root@localhost ~]# cp /vmdisk.img /srv/vdo
[root@localhost ~]# vdostats --human-readable
Device                   Size      Used Available Use% Space saving%
raidvg-vpool0-vpool      6.0G      4.3G      1.7G  72%           36%

[root@localhost ~]# cp /vmdisk.img /srv/vdo/vmdisk2.img
[root@localhost ~]# vdostats --human-readable
Device                   Size      Used Available Use% Space saving%
raidvg-vpool0-vpool      6.0G      4.3G      1.7G  72%           68%

[root@localhost ~]# cp /vmdisk.img /srv/vdo/vmdisk3.img
[root@localhost ~]# cp /vmdisk.img /srv/vdo/vmdisk4.img
[root@localhost ~]# vdostats --human-readable
Device                   Size      Used Available Use% Space saving%
raidvg-vpool0-vpool      6.0G      4.3G      1.7G  72%           83%

[root@localhost ~]# df -Th /srv/vdo
文件系统                 类型  容量  已用  可用 已用% 挂载点
/dev/mapper/raidvg-vdolv xfs    10G  2.0G  8.1G   20% /srv/vdo

你可以发现,虽然单一文件有数百 MB 的容量,但是整体 VDO 还是只有第一次拷贝时有消耗容量而已, 使用传统文件系统的 df 来看,却已经使用掉 2G 了!这就可以节省非常多的容量喔!而且你不用自己做快照!

14.5:简易磁盘配额 (Quota)

Filesystem Quota 可以使用于『公平的』使用文件系统。虽然现今磁盘容量越来越大,但是在某些特别的情境中,为了管制用户乱用文件系统, 还是有必要管理一下 quota 用量的。

14.5.1:Quota 的管理与限制

基本上,要能使用 Quota ,你需要有底下的支持:

  • Linux 内核支持:除非你自己编译内核,又不小心取消,否则目前缺省内核都有支持 Quota 的
  • 激活文件系统支持:虽然 EXT 家族与 XFS 文件系统均支持 Quota ,但是你还是得要在挂载时激活支持才行。

而一般 Quota 针对的管理对象是:

  • 可针对用户 (但不包含 root)
  • 可针对群组
  • EXT家族仅可针对整个文件系统,XFS可以针对某个目录进行 Quota 管理

那可以限制的文件系统数据是:

  • 可限制文件容量,其实就是针对 Filesystem 的 block 做限制
  • 可限制文件数量,其实就是针对 Filesystem 的 inode 做限制 (一个文件会占用 1 个 inode 之故)

至于限制的数值与数据,又可以分为底下几个:

  • Soft 限制值:仅为软性限制,可以突破该限制值,但超过 soft 数值后,就会产生『宽限时间 (grace time)』
  • Hard 限制值:就是严格限制,一定无法超过此数值
  • Grace time:宽限时间,通常为 7 天或 14 天,只有在用量超过 soft 数值后才会产生,若用户无任何动作,则 grace time 倒数完毕后, soft 数值会成为 hard 数值,因此文件系统就会被锁死。

所谓的『文件系统锁死』的意思,指的是用户将无法添加/删除文件系统的任何数据,所以就得要借由系统管理员来处理了!

由于 Quota 需要文件系统的支持,因此管理员请务必在 fstab 文件中增加底下的设置值:

  • uquota/usrquota/quota:启动用户帐号 quota 管理
  • gquota/grpquota:启动群组 quota 管理
  • pquota/prjquota:激活单一目录管理,但不可与 gquota 共用(本章不实做)

在 xfs 文件系统中,由于 quota 是『文件系统内部纪录管理』的,不像 EXT 家族是通过外部管理文件处理, 因此设置好参数后,一定要卸载再挂载 (umount --> mount),不可以使用 remount 来处理。

例题 14.5.1-1: 启动文件系统支持 quota 的参数
  1. 在测试机的系统中, /home 为 xfs 文件系统,请在设置档中加入 usrquota, grpquota 的挂载参数;
  2. 能否直接卸载 /home 再挂载?为什么?如何进行卸载再挂载的动作?
  3. 如何观察已经挂载的文件系统参数?

14.5.2:xfs 文件系统的 quota 实做

一般来说,Quota 的实做大多就是观察、设置、报告等项目,底下依序说明:

  • XFS 文件系统的 Quota 状态检查

xfs 文件系统的 quota 实做都是通过 xfs_quota 这个指令,这个指令在观察方面的语法如下:

[root@www ~]# xfs_quota -x -c "指令" [挂载点]
选项与参数:
-x  :专家模式,后续才能够加入 -c 的指令参数喔!
-c  :后面加的就是指令,这个小节我们先来谈谈数据回报的指令
指令:
      print :单纯的列出目前主机内的文件系统参数等数据
      df    :与原本的 df 一样的功能,可以加上 -b (block) -i (inode) -h (加上单位) 等
      report:列出目前的 quota 项目,有 -ugr (user/group/project) 及 -bi 等数据
      state :说明目前支持 quota 的文件系统的信息,有没有起动相关项目等

例如列出目前支持 quota 的文件系统观察可以使用:

[root@localhost ~]# xfs_quota -x -c "print"
Filesystem          Pathname
/                   /dev/mapper/rocky-root
/srv/vdo            /dev/mapper/raidvg-vdolv
/home               /dev/mapper/rocky-home (uquota, gquota)

如上表,系统就列出了有支持 quota 的载点,之后即可观察 quota 的启动状态:

[root@localhost ~]# xfs_quota -x -c "state"
User quota state on /home (/dev/mapper/rocky-home)
  Accounting: ON
  Enforcement: ON
  Inode: #5155 (4 blocks, 4 extents)
Blocks grace time: [7 days]
Blocks max warnings: 5
Inodes grace time: [7 days]
Inodes max warnings: 5
Realtime Blocks grace time: [7 days]
Group quota state on /home (/dev/mapper/rocky-home)
  Accounting: ON
  Enforcement: ON
  Inode: #5156 (4 blocks, 3 extents)
Blocks grace time: [7 days]
Blocks max warnings: 5
Inodes grace time: [7 days]
Inodes max warnings: 5
Realtime Blocks grace time: [7 days]
Project quota state on /home (/dev/mapper/rocky-home)
  Accounting: OFF
  Enforcement: OFF
  Inode: N/A
Blocks grace time: [--------]
Blocks max warnings: 0
Inodes grace time: [--------]
Inodes max warnings: 0
Realtime Blocks grace time: [--------]

上表显示的状况为:

  • 针对用户的设置已经打开 quota
  • 针对群组的设置已经打开 quota
  • 针对 Project 的设置并没有打开
  • Block 与 Inode 的宽限时间 (grace time) 均为 7 天
  • XFS 文件系统的 Quota 帐号/群组使用与设置值报告

若需要详细的列出在该载点底下的所有帐号的 quota 数据,可以使用 report 这个指令项目:

[root@localhost ~]# xfs_quota -x -c "report" /home
User quota on /home (/dev/mapper/rocky-home)
                               Blocks
User ID          Used       Soft       Hard    Warn/Grace
---------- --------------------------------------------------
root                4          0          0     00 [--------]
sysuser1           16          0          0     00 [--------]
student         98952          0          0     00 [--------]
.....
Group quota on /home (/dev/mapper/rocky-home)
                               Blocks
Group ID         Used       Soft       Hard    Warn/Grace
---------- --------------------------------------------------
root                4          0          0     00 [--------]
users              16          0          0     00 [--------]
student         98952          0          0     00 [--------]
.....

[root@localhost ~]# xfs_quota -x -c "report -ubih" /home
User quota on /home (/dev/mapper/rocky-home)
                        Blocks                            Inodes
User ID      Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace
---------- --------------------------------- ---------------------------------
root           4K      0      0  00 [------]      4      0      0  00 [------]
sysuser1      16K      0      0  00 [------]     10      0      0  00 [------]
student     96.6M      0      0  00 [------]   2.3k      0      0  00 [------]

单纯输入 report 时,系统会列出 user/group 的 block 使用状态,亦即是帐号/群组的容量使用情况,但缺省不会输出 inode 的使用状态。 若额外需要 inode 的状态,就可以在 report 后面加上 -i 之类的选项来处理。

  • XFS 文件系统的 Quota 帐号/群组实际设置方式

主要针对用户与群组的 Quota 设置方式如下:

[root@localhost ~]# xfs_quota -x -c "limit [-ug] b[soft|hard]=N i[soft|hard]=N name" mount_point
[root@localhost ~]# xfs_quota -x -c "timer [-ug] [-bir] Ndays"
选项与参数:
limit :实际限制的项目,可以针对 user/group 来限制,限制的项目有
        bsoft/bhard : block 的 soft/hard 限制值,可以加单位
        isoft/ihard : inode 的 soft/hard 限制值
        name        : 就是用户/群组的名称啊!
timer :用来设置 grace time 的项目喔,也是可以针对 user/group 以及 block/inode 设置

假设管理员要针对 student 这个帐号设置:可以使用的 /home 容量实际限制为 2G 但超过 1.8G 就予以警告, 简易的设置方式如下:

[root@localhost ~]# xfs_quota -x -c "limit -u bsoft=1800M bhard=2G student" /home
[root@localhost ~]# xfs_quota -x -c "report -ubh" /home
User quota on /home (/dev/mapper/rocky-home)
                        Blocks
User ID      Used   Soft   Hard Warn/Grace
---------- ---------------------------------
root           4K      0      0  00 [------]
sysuser1      16K      0      0  00 [------]
student     96.6M   1.8G     2G  00 [------]
.....

# 仅查看单一用户,就可以这样处理:
[root@localhost ~]# xfs_quota -x -c "quota -ubh student" /home
Disk quotas for User student (1000)
Filesystem   Blocks  Quota  Limit Warn/Time    Mounted on
/dev/mapper/rocky-home
              96.6M   1.8G     2G  00 [------] /home

若需要取消 student 设置值,直接将数值设置为 0 即可!

[root@localhost ~]# xfs_quota -x -c "limit -u bsoft=0 bhard=0 student" /home
例题 14.5.2-1: 实际设置与观察 XFS 文件系统的 Quota 设置值
  1. 创建一个名为 "quotaman" 的用户,该用户的密码设置为 "myPassWord"
  2. 观察 quotaman 刚刚创建好帐号后的 quota 数值
  3. 让 quotaman 的实际容量限制为 200M 而宽限容量限制为 150M 左右,设置完毕请观察是否正确
  4. 前往 tty5 终端机,并实际以 quotaman 的身份登录,同时运行『 dd if=/dev/zero of=test.img bs=1M count=160 』这个指令, 检查 quotaman 家目录是否有大型文件?且该指令运行是否会出错?
  5. 回归 root 的身份,再次观察 quotaman 的 quota 报告,是否有出现 grace time 的数据?为什么?
  6. 再次来到 quotaman 的 tty2 终端机,再次使用『 dd if=/dev/zero of=test.img bs=1M count=260 』这个指令, 检查 quotaman 家目录是否有大型文件?且该指令运行是否会出错?
  7. quotaman 需要如何处理数据后,才能够正常的继续操作系统?

14.6:课后练习操作

  • 上课的课后练习,非作业:
  1. 关闭 VDO 这个虚拟机的磁盘优化模块,卸载 /srv/vdo
  2. 关闭 raidvg 这个 LVM 的 VG,也关闭 /dev/md0 这个软件磁盘数组,同时恢复原本的磁盘分割,让系统只剩下 /dev/vda{1,2,3}
  3. 创建磁盘数组:
    1. 将原有剩余容量,平均分割为 2 个分区,每个分区应该是在 4G 左右即可。
    2. 设置成为 raid1 的磁盘数组,创建文件名为 /dev/md0 的软件磁盘数组
  4. 创建支持 XFS 的 LVM 文件系统
    1. 将 /dev/md0 设置成为 PV 之后,创建起 testvg 的 VG 名称,所有参数使用默认值即可
    2. 创建名为 /dev/testvg/testlv 的 LV,所有容量均给予这个设备即可
    3. 让 testlv 格式化为 xfs 文件系统,并且启动 quota 及挂载于 /srv/testlv 目录中
  5. student 在上述载点内,都具有 800M/1000M 的 quota 使用限制。
  6. 全部设置完毕后,重新开机,看看所有的数据能不能顺利运作!
  • 作业 (不提供学生答案,仅提供教师参考答案)

作业硬盘一般操作说明:

  • 打开云端虚拟机前,请务必确认你打开的硬盘是『unit14』,否则就会做错题目
  • 若要使用图形界面,请务必使用 student 身份登录,若需要切换身份,再激活终端机处理。
  • 若有简答题需要使用中文,请自行以第一堂课的动作自行处理输入法安装。
  • 每部虚拟机均有独特的网卡地址,请勿使用他人硬盘上传,否则计分为 0 分。
  • 每位同学均有自己的 IP 尾数,请先向老师询问您的 IP 尾数,才可以进行作业上传。
  • 最终上传作业结果,请务必使用 root 身份上传。
  • 进入作业硬盘后,先用 root 身份运行 vbird_book_setup_ip , 运行流程请参考:vbird_book_setup_ip

作业当中,某些部份可能为简答题~若为简答题时,请将答案写入 /home/student/ans.txt 当中,并写好正确题号,方便老师订正答案。 请注意,文件名写错将无法上传!

请使用 root 的身份进行如下实做的任务。直接在系统上面操作,操作成功即可,上传结果的程序会主动找到你的实做结果。 并请注意,题目是有相依性的,因此请依序进行底下的题目为宜

  1. (20%)请回答下列问题,并将答案写在 /root/ans14.txt 文件内:
    1. RAID0, RAID1, RAID6, RAID10 中 (1)哪一个等级性能最佳 (2)哪些等级才会有容错
    2. 承上,若以 8 颗磁盘为例,且都没有 spare disk 的环境下,上述等级各有几颗磁盘容量可用?
    3. 承上,以具有容错的磁盘数组而言,当有一颗磁盘损坏而需更换重建时, 哪些磁盘数组的重建性能最佳 (数据可直接拷贝,无须通过重新计算而言)
    4. 软件磁盘数组的 (1)操作指令为何? (2)磁盘数组文件名为何 (3)设置档文件名为何
    5. 进行分割 (partition) 时,在 GPT 的分割表情境下,(a)Linux LVM 与 (b)Linux software RAID 的 system ID 各为何?
    6. 进行磁盘配额 (filesystem quota) 时,挂载参数要加上哪两个文件系统参数 (以 XFS 文件系统为例) 才能够支持用户与群组的 quota
    7. 承上,磁盘配额限制【磁盘使用容量】与【可用文件数量】时,分别是限制甚么项目?
  2. (20%)弹性化管理文件系统:
    1. (15%)在目前的系统中,找到一个名为 hehe 的 LV ,将此 LV 的容量设置改成 1GB,且:
      • 且在这个 LV (1)会用完 VG 的所有剩余容量,也就是说,该 LV 所在的 VG 不要有剩下的容量在,若容量不足, 也请自行设法处理(自己想办法再切出需要的容量,且容量范围误差不要超过 10% 即可,亦即 900M~1100M 之间均可接受!)
      • 在这个 LV 上面的文件系统须同步处理容量。
    2. (5%)请让 /home 目录所在的文件系统具有 quota 的 user/group 磁盘容量配额限制的功能。 请注意,这一个项目与最后一题脚本创建有关,处理前,最好先注销图形界面,在 tty2 使用 root 直接登录,否则 /home 可能无法卸载。
  3. (20%)综合管理文件系统
    1. 请创建 7 个 1GB 的分区,且 system ID 请设置为 RAID 的样式
    2. 将上列磁盘分区用来创建 /dev/md0 为名的磁盘数组,等级为 RAID5,无须 spare disk,chunk size 请指定为 1M
    3. 以 /dev/md0 为磁盘来源,并依据底下的说明,创建一个 LVM 的设备
      • VG 名称请取为 govg ,PE 需要具有 8MB 的大小
      • LV 名称请取为 golv,容量约有 500MB
      • 格式化为 ext4 文件系统,且开机会自动挂载于 /data/golv 载点上
  4. (20%)创建 VDO 管理虚拟化磁盘系统的机制:
    1. 创建名为 /dev/govg/govdo 的 VDO 滚动条 (volumn),将 govg 的所有剩余容量都给 govdo,该 volumn 具有自动压缩功能, 且自动去除重复数据,最终给予 15G 的逻辑容量
    2. 格式化成为 xfs 文件系统,并且开机后会自动挂载到 /data/govdo/ 目录下
  5. (20%)创建一个名为 /root/myaccount.sh 的大量创建帐号的脚本,这个脚本运行后,可以完成底下的事件
    1. 会创建一个名为 mygroup 的群组
    2. 会依据缺省环境创建 30 个帐号,帐号名称为 myuser01 ~ myuser30 共 30 个帐号,且这些帐号会支持 mygroup 为次要群组
    3. 每个人的密码会使用【 openssl rand -base64 6 】随机取得一个 8 个字符的密码, 并且这个密码会被记录到 /root/account.password 文件中,每一行一个,帐号与密码当中用冒号隔开, 每一行的格式有点像【myuser01:AABBCCDD】
    4. 每个帐号缺省都会有 200MB/250MB 的 soft/hard 磁盘配额限制。

作业结果传输:请以 root 的身分运行 vbird_book_check_unit 指令上传作业结果。 正常运行完毕的结果应会出现【XXXXXX_aa:bb:cc:dd:ee:ff_unitNN】字样。若需要查阅自己上传数据的时间, 请在操作系统上面使用浏览器查找: http://192.168.251.254 检查相对应的课程文件。 相关流程请参考: vbird_book_check_unit

修改历史:
  • 2023/05/29:在 RHEL 9 的 stratis 以及 VDO 的设计说明,跟前一代确实有不一样了!
  • 2023/06/05:作业硬盘终于搞定!
2023/05/29 以来统计人数
计数器
其他链接
环境工程模式篇
鸟园讨论区
鸟哥旧站

今日 人数统计
昨日 人数统计
本月 人数统计
上月 人数统计