详细指南

详细指南

更新:以下问题和答案也适用于 Ubuntu 16.04

我有一台配备双 SSD 的计算机,并且在另一个磁盘上预装了 Win (7)。预安装使用 (U)EFI/GPT 启动。我想在我的 SSD 上的 RAID1 根分区上安装 Ubuntu 14.04 64 位桌面,并且仍然能够双启动我的 Win7 系统。这可能吗?

本指南使用桌面安装程序不起作用,可能是因为它(隐式)假设 MBR 启动。安装服务器发行版,可能出于同样的原因。

答案1

更新:我已验证以下描述也适用于 Ubuntu 16.04。其他用户报告称其适用于 17.10 和 18.04.1。

注意:本 HOWTO 不会提供 LVM。如果您也需要 LVM,请尝试在具有 UEFI BIOS 的机器上安装具有 RAID 1 和 LVM 的 Ubuntu 18.04 桌面反而。

经过几天的尝试,我现在有了一个可以运行的系统!简而言之,解决方案包括以下步骤:

  1. 使用 Ubuntu Live CD/USB 启动。
  2. 根据需要对 SSD 进行分区。
  3. 安装缺少的软件包(mdadm 和 grub-efi)。
  4. 创建 RAID 分区。
  5. 运行 Ubiquity 安装程序(但不要启动新系统)。
  6. 修补已安装的系统(initramfs)以便从 RAID 根启动。
  7. 用 GRUB 填充第一个 SSD 的 EFI 分区并将其安装到 EFI 启动链中。
  8. 克隆EFI 分区复制到另一个 SSD 并将其安装到启动链中。
  9. 完成!您的系统现在将具有 RAID 1 冗余。请注意,内核更新等操作后无需执行任何特殊操作,因为 UEFI 分区未受影响。

解决方案第 6 步的一个关键部分是启动顺序的延迟,否则如果任何一个 SSD 丢失,我就会直接进入 GRUB 提示符(没有键盘!)。

详细指南

1. 引导

使用 USB 上的 EFI 启动。具体操作方法将因您的系统而异。选择无需安装即可试用 ubuntu

启动终端仿真器,例如xterm运行以下命令。

1.1 从另一台计算机登录

在尝试这个方法时,我发现从另一台已经完全配置好的计算机登录更容易。这简化了命令的剪切和粘贴等操作。如果您想做同样的事情,您可以通过执行以下操作通过 ssh 登录:

在需要配置的计算机上,安装 openssh 服务器:

sudo apt-get install openssh-server

更改密码。用户的默认密码ubuntu为空。你可以选择一个中等强度的密码。重新启动新计算机后,该密码将被忘记。

passwd

现在您可以从另一台计算机登录 ubuntu live 会话。以下说明适用于 Linux:

ssh -l ubuntu <your-new-computer>

如果您收到有关疑似中间人攻击的警告,则需要清除用于识别新计算机的 ssh 密钥。这是因为openssh-server每次安装时都会生成新的服务器密钥。要使用的命令通常会打印出来,如下所示

ssh-keygen -f <path-to-.ssh/known_hosts> -R <your-new-computer>

执行该命令后,您应该能够登录到 ubuntu live 会话。

2. 分区磁盘

清除所有旧分区和启动块。警告!这将破坏磁盘上的数据!

sudo sgdisk -z /dev/sda
sudo sgdisk -z /dev/sdb

在最小的驱动器上创建新分区:100M 用于 ESP,32G 用于 RAID SWAP,其余用于 RAID root。如果您的 sda 驱动器最小,请按照第 2.1 节操作,否则请按照第 2.2 节操作。

2.1 创建分区表(/dev/sda较小)

执行以下步骤:

sudo sgdisk -n 1:0:+100M -t 1:ef00 -c 1:"EFI System" /dev/sda
sudo sgdisk -n 2:0:+32G -t 2:fd00 -c 2:"Linux RAID" /dev/sda
sudo sgdisk -n 3:0:0 -t 3:fd00 -c 3:"Linux RAID" /dev/sda

将分区表复制到其他磁盘并重新生成唯一的 UUID(实际上将为 sda 重新生成 UUID)。

sudo sgdisk /dev/sda -R /dev/sdb -G

2.2 创建分区表(/dev/sdb较小)

执行以下步骤:

