如何在UEFI / GPT系统上安装带有双启动RAID 1分区的Ubuntu 14.04 / 16.04 64位?

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

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

使用桌面安装程序的本指南不起作用,可能是因为它(隐式)假设MBR引导。 也没有安装服务器分发 ,可能是出于同样的原因。

更新:我已经validation下面的描述也适用于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)以启用从RAIDed root启动。
  7. 使用GRUB填充第一个SSD的EFI分区,并将其安装到EFI引导链中。
  8. 将EFI分区克隆到另一个SSD并将其安装到引导链中。
  9. 完成! 您的系统现在将具有RAID 1冗余。 请注意,在内核更新之后,没有什么特别需要做的,因为UEFI分区是不受影响的。

解决方案的第6步的关键组成部分是引导顺序的延迟,否则如果其中任何一个SSD丢失,则会将我直接转移到GRUB提示符(没有键盘!)。

详细的HOWTO

1.开机

从USB记忆棒使用EFI启动。 具体如何因您的系统而异。 选择尝试ubuntu而不安装

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

1.1从另一台计算机登录

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

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

 sudo apt-get install openssh-server 

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

 passwd 

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

 ssh -l ubuntu  

如果您收到有关可疑的中间人攻击的警告,则需要清除用于识别新计算机的ssh密钥。 这是因为openssh-server在安装时会生成新的服务器密钥。 通常打印使用的命令,看起来应该是这样的

 ssh-keygen -f  -R  

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

2.分区磁盘

清除所有旧分区和引导块。 警告! 这会破坏磁盘上的数据!

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

在最小的驱动器上创建新分区:ESP为100M,RAID SWAP为32G,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。 安装它们。 (我不是100%确定这里需要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而不是grub-efi-amd64 。 (见Alecz的评论。)

4.创建RAID分区

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

 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 

validationRAID状态。

 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:  

分区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 

选择Something else作为安装类型,并将md1p1类型修改为ext4 ,格式:yes和mount point /md0p1分区将自动选择为swap。

安装完成后,喝一杯咖啡。

要点:安装完成后,选择继续测试,因为系统尚未启动。

完成RAID设备

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

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

validation所有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:  

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

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 

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

 /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将避免Diskfilter写入不受支持的错误。 禁用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。 添加睡眠脚本

(社区已经建议这个步骤可能是不必要的,可以使用/etc/default/grub GRUB_CMDLINE_LINUX="rootdelay=30"替换。由于本HOWTO底部解释的原因,我建议坚持使用睡眠脚本,即使它比使用rootdelay更丑陋。 因此,我们继续我们的常规程序…

创建一个等待RAID设备稳定的脚本。 如果没有这种延迟, 由于RAID组件未及时完成,root的安装可能会失败 。 我发现这很困难 – 直到我断开其中一个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 (在/dev/sda1上称为EFI/Ubuntu )中安装引导加载程序,并首先将其安装在计算机上的UEFI引导链中。

8.从第二个SSD启用启动

我们差不多完成了。 此时,我们应该可以在sda驱动器上重新启动。 此外, mdadm应该能够处理sdasdb驱动器的故障。 但是,EFI不是RAIDed,因此我们需要克隆它 。

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

除了在第二个驱动器上安装引导加载程序之外,这将使sdb1分区上的FAT32文件系统的UUID(由blkid报告)与sda1/etc/fstab的UUID相匹配。 (注意, /dev/sda1/dev/sdb1分区的UUID仍然不同 – 将ls -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' 

我没有测试它,但可能需要在sdasdb上的ESP之间使用唯一标签(-L)。

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

 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: for /dev/sdb1 ):

 FS0: \EFI\ubuntu\grubx64.efi 

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

模拟磁盘故障

可以使用mdadm模拟任一RAID组件设备的故障。 但是,为了validation引导内容能否在磁盘故障中存在,我不得不关闭计算机并断开磁盘的电源。 如果这样做,请首先确保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:  

在下面的说明中,sdX是失败的设备(X = a或b),sdY是ok设备。

断开驱动器

关闭计算机。 断开驱动器。 重新开始。 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:  

从故障磁盘中恢复

如果您需要更换故障磁盘,则需要遵循此过程。 如果要模拟替换,可以启动到Ubuntu Live会话并使用

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

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

更换磁盘后恢复RAID +引导系统需要执行以下步骤:

  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设备可能仍在同步)!

为什么睡眠脚本?

社区建议添加睡眠脚本可能是不必要的,可以在/etc/default/grub使用GRUB_CMDLINE_LINUX="rootdelay=30" ,然后使用sudo update-grub替换。 这个建议当然更清晰,并且可以在磁盘故障/替换方案中工作。 不过,有一点需要注意……

我断开了我的第二个SSD,发现使用rootdelay=30等,而不是睡眠脚本:
1)系统在没有“故障”驱动器的情况下以降级模式启动。
2)在非降级启动(两个驱动器都存在)中,启动时间减少。 只有第二个驱动器丢失才能感知到延迟。

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

可以说,删除一个完全健康的RAID组件设备,重新启动RAID到降级模式然后重新添加组件设备是一个不切实际的场景:现实情况是一个设备发生故障并被一个新设备取代,让mdadm机会变得更加困惑。 我同意这个论点。 但是,我不知道如何测试系统如何容忍硬件故障,除了实际禁用某些硬件! 经过测试,我想回到一个冗余的工作系统。 (好吧,我可以将我的第二个SSD连接到另一台机器并在重新添加它之前滑动它,但那是不可行的。)

总结:据我所知, rootdelay解决方案干净,比非降级引导的睡眠脚本更快,并且应该适用于真正的驱动器故障/替换方案。 但是,我不知道测试它的可行方法。 所以,暂时,我会坚持丑陋的睡眠剧本。

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

解决许多主板无法正确处理UEFI条目时出现问题的一种可能方法(即使您输入了正确的条目,Debian也无法启动efibootmgr -c -g -d /dev/sda -p 1 -w -L "debian" -l /EFI/debian/grubx64.efi 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”通用引导而没有任何问题。