前言

近日在腾讯云的VPS上搭建私用网盘,刚开始申请的50G硬盘感觉小了,就又买了一块。但是腾讯云的镜像使用的都是传统分区表,这样当网盘的内容大于50G之后,我就得手动指定网盘把新内容存储到另一块硬盘上。

我用的网盘是Nextcloud,有个插件 External storage support 支持多硬盘,不过服务器未来可能还需要部署别的服务,于是就准备把主硬盘调整为LVM格式,然后和新硬盘一起分到同一个区上。这样就可以完全把两块硬盘当作同一个分区使用了。

网上找的资料大部分是教怎么给新硬盘、分区划分LVM的,基本没有怎么给现有分区转换的,研究了一阵子,总算摸索成功,分享一下。

准备工作

本文的转换工作的前提有:

  1. 如果是VPS,需要有VNC的连接方式,即需要能进入grub引导界面——物理机器当然没限制;
  2. 下文命令适用于Ubuntu 18.04,其他发行版也可以参考。

注:VPS的VNC连接方式通常需要通过其管理网站操作,比如腾讯云需要在实例管理页面上,点击指定机器的 登录其他方式(VNC)

开始干活

我的环境具体是这样的:首先是原始硬盘 /dev/vda,有一个分区 /dev/vda1,挂载到 / 上面,然后新硬盘是 /dev/vdb

思路是这样的,先在vdb上安装一个Ubuntu,然后启动到上面,对vda进行数据备份、调整LVM、数据恢复的操作,最后恢复vda的引导,并把vdb也调整为LVM。

制作启动硬盘

以下假设所有命令在root权限下执行。

硬盘分区

首先给vdb分区:

1
fdisk /dev/vdb

如果vdb上面本来有分区的话,需要用d删除,之后依次用 n p 新建分区:

fdisk new

新建完之后再用 t 修改分区格式为 Linux LVM 格式,并用w写入:

fdisk change

此时使用 fdisk -l 查看分区别,可以看到vdb的分区格式如下:

1
2
3
4
5
6
7
8
9
Disk /dev/vdb: 50 GiB, 53687091200 bytes, 104857600 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: 0x5dee0536

Device     Boot Start       End   Sectors Size Id Type
/dev/vdb1        2048 104857599 104855552  50G 8e Linux LVM

LVM格式转换

分区创建完成,接下来转换为LVM格式:

1
2
3
4
5
6
7
8
#先安装lvm
apt install lvm2

#创建物理卷
pvcreate /dev/vdb1

#创建卷组,命名为vg2
vgcreate vg2 /dev/vdb1

此时用 vgdisplay 可以看到卷组信息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
  --- Volume group ---
  VG Name               vg2
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  3
  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               <50.00 GiB
  PE Size               4.00 MiB
  Total PE              12799
  Alloc PE / Size       0 / 0
  Free  PE / Size       12799 / <50.00 GiB
  VG UUID               mwyJu2-F9a4-bBr8-af3c-cGcB-kWca-8erl39

可以看到卷组大小为50G。

现在在卷组上创建逻辑卷,逻辑卷就是我们要使用的分区了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#49.9是分区大小,lv1是卷的名字,vg2是所使用的卷组名字
lvcreate -L 49.9G -n lv1 vg2

#可以使用 lvdisplay 查看卷的信息。
lvdisplay

#格式化这个分区
mkfs.ext4 /dev/vg2/lv1

#最后将其挂载,我挂载到了/vol目录下
mkdir /vol
mount /dev/vg2/lv1 /vol

使用debootstrap安装Ubuntu

debootstrap 是一个用于创建一个Linux根文件系统的工具,我使用它来创建一个启动盘。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#先安装debootstrap
apt install debootstrap

#在/vol上安装ubuntu18.04,如果你的Ubuntu不是这个版本,需要把bionic换成对应版本的。
debootstrap --arch=amd64 --include=linux-generic,grub-pc,vim,lvm2 bionic
/vol http://mirrors.tencentyun.com/ubuntu/

#安装grub
grub-install /dev/vdb

#设置dev目录
mount -o bind /dev /vol/dev

#chroot到新系统中,并更新grub
chroot /vol
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devpts none /dev/pts
update-grub