sudo sgdisk -n 1:0:+100M -t 1:ef00 -c 1:"EFI System" /dev/sdb
sudo sgdisk -n 2:0:+32G -t 2:fd00 -c 2:"Linux RAID" /dev/sdb
sudo sgdisk -n 3:0:0 -t 3:fd00 -c 3:"Linux RAID" /dev/sdb

将分区表复制到其他磁盘并重新生成唯一的 UUID(实际上将为 sdb 重新生成 UUID)。

sudo sgdisk /dev/sdb -R /dev/sda -G

2.3 在/dev/sda上创建FAT32文件系统

为 EFI 分区创建 FAT32 文件系统。

sudo mkfs.fat -F 32 /dev/sda1
mkdir /tmp/sda1
sudo mount /dev/sda1 /tmp/sda1
sudo mkdir /tmp/sda1/EFI
sudo umount /dev/sda1

3. 安装缺失的软件包

Ubuntu Live CD 不附带两个关键软件包:grub-efi 和 mdadm。请安装它们。(我不确定这里是否需要 grub-efi,但为了与即将到来的安装保持对称,请也将其带入。)

sudo apt-get update
sudo apt-get -y install grub-efi-amd64 # (or grub-efi-amd64-signed)
sudo apt-get -y install mdadm

如果您启用了安全启动,则可能需要grub-efi-amd64-signed而不是。(请参阅 Alecz 的评论。)grub-efi-amd64

4.创建 RAID 分区

在降级模式下创建 RAID 设备。设备稍后将完成。创建完整的 RAID1 有时会在ubiquity下面的安装过程中给我带来问题,不知道为什么。(安装/卸载?格式化?)

sudo mdadm --create /dev/md0 --bitmap=internal --level=1 --raid-disks=2 /dev/sda2 missing
sudo mdadm --create /dev/md1 --bitmap=internal --level=1 --raid-disks=2 /dev/sda3 missing

验证 RAID 状态。

cat /proc/mdstat

Personalities : [raid1] 
md1 : active raid1 sda3[0]
      216269952 blocks super 1.2 [2/1] [U_]
      bitmap: 0/2 pages [0KB], 65536KB chunk

md0 : active raid1 sda2[0]
      33537920 blocks super 1.2 [2/1] [U_]
      bitmap: 0/1 pages [0KB], 65536KB chunk

unused devices: <none>

对 md 设备进行分区。

sudo sgdisk -z /dev/md0
sudo sgdisk -z /dev/md1
sudo sgdisk -N 1 -t 1:8200 -c 1:"Linux swap" /dev/md0
sudo sgdisk -N 1 -t 1:8300 -c 1:"Linux filesystem" /dev/md1

5. 运行安装程序

运行 Ubiquity 安装程序(不包括引导加载程序)无论如何都会失败。 (笔记:如果您已经通过 ssh 登录,您可能希望在新计算机上执行此操作。)

sudo ubiquity -b

选择其他内容作为安装类型,并将md1p1类型修改为ext4,格式:是 ,以及挂载点/md0p1分区将自动选择为交换。

安装完成时,喝杯咖啡。

重要的:安装完成后,选择继续测试因为系统尚未准备好启动。

完成 RAID 设备

将等待的 sdb 分区附加到 RAID。

sudo mdadm --add /dev/md0 /dev/sdb2
sudo mdadm --add /dev/md1 /dev/sdb3

验证所有 RAID 设备均正常(并且可以选择同步)。

cat /proc/mdstat

Personalities : [raid1] 
md1 : active raid1 sdb3[1] sda3[0]
      216269952 blocks super 1.2 [2/1] [U_]
      [>....................]  recovery =  0.2% (465536/216269952)  finish=17.9min speed=200000K/sec
      bitmap: 2/2 pages [8KB], 65536KB chunk

md0 : active raid1 sdb2[1] sda2[0]
      33537920 blocks super 1.2 [2/2] [UU]
      bitmap: 0/1 pages [0KB], 65536KB chunk

unused devices: <none>

以下过程可能会在同步期间继续,包括重新启动。

6.配置已安装的系统

设置以启用 chroot 进入安装系统。

sudo -s
mount /dev/md1p1 /mnt
mount -o bind /dev /mnt/dev
mount -o bind /dev/pts /mnt/dev/pts
mount -o bind /sys /mnt/sys
mount -o bind /proc /mnt/proc
cat /etc/resolv.conf >> /mnt/etc/resolv.conf
chroot /mnt

