(一图胜千言)
背景
我们在使用 Linux 的时候,经常会遇到如下问题:
/var/log、/var/lib/docker 等都会使用磁盘分区或者独立磁盘来管理容量和性能,但是不同集群规模,需要的容量是不一样的,硬盘设备容量不足时,往往就需要做迁移等操作;
容器在不同节点上运行的时候,为了保证 volume 映射的一致性,需要使用 mount bind 来让某一路径是同一的。
数据盘在使用的过程中,有些用得多,有些用得少,最终十几块硬盘可能会出现若干空间浪费(总空间足够,但是分散在各个硬盘上,无法整合使用);
幸运的是 Linux 提供的逻辑盘卷管理(LVM,LogicalVolumeManager)机制就是一个不错的解决方案。
LVM 简介
LVM 是逻辑卷管理(Logical Volume Manager)的简称,它是 Linux 环境下对磁盘分区进行管理的一种机制。LVM通过在硬盘和文件系统之间添加一个逻辑层,来为文件系统屏蔽下层硬盘分区布局,提高硬盘分区管理的灵活性。
使用LVM管理硬盘的基本过程如下:
将硬盘创建为物理卷。
将多个物理卷组合成卷组。
在卷组中创建逻辑卷。
在逻辑卷之上创建文件系统。
通过 LVM 管理硬盘之后,文件系统不再受限于硬盘的大小,可以分布在多个硬盘上,也可以动态扩容。
LVM 历史
当然,LVM并不是最新技术,早在UNIX操作系统时代,在像HP、IBM AIX上就可以看到VM的身影,作为IBM的旗舰产品,AIX很早就支持了动态逻辑分区(DVM),当然,它的DVM设计是比较厉害的,此后在AIX 5L中,重构了UNIX内核,增加了逻辑卷管理(LVM)和日志文件系统(JFS)等功能。使之AIX更加强大。在各种商业UNIX系统中,譬如AIX、 HP-UNIX、Tru64 UNIX等系统中,逻辑卷管理已经被广泛采用,成为了事实上的一个标准。
LVM 的功能于 2.3 内核发展中版本纳入支持。2001年1月,Linux2.4.0内核发布,开始正式支持逻辑卷管理,使得 Linux 新内核更适应服务器的应用。以前版本的 Linux 必须要在内核上打上相应的补丁才能实现 LVM 功能。现在我们看到从 RHEL 9.0 开始已经在内核级支持LVM。因此,我们可以使用 LVM 帮助我们更加有效地管理磁盘。要注意的是LVM有两个版本,分别是 LVM 1 与LVM 2,相关工具与设定方式会有些差异性。LVM 1命令只能在2.4内核上工作。当运行2.6内核时,不能使用LVM 1命令。
关于更多关于LVM 2的信息,请参阅/usr/share/doc/lvm2*/WHATS_NEW。一个完整的LVM 2命令被安装在/usr/sbin/下。在/usr/无效的启动环境中,每个命令前需要加上/sbin/lvm.static(例如,/sbin /lvm.static vgchange -ay)。在/usr有效的环境中,不再需要在每个命令前加上lvm(例如,/usr/sbin/lvm vgchage –ay变为/usr/sbin/vgchange -ay)。新的LVM2命令(例如,/usr/sbin/vgchange –ay和/sbin/lvm.static vgchange –ay)会检测你是否在运行2.4内核。如果是,它会调用旧的LVM 1命令。
基本概念
物理存储介质(The physical media):指系统的物理存储设备,如硬盘,系统中为/dev/hda、/dev/sda等等,是存储系统最低层的存储单元。
物理卷(Physical Volume,PV):指硬盘分区或从逻辑上与磁盘分区具有同样功能的设备(如RAID),是LVM的基本存储逻辑块。物理卷包括一个特殊的标签,该标签默认存放在第二个 512 字节扇区,但也可以将标签放在最开始的四个扇区之一。该标签包含物理卷的随机唯一识别符(UUID),记录块设备的大小和LVM元数据在设备中的存储位置。
卷组(Volume Group,VG):由物理卷组成,屏蔽了底层物理卷细节。可在卷组上创建一个或多个逻辑卷且不用考虑具体的物理卷信息。
逻辑卷(Logical Volume,LV):卷组不能直接用,需要划分成逻辑卷才能使用。逻辑卷可以格式化成不同的文件系统,挂载后直接使用。
物理块(Physical Extent,PE):物理卷以大小相等的“块”为单位存储,块的大小与卷组中逻辑卷块的大小相同。
逻辑块(Logical Extent,LE):逻辑卷以“块”为单位存储,在一卷组中的所有逻辑卷的块大小是相同的。
LVM 命令一览
PV 命令
命令 | 描述 |
pvcreate | 将物理分区建成为PV |
pvscan | 搜索当前系统里任何具有PV的磁盘 |
pvdisplay | 显示当前系统上的PV状态 |
pvremove | 将PV属性删除,让该分区不具有PV属性 |
partprobe | 这个命令可以让核心立刻读入最新的分区表而不必重新引导 |
VG 命令
命令 | 描述 |
vgcreate | 创建 VG |
vgscan | 搜索系统上面是否有VG存在 |
vgdisplay | 显示当前系统上的VG状态 |
vgextend | 在VG内增加额外的PV |
vgreduce | 在VG内删除PV |
vgchange | 设置VG是否启动(active) |
vgremove | 删除一个VG |
LV 命令
命令 | 描述 |
lvcreate | 建立LV |
lvscan | 查询系统上的LV |
lvdisplay | 显示系统上的LV状态 |
lvextend | 在LV里增加容量 |
lvreduce | 在LV里减少容量 |
lvremove | 删除一个LV |
lvresize | 对LV进行容量大小的调整 |
汇总
操作 | PV | VG | LV |
搜索(scan) | pvscan | vgscan | lvscan |
建立(create) | pvcreate | vgcreate | lvcreate |
列出(display) | pvdisplay | vgdisplay | lvdisplay |
增加(extend) | vgextend | lvextend | |
减少(reduce) | vgreduce | lvreduce | |
删除(remove) | pvremove | vgremove | lvremove |
改变容量(resize) | vgresize |
上手操作
对于本次实践演练,我们构建了一个具有 40G 根存储(不重要)和三个大小为 5G 的外部磁盘的虚拟机,这些磁盘的大小可以是任意的。
安装 lvm2
CentOS 上安装:
sudo yum install -y lvm2创建物理卷
我们可以使用原始的未分区磁盘或分区本身创建物理卷。我们使用pvcreate命令创建物理卷:
sudo pvcreate /dev/sdcPhysical volume "/dev/sdc" successfully created.
接下来我将 /dev/sdd 分成相等的两部分。我们可以使用 cfdisk、parted 或者 fdisk ,它们都可以用来完成这项工作。
lsblk -o name,size,fstype | grep sddsdd 5G ├─sdd1 2.5G └─sdd2 2.5G
我们继续创建两个物理卷:
pvcreate /dev/sdd1 /dev/sdd2 Physical volume "/dev/sdd1" successfully created. Physical volume "/dev/sdd2" successfully created.
列出可用的物理卷
我们可以使用三个命令来获取可用物理卷的列表:pvscan、pvs和pvdisplay:
sudo pvscan PV /dev/sdc lvm2 [5.00 GiB] PV /dev/sdd1 lvm2 [2.50 GiB] PV /dev/sdd2 lvm2 [<2.50 GiB] Total: 3 [<10.00 GiB] / in use: 0 [0 ] / in no VG: 3 [<10.00 GiB]
sudo pvs PV VG Fmt Attr PSize PFree /dev/sdc lvm2 --- 5.00g 5.00g /dev/sdd1 lvm2 --- 2.50g 2.50g /dev/sdd2 lvm2 --- <2.50g <2.50g
sudo pvdisplay "/dev/sdc" is a new physical volume of "5.00 GiB" --- NEW Physical volume --- PV Name /dev/sdc VG Name PV Size 5.00 GiB Allocatable NO PE Size 0 Total PE 0 Free PE 0 Allocated PE 0 PV UUID SzSkdD-xKYa-4y7P-teyU-481p-uiQ8-qieMJJ "/dev/sdd1" is a new physical volume of "2.50 GiB" --- NEW Physical volume --- PV Name /dev/sdd1 VG Name PV Size 2.50 GiB Allocatable NO PE Size 0 Total PE 0 Free PE 0 Allocated PE 0 PV UUID 553Iy4-JJ21-LfIw-udtO-j9Cd-7gFS-iXXFVS "/dev/sdd2" is a new physical volume of "<2.50 GiB" --- NEW Physical volume --- PV Name /dev/sdd2 VG Name PV Size <2.50 GiB Allocatable NO PE Size 0 Total PE 0 Free PE 0 Allocated PE 0 PV UUID bf7ghn-QkPm-EUdp-GdyW-shMG-5sMn-VhNtYB
删除物理卷
我们可以使用以下命令删除物理卷 pvremove。就像一样 pvcreate,只需将设备(初始化为物理卷)传递给 pvremove 命令即可。
我将从 /dev/sdd2 列表中删除:
sudo pvremove /dev/sdd2 Labels on physical volume "/dev/sdd2" successfully wiped.
查看当前的物理卷:
sudo pvs PV VG Fmt Attr PSize PFree /dev/sdc lvm2 --- 5.00g 5.00g /dev/sdd1 lvm2 --- 2.50g 2.50g
我们可以看到,/dev/sdd2 已经被删除了。
卷组
卷组是物理卷的集合。它是 LVM 中的下一个抽象级别。卷组是组合多个原始存储设备的存储容量的存储池。
创建卷组
卷组是使用该 vgcreate 命令创建的。第一个参数 vgcreate 是要为该卷组指定的名称,其余参数是要支持存储池的物理卷的列表。
sudo vgcreate lvm_tutorial /dev/sdc /dev/sdd1 Volume group "lvm_tutorial" successfully created
列出卷组
列出卷组与列出物理卷类似,您可以使用具有不同详细级别的不同命令vgdisplay、vgscan和vgs。
sudo vgs VG #PV #LV #SN Attr VSize VFree lvm_tutorial 2 0 0 wz--n- 7.49g 7.49g
sudo vgscan Found volume group "lvm_tutorial" using metadata type lvm2
sudo vgdisplay --- Volume group --- VG Name lvm_tutorial System ID Format lvm2 Metadata Areas 2 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 2 Act PV 2 VG Size 7.49 GiB PE Size 4.00 MiB Total PE 1918 Alloc PE / Size 0 / 0 Free PE / Size 1918 / 7.49 GiB VG UUID LYVE9P-vY0G-OAW6-an8q-yfBx-rrB1-YU61m1
列出附加到卷组的物理卷
我们可以使用以下命令列出连接到特定卷组的所有物理卷:
sudo pvdisplay -S vgname=lvm_tutorial -C -o pv_name PV /dev/sdc /dev/sdd1
我们可以获得物理卷的计数:
sudo vgdisplay -S vgname=lvm_tutorial -C -o pv_count #PV 3
扩展卷组
扩展卷组意味着向卷组添加额外的物理卷。
sudo vgextend lvm_tutorial /dev/sdd2 Physical volume "/dev/sdd2" successfully created. Volume group "lvm_tutorial" successfully extended
我们之前将物理卷 /dev/sdd2 删除了,所以在执行 vgextend 之前必须重新创建物理卷 /dev/sdd2。
再次查看卷组,以确定是否满足期望:
sudo pvdisplay -S vgname=lvm_tutorial -C -o pv_name PV /dev/sdc /dev/sdd1 /dev/sdd2
卷组缩容
卷组缩容意味着删除卷组的一个或多个物理卷。
sudo vgreduce lvm_tutorial /dev/sdc /dev/sdd1 Removed "/dev/sdc" from volume group "lvm_tutorial" Removed "/dev/sdd1" from volume group "lvm_tutorial"
如果卷组上有任何已经创建出来的逻辑卷,则我们无法简单删除物理卷。
再次检查:
sudo pvdisplay -S vgname=lvm_tutorial -C -o pv_name PV /dev/sdd2
为了后续的实验,需要再次加回来:
sudo vgextend lvm_tutorial /dev/sdc /dev/sdd1
删除卷组
我们可以使用 vgremove 来删除卷组:
sudo vgremove lvm_tutorial
(先不要执行该命令,因为我们还需要进行实验)
逻辑卷
逻辑卷就像一个分区,但它不是位于原始磁盘之上,而是位于卷组之上。我们可以,
使用任何文件系统格式化逻辑卷;
将其 mount 到文件系统中的任何位置。
创建逻辑卷
逻辑卷是使用该lvcreate命令创建的。常用的语法如下所示,
sudo lvcreate -L <size> -n <lvname> <vgname>
其中:
该-L选项针对新逻辑卷的大小,可以使用任何以“GB”、“MB”或“KB”结尾的整数。例如“1GB”;
该-n选项用于命名该逻辑卷;
卷组的名称。
因此,在为逻辑卷提供大小时,请确保卷组具有可用空间。
sudo lvcreate -L 5GB -n lv1 lvm_tutorial Logical volume "lv1" created.
逻辑卷上的常见操作
创建后,我们可以在路径中找到逻辑卷/dev/<vgname>/<lvname>。例如,在我们的例子中,卷的位置为:/dev/lvm_tutorial/lv1:
ls -l /dev/lvm_tutorial/lv1 lrwxrwxrwx 1 root root 7 May 17 02:09 /dev/lvm_tutorial/lv1 -> ../dm-0
我们可以像使用任何分区一样使用它,例如用ext4格式化:
sudo mkfs.ext4 /dev/lvm_tutorial/lv1
接下来我们可以将其 mount 到当前目录结构中的某个位置,例如/mnt:
sudo mount -t ext4 /dev/lvm_tutorial/lv1 /mnt
调整逻辑卷大小
我们可以使用命令扩展逻辑卷 lvextend 并使用命令减小其大小 lvreduce。或者我们可以使用单个命令 lvresize 来完成这两项任务。
首先我检查一下可用空间:
sudo vgs -S vgname=lvm_tutorial -o vg_free VFree <4.99g
查看 mount 信息:
mount | grep '/mnt'/dev/mapper/lvm_tutorial-lv1 on /mnt type ext4 (rw,relatime)
调整卷大小:
sudo lvresize -L +2GB lvm_tutorial/lv1
一般语法如下:
lvresize -L [+|-][Size] <vgname>/<lvname>
后面的符号 + 或 --L取决于您是否要分别尝试增大或减小卷大小。
卷大小增加后,文件系统也必须调整大小。对于 ext4,要使用的命令是resize2fs:
sudo resize2fs /dev/lvm_tutorial/lv1resize2fs 1.45.5 (07-Jan-2020)Filesystem at /dev/lvm_tutorial/lv1 is mounted on /mnt; on-line resizing requiredold_desc_blocks = 1, new_desc_blocks = 1The filesystem on /dev/lvm_tutorial/lv1 is now 1835008 (4k) blocks long.
并非所有文件系统都支持热调整大小,Ext4 和 XFS 是受支持的文件系统之一。
注意:XFS 文件系统可以支持扩容,但是不支持缩容。
删除逻辑卷
我们可以使用以下 lvremove 命令删除逻辑卷:
sudo lvremove lvm_tutorial/lv1Do you really want to remove and DISCARD active logical volume lvm_tutorial/lv1? [y/n]: y Logical volume "lv1" successfully removed
总结
关于缩容这块我们另外再讨论。此外 LVM 还依赖 device mapper,这部分我们也另外写文章讨论。
参考
《RHEL 逻辑卷管理器管理》
https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/7/html/logical_volume_manager_administration/index
《OpenEuler 使用LVM管理硬盘》https://docs.openeuler.org/zh/docs/20.03_LTS_SP4/docs/Administration/%E4%BD%BF%E7%94%A8LVM%E7%AE%A1%E7%90%86%E7%A1%AC%E7%9B%98.html