在具有 UEFI BIOS 的计算机上安装具有 RAID 1 和 LVM 的 Ubuntu 20.04 桌面

Nic*_*lin 7 lvm raid uefi system-installation 20.04

我有一台带有 UEFI BIOS 的机器。我想在 RAID 1 之上安装带有 LVM 的 Ubuntu 20.04 桌面,这样即使其中一个驱动器出现故障,我的系统也能继续工作。我还没有找到相关的 HOWTO。20.04 桌面安装程序支持 LVM,但不支持 RAID。这个问题的答案描述了18.04的流程。但是,20.04 不提供备用服务器安装程序。这个问题这个问题的答案描述了 RAID,但没有描述 LVM 或 UEFI。有没有人有一个适用于 20.04 的流程,在 UEFI 机器的 RAID 1 之上使用 LVM?

Nic*_*lin 18

经过几周的实验并在这个链接的一些帮助下,我终于找到了一个可行的解决方案。以下序列是使用 Ubuntu 20.04.2.0 LTS 执行的。我还在虚拟机中成功地使用了 21.04.0 的过程。(但是,请注意, Ubuntu 21.04 和一些较旧的 UEFI 系统存在报告问题。

\n

简而言之

\n
    \n
  1. 下载并启动 Ubuntu Live 20.04。
  2. \n
  3. 设置 mdadm 和 lvm。
  4. \n
  5. 运行 Ubuntu 安装程序,但不要重新启动。
  6. \n
  7. 将 mdadm 添加到目标系统。
  8. \n
  9. 将 EFI 分区克隆到第二个驱动器。
  10. \n
  11. 将第二个 EFI 分区安装到 UEFI 引导链中。
  12. \n
  13. 重启
  14. \n
\n

详细

\n

1. 下载安装程序并启动至 Ubuntu Live

\n

1.1 下载

\n
    \n
  • 从https://ubuntu.com/download/desktop下载 Ubuntu 桌面安装程序并将其放入可启动媒体。(截至 2021 年 12 月 13 日,iso 称为 ubuntu-20.04.3-desktop-amd64.iso。)
  • \n
\n

1.2 启动 Ubuntu Live

\n
    \n
  • 从步骤 1.1 启动到媒体。
  • \n
  • 选择Try Ubuntu
  • \n
  • 按 Ctrl-Alt-T 启动终端。应在该终端中输入以下命令。
  • \n
\n

2.设置mdadm和lvm

\n

在下面的示例中,磁盘设备称为/dev/sda/dev/sdb。如果您的磁盘被称为其他名称,例如/dev/nvme0n1/dev/sdb,您应该相应地替换磁盘名称。您可以使用它sudo lsblk来查找磁盘的名称。

\n

2.0 安装ssh服务器

\n

如果您不想键入下面的所有命令,您可以安装想要通过 ssh 登录并剪切并粘贴命令。

\n
    \n
  • 安装

    \n

    sudo apt install openssh-server

    \n
  • \n
  • 设置密码以启用外部登录

    \n

    passwd

    \n
  • \n
  • 如果您在虚拟机内测试此功能,您可能需要转发合适的端口。选择SettingsNetworkAdvancedPort forwarding和加号。例如,输入和3022作为访客端口,然后按。或者从主机系统的命令行(将 VMNAME 替换为虚拟机的名称):Host Port22OK

    \n
    VBoxManage modifyvm VMNAME --natpf1 "ssh,tcp,,3022,,22"\nVBoxManage showvminfo VMNAME | grep \'Rule\'\n
    Run Code Online (Sandbox Code Playgroud)\n
  • \n
\n

现在,您应该能够使用以下命令从外部计算机登录您的 Ubuntu Live 会话

\n
ssh <hostname> -l ubuntu\n
Run Code Online (Sandbox Code Playgroud)\n

或者,如果您正在虚拟机上进行测试localhost

\n
ssh localhost -l ubuntu -p 3022\n
Run Code Online (Sandbox Code Playgroud)\n

以及您上面设置的密码。

\n

2.1 在物理磁盘上创建分区

\n
    \n
  • 将分区表清零

    \n
    sudo sgdisk -Z /dev/sda\nsudo sgdisk -Z /dev/sdb\n
    Run Code Online (Sandbox Code Playgroud)\n
  • \n
  • 在每个驱动器上创建两个分区;一种用于 EFI,一种用于 RAID 设备。

    \n
    sudo sgdisk -n 1:0:+512M -t 1:ef00 -c 1:"EFI System" /dev/sda\nsudo sgdisk -n 2:0:0 -t 2:fd00 -c 2:"Linux RAID" /dev/sda\nsudo sgdisk -n 1:0:+512M -t 1:ef00 -c 1:"EFI System" /dev/sdb\nsudo sgdisk -n 2:0:0 -t 2:fd00 -c 2:"Linux RAID" /dev/sdb\n
    Run Code Online (Sandbox Code Playgroud)\n
  • \n
  • 在第一个驱动器上为 EFI 分区创建 FAT32 系统。(稍后将克隆到第二个驱动器。)

    \n
    sudo mkfs.fat -F 32 /dev/sda1\n
    Run Code Online (Sandbox Code Playgroud)\n
  • \n
\n

2.2 安装mdadm并创建md设备

\n

安装mdadm

\n
  sudo apt-get update\n  sudo apt-get install mdadm\n
Run Code Online (Sandbox Code Playgroud)\n

创建 md 设备。忽略有关元数据的警告,因为该阵列不会用作引导设备。

\n
  sudo mdadm --create /dev/md0 --bitmap=internal --level=1 --raid-disks=2 /dev/sda2 /dev/sdb2\n
Run Code Online (Sandbox Code Playgroud)\n

检查md设备的状态。

\n
$ cat /proc/mdstat \nPersonalities : [raid1] \nmd0 : active raid1 sdb2[1] sda2[0]\n      1047918528 blocks super 1.2 [2/2] [UU]\n      [>....................]  resync =  0.0% (1001728/1047918528) finish=69.6min speed=250432K/sec\n      bitmap: 8/8 pages [32KB], 65536KB chunk\n\nunused devices: <none>\n
Run Code Online (Sandbox Code Playgroud)\n

在这种情况下,设备正在同步磁盘,这是正常的,并且可能会在下面的过程中在后台继续进行。

\n

2.4 对md设备进行分区

\n
  sudo sgdisk -Z /dev/md0\n  sudo sgdisk -n 1:0:0 -t 1:E6D6D379-F507-44C2-A23C-238F2A3DF928 -c 1:"Linux LVM" /dev/md0\n
Run Code Online (Sandbox Code Playgroud)\n

/dev/md0p1这将在设备上创建一个分区/dev/md0。UUID 字符串标识 LVM 分区的分区。

\n

2.3 创建LVM设备

\n\n

现在,分区已准备好供 Ubuntu 安装程序使用。

\n

3.运行安装程序

\n
    \n
  • 双击Install Ubuntu 20.04.2.0 LTS新计算机桌面上的图标。(不要通过任何 ssh 连接启动安装程序!)
  • \n
  • 回答语言和键盘问题。
  • \n
  • 在页面上Installation type,选择Something else。(这是重要的部分。)这将为您提供一个名为/dev/mapper/vg0-home等的分区列表。
  • \n
  • 双击以 开头的每个分区/dev/mapper/vg0-。选择Use as: Ext4,选中该Format the partition框,然后选择适当的安装点(/for vg0-root/homeforvg0-home等、/var/libfor vg0-varlib)。
  • \n
  • /dev/sda选择引导加载程序的第一个设备。
  • \n
  • Install Now并继续安装。
  • \n
  • 安装完成后,选择Continue Testing
  • \n
\n

在终端中,运行lsblk. 输出应该是这样的:

\n
$ lsblk\nNAME               MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT\n...\nsda                  8:0    0  1000G  0 disk  \n\xe2\x94\x9c\xe2\x94\x80sda1               8:1    0   512M  0 part  \n\xe2\x94\x94\xe2\x94\x80sda2               8:2    0 999.5G  0 part  \n  \xe2\x94\x94\xe2\x94\x80md0              9:0    0 999.4G  0 raid1 \n    \xe2\x94\x94\xe2\x94\x80md0p1        259:0    0 999.4G  0 part  \n      \xe2\x94\x9c\xe2\x94\x80vg0-root   253:0    0    25G  0 lvm   /target\n      \xe2\x94\x9c\xe2\x94\x80vg0-tmp    253:1    0    10G  0 lvm   \n      \xe2\x94\x9c\xe2\x94\x80vg0-var    253:2    0     5G  0 lvm   \n      \xe2\x94\x9c\xe2\x94\x80vg0-varlib 253:3    0    10G  0 lvm   \n      \xe2\x94\x94\xe2\x94\x80vg0-home   253:4    0   200G  0 lvm   \nsdb                  8:16   0  1000G  0 disk  \n\xe2\x94\x9c\xe2\x94\x80sdb1               8:17   0   512M  0 part  \n\xe2\x94\x94\xe2\x94\x80sdb2               8:18   0 999.5G  0 part  \n  \xe2\x94\x94\xe2\x94\x80md0              9:0    0 999.4G  0 raid1 \n    \xe2\x94\x94\xe2\x94\x80md0p1        259:0    0 999.4G  0 part  \n      \xe2\x94\x9c\xe2\x94\x80vg0-root   253:0    0    25G  0 lvm   /target\n      \xe2\x94\x9c\xe2\x94\x80vg0-tmp    253:1    0    10G  0 lvm   \n      \xe2\x94\x9c\xe2\x94\x80vg0-var    253:2    0     5G  0 lvm   \n      \xe2\x94\x9c\xe2\x94\x80vg0-varlib 253:3    0    10G  0 lvm   \n      \xe2\x94\x94\xe2\x94\x80vg0-home   253:4    0   200G  0 lvm   \n...\n
Run Code Online (Sandbox Code Playgroud)\n

如您所见,安装程序将安装的系统根目录挂载到/target. 但是,其他分区未安装。更重要的是,mdadm它还不是已安装系统的一部分。

\n

4.将mdadm添加到目标系统

\n

4.1 chroot进入目标系统

\n

首先,我们必须挂载未挂载的分区:

\n
sudo mount /dev/mapper/vg0-home /target/home\nsudo mount /dev/mapper/vg0-tmp /target/tmp\nsudo mount /dev/mapper/vg0-var /target/var\nsudo mount /dev/mapper/vg0-varlib /target/var/lib\n
Run Code Online (Sandbox Code Playgroud)\n

接下来,绑定一些设备,准备chroot...

\n
cd /target\nsudo mount --bind /dev dev \nsudo mount --bind /proc proc\nsudo mount --bind /sys sys\n
Run Code Online (Sandbox Code Playgroud)\n

...并chroot进入目标系统。

\n
sudo chroot .\n
Run Code Online (Sandbox Code Playgroud)\n

4.2 更新目标系统

\n

现在我们位于目标系统内部。安装mdadm

\n
apt install mdadm\n
Run Code Online (Sandbox Code Playgroud)\n

如果您收到 dns 错误,请执行以下操作

\n
echo "nameserver 1.1.1.1" >> /etc/resolv.conf \n
Run Code Online (Sandbox Code Playgroud)\n

并重复

\n
apt install mdadm\n
Run Code Online (Sandbox Code Playgroud)\n

您可以忽略任何有关管道泄漏的警告。

\n

检查配置文件/etc/mdadm/mdadm.conf。它应该在末尾附近包含一行,类似于

\n
ARRAY /dev/md/0 metadata=1.2 UUID=7341825d:4fe47c6e:bc81bccc:3ff016b6 name=ubuntu:0\n
Run Code Online (Sandbox Code Playgroud)\n

删除该name=...部分以使该行看起来像

\n
ARRAY /dev/md/0 metadata=1.2 UUID=7341825d:4fe47c6e:bc81bccc:3ff016b6\n
Run Code Online (Sandbox Code Playgroud)\n

更新内核应在启动时加载的模块列表。

\n
echo raid1 >> /etc/modules\n
Run Code Online (Sandbox Code Playgroud)\n

更新启动虚拟盘

\n
update-initramfs -u\n
Run Code Online (Sandbox Code Playgroud)\n

最后退出chroot

\n
exit\n
Run Code Online (Sandbox Code Playgroud)\n

5.克隆EFI分区

\n

至此目标系统安装完成。此外,通过 RAID 设备可以保护主分区免受单个磁盘故障的影响。但是,EFI 启动分区不受 RAID 保护。相反,我们将克隆它。

\n
sudo dd if=/dev/sda1 of=/dev/sdb1 bs=4096\n
Run Code Online (Sandbox Code Playgroud)\n

跑步

\n
$ sudo blkid /dev/sd[ab]1\n/dev/sda1: UUID="108A-114D" TYPE="vfat" PARTLABEL="EFI System" PARTUUID="ccc71b88-a8f5-47a1-9fcb-bfc960a07c16"\n/dev/sdb1: UUID="108A-114D" TYPE="vfat" PARTLABEL="EFI System" PARTUUID="fd070974-c089-40fb-8f83-ffafe551666b"\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,FAT UUID 相同,但 GPT PARTUUID 不同。

\n

6.将第二个磁盘的EFI分区插入启动链

\n

最后,我们需要将第二个磁盘上的 EFI 分区插入引导链。为此,我们将使用efibootmgr.

\n
sudo apt install efibootmgr\n
Run Code Online (Sandbox Code Playgroud)\n

跑步

\n
sudo efibootmgr -v\n
Run Code Online (Sandbox Code Playgroud)\n

并研究输出。应该有一行类似于

\n
Boot0005* ubuntu HD(1,GPT,ccc71b88-a8f5-47a1-9fcb-bfc960a07c16,0x800,0x100000)/File(\\EFI\\ubuntu\\shimx64.efi)\n
Run Code Online (Sandbox Code Playgroud)\n

注意 后面的路径File。跑步

\n
sudo efibootmgr -c -d /dev/sdb -p 1 -L "ubuntu2" -l \'\\EFI\\ubuntu\\shimx64.efi\'\n
Run Code Online (Sandbox Code Playgroud)\n

在分区 1 上创建一个新的启动项,其/dev/sdb路径与该项相同ubuntu。重新运行

\n
sudo efibootmgr -v\n
Run Code Online (Sandbox Code Playgroud)\n

并验证是否存在ubuntu2与以下路径相同的第二个条目ubuntu

\n
Boot0005* ubuntu  HD(1,GPT,ccc71b88-a8f5-47a1-9fcb-bfc960a07c16,0x800,0x100000)/File(\\EFI\\ubuntu\\shimx64.efi)\nBoot0006* ubuntu2 HD(1,GPT,fd070974-c089-40fb-8f83-ffafe551666b,0x800,0x100000)/File(\\EFI\\ubuntu\\shimx64.efi)\n
Run Code Online (Sandbox Code Playgroud)\n

此外,请注意每个条目的 UUID 字符串与上面相应的 PARTUUID 字符串相同。

\n

7. 重新启动

\n

现在我们准备重新启动。检查同步过程是否已完成。

\n
$ cat /proc/mdstat \nPersonalities : [raid1] \nmd0 : active raid1 sdb2[1] sda2[0]\n      1047918528 blocks super 1.2 [2/2] [UU]\n      bitmap: 1/8 pages [4KB], 65536KB chunk\n\nunused devices: <none>\n
Run Code Online (Sandbox Code Playgroud)\n

如果同步仍在进行中,则重新启动应该可以。不过,我建议等到同步完成后再重新启动。

\n

重新启动后,系统应该可以使用了!此外,如果其中一个磁盘发生故障,系统将使用健康磁盘中的 UEFI 分区,并在设备md0处于降级模式的情况下启动 ubuntu。

\n

8. grub-efi-amd64更新后更新EFI分区

\n

当软件包grub-efi-amd64更新时,EFI 分区(安装在 )上的文件/boot/efi可能会发生变化。在这种情况下,必须手动将更新克隆到镜像分区。幸运的是,您应该从即将更新的更新管理器收到警告grub-efi-amd64,因此您不必在每次更新后进行检查。

\n

8.1 查找克隆源的快速方法

\n

如果更新后尚未重新启动,请使用

\n
mount | grep boot\n
Run Code Online (Sandbox Code Playgroud)\n

找出挂载的 EFI 分区。该分区通常/dev/sdb1应用作克隆源。

\n

8.2 找出克隆来源,偏执的方式

\n

创建挂载点并挂载两个分区:

\n
sudo mkdir /tmp/sda1 /tmp/sdb1\nsudo mount /dev/sda1 /tmp/sda1\nsudo mount /dev/sdb1 /tmp/sdb1\n
Run Code Online (Sandbox Code Playgroud)\n

查找每棵树中最新文件的时间戳

\n
sudo find /tmp/sda1 -type f -printf \'%T+ %p\\n\' | sort | tail -n 1 > /tmp/newest.sda1\nsudo find /tmp/sdb1 -type f -printf \'%T+ %p\\n\' | sort | tail -n 1 > /tmp/newest.sdb1\n
Run Code Online (Sandbox Code Playgroud)\n

比较时间戳

\n
cat /tmp/newest.sd* | sort | tail -n 1 | perl -ne \'m,/tmp/(sd[ab]1)/, && print "/dev/$1 is newest.\\n"\'\n
Run Code Online (Sandbox Code Playgroud)\n

应该打印/dev/sdb1 is newest(最有可能)或/dev/sda1 is newest. 该分区应用作克隆源。

\n

在克隆之前卸载分区以避免缓存/分区不一致。

\n
sudo umount /tmp/sda1 /tmp/sdb1\n
Run Code Online (Sandbox Code Playgroud)\n

8.3 克隆

\n

如果/dev/sdb1是克隆源:

\n
sudo dd if=/dev/sdb1 of=/dev/sda1\n
Run Code Online (Sandbox Code Playgroud)\n

如果/dev/sda1是克隆源:

\n
sudo dd if=/dev/sda1 of=/dev/sdb1\n
Run Code Online (Sandbox Code Playgroud)\n

完毕!

\n

9. 虚拟机陷阱

\n

如果您想首先在虚拟机中尝试此操作,则有一些注意事项:显然,保存 UEFI 信息的 NVRAM 在重新启动之间会被记住,但在关闭-重新启动周期之间不会被记住。在这种情况下,您可能最终会进入 UEFI Shell 控制台。以下命令应将您引导至您的计算机/dev/sda1(使用FS1:for /dev/sdb1):

\n
FS0:\n\\EFI\\ubuntu\\grubx64.efi\n
Run Code Online (Sandbox Code Playgroud)\n

UEFI boot in virtualbox - Ubuntu 12.04的最佳答案中的第一个解决方案也可能会有所帮助。

\n