配置并安装包。

apt-get install -y grub-efi-amd64 # (or grub-efi-amd64-signed; same as in step 3)
apt-get install -y mdadm

如果您的 md 设备仍在同步,您可能会偶尔看到类似以下警告:

/usr/sbin/grub-probe: warning: Couldn't find physical volume `(null)'. Some modules may be missing from core image..

这是正常的,可以忽略(参见 这个问题)。

nano /etc/grub.d/10_linux
# change quick_boot and quiet_boot to 0

禁用quick_boot将避免不支持磁盘过滤器写入错误。禁用quiet_boot仅出于个人喜好。

修改 /etc/mdadm/mdadm.conf 以删除任何标签引用,即更改

ARRAY /dev/md/0 metadata=1.2 name=ubuntu:0 UUID=f0e36215:7232c9e1:2800002e:e80a5599
ARRAY /dev/md/1 metadata=1.2 name=ubuntu:1 UUID=4b42f85c:46b93d8e:f7ed9920:42ea4623

ARRAY /dev/md/0 UUID=f0e36215:7232c9e1:2800002e:e80a5599
ARRAY /dev/md/1 UUID=4b42f85c:46b93d8e:f7ed9920:42ea4623

这一步可能是不必要的,但我看到一些页面表明命名方案可能不稳定(name=ubuntu:0/1),这可能会阻止在启动过程中组装完好的 RAID 设备。

修改行/etc/default/grub以读取

#GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""

再次强调,这一步可能是不必要的,但我更喜欢睁着眼睛开机……

6.1. 添加睡眠脚本

