答案1
经过几周的实验,并在此链接,我终于找到了一个可行的解决方案。下面的顺序是使用 Ubuntu 20.04.2.0 LTS 执行的。我也在虚拟机中使用 21.04.0 成功完成了该过程。(但是,请注意,有一个报告的问题使用 Ubuntu 21.04 和一些较旧的 UEFI 系统。
简而言之
- 下载并启动 Ubuntu Live 20.04。
- 设置 mdadm 和 lvm。
- 运行 Ubuntu 安装程序,但不要重新启动。
- 将 mdadm 添加到目标系统。
- 将 EFI 分区克隆到第二个驱动器。
- 将第二个 EFI 分区安装到 UEFI 启动链中。
- 重启
详细
1. 下载安装程序并启动 Ubuntu Live
1.1 下载
- 从以下位置下载 Ubuntu 桌面安装程序https://ubuntu.com/download/desktop并将其放到可启动媒体上。(截至 2021-12-13,该 iso 被称为 ubuntu-20.04.3-desktop-amd64.iso。)
1.2 启动 Ubuntu Live
- 从步骤 1.1 启动到媒体。
- 选择
Try Ubuntu
。 - 按 Ctrl-Alt-T 启动终端。以下命令应在该终端中输入。
2.设置 mdadm 和 lvm
在下面的例子中,磁盘设备被称为/dev/sda
和/dev/sdb
。如果您的磁盘有其他名称,例如/dev/nvme0n1
和/dev/sdb
,则应相应地替换磁盘名称。您可以使用sudo lsblk
来查找磁盘的名称。
2.0 安装 ssh 服务器
如果您不想输入以下所有命令,您可以安装通过 ssh 登录并剪切粘贴命令。
安装
sudo apt install openssh-server
设置密码以启用外部登录
passwd
如果您在虚拟机内测试此操作,则可能需要转发合适的端口。选择
Settings
、Network
、Advanced
、Port forwarding
和加号。例如,输入3022
作为Host Port
和22
作为 Guest Port 并按OK
。或者从主机系统的命令行(将 VMNAME 替换为您的虚拟机名称):VBoxManage modifyvm VMNAME --natpf1 "ssh,tcp,,3022,,22" VBoxManage showvminfo VMNAME | grep 'Rule'
现在,你应该能够使用以下命令从外部计算机登录到你的 Ubuntu Live 会话
ssh <hostname> -l ubuntu
或者,如果你在虚拟机上进行测试localhost
,
ssh localhost -l ubuntu -p 3022
以及您上面设置的密码。
2.1 在物理磁盘上创建分区
将分区表清零
sudo sgdisk -Z /dev/sda sudo sgdisk -Z /dev/sdb
在每个驱动器上创建两个分区;一个用于 EFI,一个用于 RAID 设备。
sudo sgdisk -n 1:0:+512M -t 1:ef00 -c 1:"EFI System" /dev/sda sudo sgdisk -n 2:0:0 -t 2:fd00 -c 2:"Linux RAID" /dev/sda sudo sgdisk -n 1:0:+512M -t 1:ef00 -c 1:"EFI System" /dev/sdb sudo sgdisk -n 2:0:0 -t 2:fd00 -c 2:"Linux RAID" /dev/sdb
为第一个驱动器上的 EFI 分区创建 FAT32 系统。(稍后将克隆到第二个驱动器。)
sudo mkfs.fat -F 32 /dev/sda1
2.2 安装mdadm并创建md设备
安装mdadm
sudo apt-get update
sudo apt-get install mdadm
创建 md 设备。忽略有关元数据的警告,因为该阵列不会用作启动设备。
sudo mdadm --create /dev/md0 --bitmap=internal --level=1 --raid-disks=2 /dev/sda2 /dev/sdb2
检查md设备的状态。
$ cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sdb2[1] sda2[0]
1047918528 blocks super 1.2 [2/2] [UU]
[>....................] resync = 0.0% (1001728/1047918528) finish=69.6min speed=250432K/sec
bitmap: 8/8 pages [32KB], 65536KB chunk
unused devices: <none>
在这种情况下,设备正在同步磁盘,这是正常的,并且可能会在下面的过程中在后台继续。
2.4 对 md 设备进行分区
sudo sgdisk -Z /dev/md0
sudo sgdisk -n 1:0:0 -t 1:E6D6D379-F507-44C2-A23C-238F2A3DF928 -c 1:"Linux LVM" /dev/md0
/dev/md0p1
这会在设备上创建一个分区/dev/md0
。UUID 字符串标识该分区是 LVM 分区。
2.3 创建LVM设备
在 md 设备上创建物理卷
sudo pvcreate /dev/md0p1
在物理卷上创建卷组
sudo vgcreate vg0 /dev/md0p1
在新卷组上创建逻辑卷(分区)。以下大小和名称是我的选择。您可以做出不同的决定。
sudo lvcreate -Z y -L 25GB --name root vg0 sudo lvcreate -Z y -L 10GB --name tmp vg0 sudo lvcreate -Z y -L 5GB --name var vg0 sudo lvcreate -Z y -L 10GB --name varlib vg0 sudo lvcreate -Z y -L 200GB --name home vg0
现在,分区已准备好安装 Ubuntu 安装程序。
3. 运行安装程序
- 双击
Install Ubuntu 20.04.2.0 LTS
新计算机桌面上的图标。(请勿不是通过任何 ssh 连接启动安装程序!) - 回答语言和键盘问题。
- 在
Installation type
页面上,选择。 (这是重要的部分。)这将向您显示名为等的Something else
分区列表。/dev/mapper/vg0-home
- 双击以 开头的每个分区
/dev/mapper/vg0-
。选择Use as:
Ext4
,选中Format the partition
复选框,然后选择适当的挂载点(/
对于vg0-root
,/home
对于vg0-home
,等等,/var/lib
对于vg0-varlib
)。 /dev/sda
选择引导加载程序的第一个设备。- 按下
Install Now
并继续安装。 - 安装完成后,选择
Continue Testing
。
在终端中运行lsblk
。输出应类似以下内容:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
...
sda 8:0 0 1000G 0 disk
├─sda1 8:1 0 512M 0 part
└─sda2 8:2 0 999.5G 0 part
└─md0 9:0 0 999.4G 0 raid1
└─md0p1 259:0 0 999.4G 0 part
├─vg0-root 253:0 0 25G 0 lvm /target
├─vg0-tmp 253:1 0 10G 0 lvm
├─vg0-var 253:2 0 5G 0 lvm
├─vg0-varlib 253:3 0 10G 0 lvm
└─vg0-home 253:4 0 200G 0 lvm
sdb 8:16 0 1000G 0 disk
├─sdb1 8:17 0 512M 0 part
└─sdb2 8:18 0 999.5G 0 part
└─md0 9:0 0 999.4G 0 raid1
└─md0p1 259:0 0 999.4G 0 part
├─vg0-root 253:0 0 25G 0 lvm /target
├─vg0-tmp 253:1 0 10G 0 lvm
├─vg0-var 253:2 0 5G 0 lvm
├─vg0-varlib 253:3 0 10G 0 lvm
└─vg0-home 253:4 0 200G 0 lvm
...
如您所见,安装程序将已安装系统的根目录挂载到/target
。但是,其他分区尚未挂载。更重要的是,mdadm
还不是已安装系统的一部分。
4. 将 mdadm 添加到目标系统
4.1 chroot 进入目标系统
首先,我们必须挂载未挂载的分区:
sudo mount /dev/mapper/vg0-home /target/home
sudo mount /dev/mapper/vg0-tmp /target/tmp
sudo mount /dev/mapper/vg0-var /target/var
sudo mount /dev/mapper/vg0-varlib /target/var/lib
接下来绑定一些设备以做准备chroot
……
cd /target
sudo mount --bind /dev dev
sudo mount --bind /proc proc
sudo mount --bind /sys sys
...并chroot
进入目标系统。
sudo chroot .
4.2 更新目标系统
现在我们进入目标系统。安装mdadm
apt install mdadm
如果出现 DNS 错误,请执行以下操作
echo "nameserver 1.1.1.1" >> /etc/resolv.conf
并重复
apt install mdadm
您可以忽略有关管道泄漏的任何警告。
检查配置文件/etc/mdadm/mdadm.conf
。它应该包含一行类似于
ARRAY /dev/md/0 metadata=1.2 UUID=7341825d:4fe47c6e:bc81bccc:3ff016b6 name=ubuntu:0
删除该name=...
部分,使行显示如下
ARRAY /dev/md/0 metadata=1.2 UUID=7341825d:4fe47c6e:bc81bccc:3ff016b6
更新内核在启动时应加载的模块列表。
echo raid1 >> /etc/modules
更新启动 ramdisk
update-initramfs -u
最后退出 chroot
exit
5. 克隆 EFI 分区
现在,安装的目标系统已完成。此外,主分区通过 RAID 设备受到保护,以免发生单个磁盘故障。但是,EFI 启动分区不受 RAID 保护。相反,我们将克隆它。
sudo dd if=/dev/sda1 of=/dev/sdb1 bs=4096
跑步
$ sudo blkid /dev/sd[ab]1
/dev/sda1: UUID="108A-114D" TYPE="vfat" PARTLABEL="EFI System" PARTUUID="ccc71b88-a8f5-47a1-9fcb-bfc960a07c16"
/dev/sdb1: UUID="108A-114D" TYPE="vfat" PARTLABEL="EFI System" PARTUUID="fd070974-c089-40fb-8f83-ffafe551666b"
请注意,FAT UUID 相同,但 GPT PARTUUID 不同。
6.将第二个磁盘的 EFI 分区插入启动链
最后,我们需要将第二个磁盘上的 EFI 分区插入到启动链中。为此,我们将使用efibootmgr
。
sudo apt install efibootmgr
跑步
sudo efibootmgr -v
并研究输出。应该有一行类似于
Boot0005* ubuntu HD(1,GPT,ccc71b88-a8f5-47a1-9fcb-bfc960a07c16,0x800,0x100000)/File(\EFI\ubuntu\shimx64.efi)
注意后面的路径File
。运行
sudo efibootmgr -c -d /dev/sdb -p 1 -L "ubuntu2" -l '\EFI\ubuntu\shimx64.efi'
在分区 1 上创建一个新的启动项,其/dev/sdb
路径与该项相同ubuntu
。重新运行
sudo efibootmgr -v
并验证是否存在ubuntu2
与 相同的路径的第二个条目ubuntu
:
Boot0005* ubuntu HD(1,GPT,ccc71b88-a8f5-47a1-9fcb-bfc960a07c16,0x800,0x100000)/File(\EFI\ubuntu\shimx64.efi)
Boot0006* ubuntu2 HD(1,GPT,fd070974-c089-40fb-8f83-ffafe551666b,0x800,0x100000)/File(\EFI\ubuntu\shimx64.efi)
此外,请注意每个条目的 UUID 字符串与上面相应的 PARTUUID 字符串相同。
7. 重启
现在我们可以重启了。检查同步过程是否已完成。
$ cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sdb2[1] sda2[0]
1047918528 blocks super 1.2 [2/2] [UU]
bitmap: 1/8 pages [4KB], 65536KB chunk
unused devices: <none>
如果同步仍在进行中,则应该重启就可以了。不过我建议等到同步完成后再重启。
重启后,系统就可以使用了!此外,如果任何一个磁盘出现故障,系统将使用健康磁盘的 UEFI 分区,并md0
在降级模式下使用设备启动 ubuntu。
8. 更新 grub-efi-amd64 后更新 EFI 分区
更新软件包时grub-efi-amd64
,EFI 分区(安装在 )上的文件/boot/efi
可能会发生变化。在这种情况下,必须手动将更新克隆到镜像分区。幸运的是,您应该会收到即将更新的更新管理器警告grub-efi-amd64
,因此您不必在每次更新后都进行检查。
8.1 查找克隆源,快捷方法
如果更新后尚未重启,请使用
mount | grep boot
找出已安装的 EFI 分区。通常/dev/sdb1
,该分区应用作克隆源。
8.2 找出克隆源,偏执的方式
创建挂载点并挂载两个分区:
sudo mkdir /tmp/sda1 /tmp/sdb1
sudo mount /dev/sda1 /tmp/sda1
sudo mount /dev/sdb1 /tmp/sdb1
在每个树中查找最新文件的时间戳
sudo find /tmp/sda1 -type f -printf '%T+ %p\n' | sort | tail -n 1 > /tmp/newest.sda1
sudo find /tmp/sdb1 -type f -printf '%T+ %p\n' | sort | tail -n 1 > /tmp/newest.sdb1
比较时间戳
cat /tmp/newest.sd* | sort | tail -n 1 | perl -ne 'm,/tmp/(sd[ab]1)/, && print "/dev/$1 is newest.\n"'
应该打印/dev/sdb1 is newest
(最有可能)或/dev/sda1 is newest
。该分区应该用作克隆源。
克隆之前卸载分区以避免缓存/分区不一致。
sudo umount /tmp/sda1 /tmp/sdb1
8.3 克隆
如果/dev/sdb1
是克隆源:
sudo dd if=/dev/sdb1 of=/dev/sda1
如果/dev/sda1
是克隆源:
sudo dd if=/dev/sda1 of=/dev/sdb1
完毕!
9. 虚拟机陷阱
如果您想先在虚拟机中尝试这一点,请注意以下几点:显然,保存 UEFI 信息的 NVRAM 会在重启之间被记住,但不会记住关机-重启周期之间的信息。在这种情况下,您可能会进入 UEFI Shell 控制台。以下命令应会将您引导到您的计算机/dev/sda1
(使用FS1:
)/dev/sdb1
:
FS0:
\EFI\ubuntu\grubx64.efi
最佳答案中的第一个解决方案虚拟机中的 UEFI 启动 - Ubuntu 12.04也可能有帮助。
答案2
抱歉。我的反馈显然不清楚,所以再次说明。问题是“是否有人有适用于 20.04 的流程,在 UEFI 机器上使用 RAID 1 上的 LVM?”
我的“答案”是,步骤 1-7 中给出的说明既准确又恰当——非常感谢——但我在 20.04 上遇到了困难,因为它不支持我现代主板的 XID 641 板载显卡。我尝试使用 21.10 台式机,没有任何问题。请注意,我事先在 BIOS 中将 SATA 从 RAID 切换到 AHCI,并等待同步在第 7 步完成,否则,这是一个轻松的过程。目标机器是 Ryzen 9 5950X、ASUS Crosshair VIII Hero 主板、2x8TB 光盘。
答案3
这些是出色的详细说明。我只想补充一点,22.10 和 23.04 的桌面安装程序不支持 raid 或 LVM。它看不到以这种方式创建的分区/文件系统。解决方案是切换到服务器安装程序。安装服务器后,您可以执行“sudo apt install ubuntu-desktop”以及安装任何其他驱动程序(例如 nvidia)。
答案4
如果你使用 Niclas Börlin 的回答,考虑使用 rsync 而不是 dd:
mkdir mnt
sudo mount /dev/sd?1 mnt #whichever of sda1 or sdb1 is not mounted at /boot/efi
sudo rsync -av --delete /boot/efi/ mnt
sudo umount mnt
这样,如果您混淆了驱动器内容,就不可能意外覆盖它们。