#配置一个新用户,以便之后通过此用户登录
adduser test1
usermod -aG sudo test1

#记下新的LVM分区的uuid(注意不是指vdb1分区)
blkid

#修改root分区的uuid为刚刚的uuid
vim /etc/fstab

exit

现在Ubuntu的启动硬盘已经准备好了,退回原始系统之后,我们就准备要使用vdb上的Ubuntu来启动了。不过在这之前先更新vda上的grub以将其加入启动菜单。

1
2
3
4
5
#如果是vps上,可以先去这个文件里面,把GRUB_TIMEOUT一项设置成较大的数值,以方便
#在机器重启之后有足够的时间通过VNC连接。腾讯云我设置的是20秒。
vim /etc/default/grub

update-grub

启动到新系统中

重启机器。

然后在网页上使用VNC连接VPS(物理机器的话盯着显示器就行了),此时应该能看到grub引导界面,选中新安装的那个ubuntu,回车进入。

不出意外的话,就可以进入login界面了,使用刚刚设置的用户名和密码登录。

此时,新系统的根分区可能是以只读的方式加载的,需要使用如下命令来将其重载为可读写的。

1
mount -o remount, rw /

备份旧系统

1
2
3
4
5
6
#先装载旧的分区
mkdir /vol
mount /dev/vda1 /vol

#备份旧的硬盘,如果嫌慢,而且硬盘IO比较快的话可以把cpzf中的z去掉,就不会压缩了
tar cpzf /backup.tar.gz --exclude=/lost+found -C /vol/ .

创建LVM

!!注意!!这一步会完全破坏掉原始分区的内容!请确认已经先备份好数据!

首先卸载旧分区:

1
umount /vol

之后步骤类似LVM格式转换,只需把其中的 vdb 对应换成 vda,且自己定义新的卷组名字即可:

1
2
3
4
5
pvcreate /dev/vda1
vgcreate vg1 /dev/vda1
lvcreate -L 49.9G -n lv1 vg1
mkfs.ext4 /dev/vg1/lv1
mount /dev/vg1/lv1 /vol

恢复旧系统

1
2
#如果备份的时候没有加z,这里也需要去掉
tar xpzf /backup.tar.gz -C /vol/

恢复引导

首先配置一下grub。

1
2
3
4
5
6
7
grub-install /dev/vda
mount -o bind /dev /vol/dev
chroot /vol
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devpts none /dev/pts
update-grub

随后再次查看 blkid 并编辑一下fstab中的UUID。(也可以等重启之后再做)

这时就可以重启了,重启之前可以先把vdb卸载掉,即强制使用vda来引导。

连接VNC,这时可能会进入一个grub启动失败的界面(这里我也不太清楚原因,希望有高手可以解惑),不用慌,可以这样修复:

grub引导修复

先用 ls 找到引导硬盘的名字,然后依次设置 prefixroot 变量,并借此找到 normal 模块,加载和运行。

随后便可进入熟悉的grub引导界面,从而启动系统。

进入了熟悉的旧系统,如果fstab还没修复的话,也可以这时来修复:

1
2
3
mount -o remount, rw /
blkid
vim /etc/fstab

最后,修复grub引导:

1
2
grub-install /dev/vda
update-grub

LVM扩展

把vdb的分区抹掉,并加到vg1这个卷组内。这一步就比较正常了,网上所有与LVM有关的教程基本都会教到,就不赘述了。

至此,大功告成!

其他思路

其实要达成“方便使用另一块硬盘”的目的,还有很多思路,这里罗列一下以供参考:

  1. 如前言所述,使用Nextcloud的 External storage support 插件。
  2. 腾讯云的Ubuntu镜像是整个硬盘只分一个区,挂到 / 上面的,于是可以使用 resize2fs + fdisk 等分区工具,把分区缩小一些作为系统分区,然后把剩余的部分和新硬盘一起作为LVM的物理卷,挂到其他路径上。当然,这个操作还是需要一个“启动盘”。
  3. 如果是物理机器的话,其实可以直接使用一个LiveCD来进行数据备份、调整LVM等操作,就免除了本文前面制作启动硬盘的步骤。