(社区有人建议这一步可能没有必要,可以使用 来代替GRUB_CMDLINE_LINUX="rootdelay=30"/etc/default/grub出于本 HOWTO 底部解释的原因,我建议坚持使用 sleep 脚本,尽管它比使用 rootdelay 更丑陋。因此,我们继续我们的常规计划......

创建一个等待 RAID 设备稳定下来的脚本。如果没有这个延迟,由于 RAID 组装未及时完成,根安装可能会失败。我费了一番功夫才发现这一点——直到我断开其中一个 SSD 来模拟磁盘故障时,问题才出现!可能需要根据可用硬件(例如速度较慢的外部 USB 磁盘等)调整时间。

在 输入以下代码/usr/share/initramfs-tools/scripts/local-premount/sleepAwhile

#!/bin/sh
echo
echo "sleeping for 30 seconds while udevd and mdadm settle down"
sleep 5
echo "sleeping for 25 seconds while udevd and mdadm settle down"
sleep 5
echo "sleeping for 20 seconds while udevd and mdadm settle down"
sleep 5
echo "sleeping for 15 seconds while udevd and mdadm settle down"
sleep 5
echo "sleeping for 10 seconds while udevd and mdadm settle down"
sleep 5
echo "sleeping for 5 seconds while udevd and mdadm settle down"
sleep 5
echo "done sleeping"

使脚本可执行并安装它。

chmod a+x /usr/share/initramfs-tools/scripts/local-premount/sleepAwhile
update-grub
update-initramfs -u

7. 从第一个 SSD 启用启动

现在系统几乎已经准备好了,只需要安装 UEFI 启动参数。

mount /dev/sda1 /boot/efi
grub-install --boot-directory=/boot --bootloader-id=Ubuntu --target=x86_64-efi --efi-directory=/boot/efi --recheck
update-grub
umount /dev/sda1

/boot/efi/EFI/Ubuntu这将在 中(又名EFI/Ubuntu)安装引导加载程序/dev/sda1,并将其首先安装在计算机的 UEFI 引导链中。

8. 启用从第二个 SSD 启动

我们快完成了。此时,我们应该能够重新启动驱动器sda。此外,mdadm应该能够处理sdasdb驱动器的故障。但是,EFI 没有 RAID,所以我们需要克隆它

dd if=/dev/sda1 of=/dev/sdb1

除了在第二个驱动器上安装引导加载程序之外,这还会使分区上的 FAT32 文件系统的 UUID sdb1(由 报告blkid)与sda1和的 UUID 相匹配。(但请注意,和分区/etc/fstab的 UUID仍然不同 -请在安装后与进行比较以自行检查。)/dev/sda1/dev/sdb1ls -la /dev/disk/by-partuuid | grep sd[ab]1blkid /dev/sd[ab]1

最后,我们必须将sdb1分区插入到启动顺序中。(注意:此步骤可能不是必需的,具体取决于您的 BIOS。我收到报告称,某些 BIOS 会自动生成有效 ESP 列表。)

efibootmgr -c -g -d /dev/sdb -p 1 -L "Ubuntu #2" -l '\EFI\ubuntu\grubx64.efi'

我没有测试过,但可能需要在 ESPsda和之间有唯一的标签 (-L) sdb

这将生成当前启动顺序的打印输出,例如

Timeout: 0 seconds
BootOrder: 0009,0008,0000,0001,0002,000B,0003,0004,0005,0006,0007
Boot0000  Windows Boot Manager
Boot0001  DTO UEFI USB Floppy/CD
Boot0002  DTO UEFI USB Hard Drive
Boot0003* DTO UEFI ATAPI CD-ROM Drive
Boot0004  CD/DVD Drive 
Boot0005  DTO Legacy USB Floppy/CD
Boot0006* Hard Drive
Boot0007* IBA GE Slot 00C8 v1550
Boot0008* Ubuntu
Boot000B  KingstonDT 101 II PMAP
Boot0009* Ubuntu #2

请注意,Ubuntu #2 (sdb) 和 Ubuntu (sda) 在启动顺序中是第一位的。

重启

现在我们准备重新启动。

exit # from chroot
exit # from sudo -s
sudo reboot

系统现在应该重新启动进入 Ubuntu(您可能必须先删除 Ubuntu Live 安装媒体。)

启动后你可以运行

sudo update-grub

将 Windows 引导加载程序附加到 grub 引导链。

虚拟机陷阱

如果您想先在虚拟机中尝试这一点,请注意以下几点:显然,保存 UEFI 信息的 NVRAM 会在重启之间被记住,但不会记住关机-重启周期之间的信息。在这种情况下,您可能会进入 UEFI Shell 控制台。以下命令应会将您引导到您的计算机/dev/sda1(使用FS1:/dev/sdb1

FS0:
\EFI\ubuntu\grubx64.efi

最佳答案中的第一个解决方案虚拟机中的 UEFI 启动 - Ubuntu 12.04也可能有帮助。

模拟磁盘故障

可以使用 模拟任一 RAID 组件设备的故障mdadm。但是,为了验证启动内容能否在磁盘故障后继续存在,我必须关闭计算机并断开磁盘的电源。如果这样做,首先确保 md 设备已同步

cat /proc/mdstat 

Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] 
md1 : active raid1 sdb3[2] sda3[0]
      216269952 blocks super 1.2 [2/2] [UU]
      bitmap: 2/2 pages [8KB], 65536KB chunk

md0 : active raid1 sda2[0] sdb2[2]
      33537920 blocks super 1.2 [2/2] [UU]
      bitmap: 0/1 pages [0KB], 65536KB chunk

unused devices: <none>

在下面的说明中,sdX 是故障设备(X=a 或 b),sdY 是正常设备。

断开驱动器

关闭计算机。断开驱动器。重新启动。Ubuntu 现在应该以降级模式启动 RAID 驱动器。(庆祝!这就是您想要实现的目标!;)

cat /proc/mdstat 

Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] 
md1 : active raid1 sda3[0]
      216269952 blocks super 1.2 [2/1] [U_]
      bitmap: 2/2 pages [8KB], 65536KB chunk

md0 : active raid1 sda2[0]
      33537920 blocks super 1.2 [2/1] [U_]
      bitmap: 0/1 pages [0KB], 65536KB chunk

unused devices: <none>

从故障磁盘恢复

如果您需要更换故障磁盘,请按照此过程操作。如果您想模拟更换,可以启动 Ubuntu Live 会话并使用

dd if=/dev/zero of=/dev/sdX

在重新引导进入实际系统之前将磁盘清除干净。如果您刚刚在上面的部分中测试了启动/RAID 冗余,则可以跳过此步骤。但是,您必须至少执行下面的步骤 2 和 4 才能恢复系统的完整启动/RAID 冗余。

更换磁盘后恢复 RAID+boot 系统需要以下步骤:

  1. 对新驱动器进行分区。
  2. 将分区添加到 md 设备。
  3. 克隆启动分区。
  4. 为克隆添加 EFI 记录。

1. 对新驱动器进行分区

从健康的驱动器复制分区表:

sudo sgdisk /dev/sdY -R /dev/sdX

在新驱动器上重新随机化 UUID。

sudo sgdisk /dev/sdX -G

2.添加到md设备

sudo mdadm --add /dev/md0 /dev/sdX2
sudo mdadm --add /dev/md1 /dev/sdX3

3.克隆启动分区

从健康驱动器克隆 ESP。(小心,如​​果真的搞砸了,也许需要先对两个 ESP 进行转储到文件,以便进行恢复。)

sudo dd if=/dev/sdY1 of=/dev/sdX1

4. 将新恢复的磁盘插入启动顺序

为克隆添加 EFI 记录。根据需要修改 -L 标签。

sudo efibootmgr -c -g -d /dev/sdX -p 1 -L "Ubuntu #2" -l '\EFI\ubuntu\grubx64.efi'

现在,重新启动系统应该可以恢复正常(RAID 设备可能仍在同步)!

为什么要使用睡眠脚本?

社区建议添加 sleep 脚本可能没有必要,可以使用GRUB_CMDLINE_LINUX="rootdelay=30"in/etc/default/grub后跟 来代替sudo update-grub。这个建议当然更简洁,并且在磁盘故障/更换情况下确实有效。但是,有一个警告...

我断开了第二个 SSD 的连接,发现使用rootdelay=30等代替睡眠脚本:
1) 系统确实会在降级模式下启动,而不会出现“故障”驱动器。2
) 在非降级启动(两个驱动器都存在)中,启动时间会缩短。只有在第二个驱动器丢失的情况下,延迟才会明显。

1) 和 2) 听起来不错,直到我重新添加了第二个驱动器。在启动时,RAID 阵列无法组装,让我initramfs不知道该怎么做。也许可以通过 a) 启动到 Ubuntu Live USB 棒,b) 安装mdadm和 c) 手动重新组装阵列来挽救这种情况,但是……我搞砸了某个地方。相反,当我重新运行此测试时睡眠脚本(是的,我确实第 n 次从顶部启动了 HOWTO……),系统做过启动。阵列处于降级模式,我可以手动重新添加/dev/sdb[23]分区,而无需任何额外的 USB 记忆棒。我不知道为什么睡眠脚本可以工作而rootdelay不能。也许是mdadm被两个稍微不同步的组件设备混淆了,但我认为mdadm它是为了处理这个问题而设计的。无论如何,既然睡眠脚本可以工作,我就会坚持使用它。

有人可能会说,移除一个完全健康的 RAID 组件设备,将 RAID 重新启动到降级模式,然后重新添加组件设备是一种不切实际的情况:现实情况是,一个设备发生故障,被一个新设备取代,这样mdadm混淆的可能性就更小了。我同意这个说法。但是,除了实际禁用某些硬件之外,我不知道如何测试系统如何容忍硬件故障!测试后,我想回到一个冗余的、正常工作的系统。(好吧,我可以将我的第二块 SSD 连接到另一台机器,然后在重新添加之前对其进行刷卡,但这是不可行的。)

总结:据我所知,该rootdelay解决方案很简洁,比非降级启动的睡眠脚本更快,并且应该适用于真正的驱动器故障/更换场景。但是,我不知道可行的测试方法。所以,暂时,我将坚持使用丑陋的睡眠脚本。

答案2

我的建议是针对 Debian 操作系统,但我认为它也适用于 Ubuntu 和其他操作系统。

解决许多主板无法正确处理 UEFI 条目的问题(即使您输入了正确的条目,Debian 也无法启动efibootmgr -c -g -d /dev/sda -p 1 -w -L "debian" -l /EFI/debian/grubx64.efi,UEFI BIOS 显示“debian”可启动磁盘但无法从中启动)的一种可能方法是使用通用条目/boot/efi/EFI/boot/bootx4.efi

例如华硕Z87C就不喜欢/EFI/debian/grubx64.efi

因此,如果您将 efi 分区挂载/dev/sda1/boot/efi路径:

mkdir /boot/efi/EFI/boot
cp /boot/efi/EFI/debian/grubx64.efi /boot/efi/EFI/boot/bootx4.efi

然后重新启动。

UEFI BIOS 将看到“UEFI OS”通用磁盘,以及任何其他先前使用 efibootmgr 创建的条目,但它可以从“UEFI OS”通用磁盘启动而不会出现任何问题。

相关内容