第十一章:复杂安装

FreeBSD存储系统的强大之处不在于单个工具,而在于如何组合它们。在本章中,我们将处理更高级的任务,以创建和自动化自定义FreeBSD安装。

如果你有很多FreeBSD机器要安装,比如在一个服务器场,直接转到PC-BSD安装程序。PC-BSD允许您创建适合装配线部署的安装脚本。当你使用FreeBSD构建下一个Tinder时,这就是你想要的。

如果你只是偶尔安装机器,并且希望能够定制那些超出FreeBSD安装程序允许的安装,本章将为你提供帮助。

第十一章:复杂安装安装到 Gmirror先决条件分区过程分配分区方案配置Geoms创建分区创建分区表启动器创建文件系统临时挂载安装后设置手动安装FreeBSD安装内核高级配置脚本安装通过安装介质联网安装脚本完整的磁盘加密独立驱动器分区单磁盘分区安装 /boot安装加密分区安装后设置和管理扩展虚拟磁盘后记

安装到 Gmirror

FreeBSD安装程序为您提供了手动分区硬盘的机会。您可以安装到可由您的体系结构引导的任何类型的分区。我将使用 gmerror(8) 安装作为示例来演示这一点。

先决条件

启动计算机必须找到操作系统内核,否则无法启动。BIOS在不熟悉的磁盘上找不到分区,可悲的是,很少有BIOS理解FreeBSD的GEOM类。至少,硬件的BIOS必须能够找到 /boot 分区并加载内核。BIOS可以理解单磁盘和镜像磁盘,但无法识别RAID-3、RAID-5、RAID-10或其他更复杂的磁盘冗余协议。

为了克服这一限制,可以在镜像驱动器上放置 /boot ,然后将 //usr 和所有其他文件放在RAID-5上,或者以其他方式放置。我们将在本章稍后看到一个这样的例子。

FreeBSD安装程序不会为你镜像磁盘,必须自己做。

分区过程

启动安装程序,然后进入安装过程。指定主机名并选择要安装的软件。在分区阶段,将有机会使用引导方法、手动方法或命令行。对于复杂的安装,需要进入命令行状态。

按以下步骤准备磁盘以成功安装:

分区挂载之后,可以让安装程序继续。安装过程的结尾,升级新的 /boot/loader.conf 文件使得系统启动时自动挂载gmirror内核模块。

让我们按顺序看每一步。

分配分区方案

使用 geom disk listcamcontrol devlist 命令来识别所有的磁盘。假设测试机器有两个磁盘,da0da1 。我想镜像它们。先删除磁盘上的任何分区方案,并分配所需的方案:

现在磁盘准备好用于镜像了。

配置Geoms

现在在两个磁盘上创建一个镜像。这需要先加载 gmirror(8) 模块,标识一个磁盘,然后插入另一块磁盘到镜像中。

镜像盘将开始同步。可以等它结束,也可以在安装过程结束后等待。或者可以忽略它,继续前进。

创建分区

我希望服务器上有分区,因此需要在镜像geom上有一个GPT表。这台机器为引导加载程序获得一个512KB的分区,一个8GB的交换分区,5GB的根目录,1GB的 /tmp 和5GB的 /var ,其余分配给 /usr 。我希望每个分区都有一个GPT标签,所有内容都以最接近的兆字节对齐。

现在可以在镜像中创建文件系统了。

注意,我们将这些分区放置在镜像上,而不是底层磁盘上。当写入镜像的分区表时,gmirror会将其传递到每一个单独磁盘上的相同分区表。启动计算机在其中一个磁盘上找到GPT分区表,并使用它来查找内核。即使机器进入单用户模式,镜像设备也会配置并准备就绪。

创建分区表

FreeBSD安装程序使用 /tmp/bsdinstall_etc 保存临时文件。其中一个临时文件是文件系统表 /etc/fstab 。我建议在创建分区后立即创建文件系统表,以便它们在内存中保持新鲜。创建包含以下内容的 /tmp/bsdinstall_etc/fstab

还可以根据需求添加可移动媒体(标记为 noauto )或其他设备,或加密交换空间,或网络共享设备,无论您想要什么。

当安装程序恢复时,它会把此文件复制到已完成的系统上。

启动器

镜像的两个驱动器都需要引导器,以放置其中一个发生故障。通常将此引导加载程序写入镜像,将其放在每一个磁盘上。

镜像将引导器和保护MBR直接复制到底层磁盘上。

创建文件系统

现在在分区创建需要的文件系统。我使用GPT标签取代完整的设备节点:

-j 选项激活软更新日志,-L 选项套用UFS标签。UFS标签与GPT标签相同。

【将 /dev/label/usr 设置为与 /dev/gpt/root 相同的设备是确保没有人试图多次管理您的系统的好方法。】

临时挂载

安装程序希望目标文件系统安装在 /mnt 下。先挂载新的根分区。

为每个挂载点创建目录:

创建完目录后,将空的文件系统挂载到对应目录上:

您的自定义分区现已准备就绪。在命令提示符下键入 exit 返回安装程序,安装程序将开始将FreeBSD解压缩到磁盘上。

安装后设置

当设置了root密码、配置了时区并添加了初始用户,FreeBSD会询问是否想在系统中打开一个shell进行任何最终的手动更改,回答 yes

现在处于已完成安装的chroot中。新机器的根目录不再是 /mnt ,而是 / 。进入 /boot 目录并创建 loader.conf 文件,其中应包含以下行:

验证镜像是否已完成同步,然后重启系统。

手动安装FreeBSD

等一下!如果你在命令行中手动分区磁盘并创建文件系统,你不能自己安装FreeBSD文件而不通过安装程序吗?

为什么。是的,你可以。【Why yes. Yes you can.】

安装内核

FreeBSD需要的文件都在安装介质的 /usr/freebsd-dist 目录中。现在我们安装base和kernel到新根文件系统中,它挂载在 /mnt 上。

base和kernel是唯一必须的组件,但可以根据需要从该目录安装其他组件。在amd64上,建议安装32位库(lib32.txz)。无论如何,我更喜欢用 portsnap(8) 安装端口集合。如果我需要游戏或源代码,我稍后会回来取。【postsnap 基础架构将在13.x的EOL后删除,到期日为2026年4月30日】

新安装需要文件系统表,/etc/fstab 。建议在创建分区时创建文件系统表。如果是手动安装FreeBSD,则必须将文件系统表复制到新安装中:

或者直接在 /mnt/etc/fstab 中创建它。

系统现在拥有从硬盘启动所需的一切。它没有用户,没有root密码,也没有配置。这对很多人来说已经足够了,但我们可以做到更好。

高级配置

如果你想让手动安装的机器启动到一切都设置好的状态,可以编辑一些文件,比如 /etc/rc.conf 文件(安装过程中,它可能位于 /mnt/etc/rc.conf )。

有些命令只能在运行中的系统上才能正常工作,比如 adduser(8) ,它只将用户添加到 /etc 的密码文件中。这就是调用 chroot(8) 魔力的时候:

现在已经进入新安装,允许 adduser(8) 会影响新安装,而不是安装介质。

键入 exit 退出chroot完成设置,然后重新启动以进行新安装。

脚本安装

FreeBSD安装程序使脚本磁盘分区和安装后设置变得相当简单。它仍然需要一些手动步骤和人工交互,但您可以编写复杂的脚本并减少用户错误。同样,如果你有很多服务器要安装,PC-BSD有一个完整的FreeBSD安装自动化工具。

脚本安装带来了两个小挑战:让网络运行和创建实际的脚本。两者都不难。

通过安装介质联网

虽然FreeBSD有几个实时CD版本,但我更喜欢直接跳到安装介质。虽然安装介质不是最简单的桌面环境,但我相信你有它,它总是适用于你想要安装的版本。如果你想使用不同的live CD,请使用基于你正在安装的FreeBSD版本的CD。

启动安装介质,当遇到选择执行安装还是转到shell时,请选择shell。这将启动命令提示符。

将安装脚本安装到计算机上的最简单方法是通过网络。这意味着需要一个解析器配置 /etc/resolv.conf 。安装介质的 /etc 目录是只读介质,因此无法直接创建。

使用 mount_unionfs(8) 将目录覆盖在另一个目录上。创建一个 /tmp/etc 目录,并将其挂载到现有 /etc 目录上:

现在可以创建 /tmp/etc/resolv.conf 文件并配置名称服务器(nameserver),它将会出现在 /etc 目录中。

联网之后使用 fetch(1) 命令获取安装脚本:

现在,你所需要的就是一个安装脚本了。

安装脚本

安装脚本包括创建geom和文件系统,并将FreeBSD解压到其中所需要的所有命令的列表。下面显示了一个示例脚本。我的网站上这本书的清单上也有这个脚本,而不是让你把它打出来(https://www.michaelwlucas.com,在“nonfiction”下)。

虽然我本可以在这个脚本中放入各种echo语句,但我更喜欢使用 -x 参数运行shell,这样shell在运行命令时就会打印出来。

虽然此脚本满足我的需求,但您可能希望根据您的环境对其进行自定义。此脚本做的最后一件事是打印镜像状态,提醒我必须在重新启动之前让磁盘同步。

此脚本也不会添加本地用户或设置根密码。您不能在脚本执行到一半时运行 chroot(8) 命令,然后让脚本继续执行。如有必要,您可以编写第二个脚本,将其复制到 /mnt ,chroot到新系统中,然后运行该脚本。

安装脚本还可以将关键系统文件复制到服务器,以预配置SSH和LDAP等服务。

完整的磁盘加密

无法完全加密计算机上的所有内容。每个系统都需要足够的未加密代码来告诉它如何解密加密的驱动器。在FreeBSD上,使用GELI进行加密,需要一个未加密的 /boot 目录,其中包含内核和GELI密钥文件。可以在只读介质(如CD)、可移动介质(如U盘)或主硬盘上的小分区上进行启动。可以加密此启动介质之外的所有内容。

FreeBSD安装程序允许您使用主硬盘上的一个小分区,使用单个大型文件系统创建加密的ZFS安装。如果你需要的不是安装程序给你的东西——比如说,如果你想要UFS,或者你想要一个细粒度的ZFS安装——你必须手动安装。

第一个问题是,您希望将未加密的启动驱动器放在哪里?您可以使用主硬盘上的小分区或单独的设备,如USB闪存驱动器。1GB未加密的驱动器将为您提供足够的升级空间。

如果你想把 /boot 分区放在只读介质上,比如CD,你会有一些额外的步骤。安装程序需要将文件写入 /boot ,但不能写入CD-R。如果您打算使用只读介质进行 /boot ,请先使用 /boot 的闪存驱动器进行安装。安装完成后,将闪存驱动器上的文件复制到可引导CD上。

我的测试系统有一个256GB的驱动器。无论哪种情况,我的目标都是有一个4GB的交换分区,以及运行加密FreeBSD安装的引导分区未使用的任何剩余空间。

在任何一种情况下,首先启动要安装的版本的FreeBSD安装介质,然后选择Shell。

独立驱动器分区

测试系统有一个256GB的主硬盘(da0)需要被加密,和另一个8GB的第二个硬盘(da1)不需要被加密。首先销毁驱动器上所有分区,然后创建新的方案:

驱动器现在已清除所有以前的文件系统,并准备好进行GPT分区。现在,我们将在每个分区上创建两个新分区。未加密的驱动器需要一个引导分区和一个FreeBSD UFS分区。(即使你使用ZFS作为主磁盘,/boot 也很小,而且大多是静态的,所以这样做没有多大意义。)

使用 gpart show 命令核查结果。应该有一个引导加载器分区和一个用于未加密文件系统的分区。现在安装PMBR和GPT引导加载器:

至此,引导驱动器完成了分区。接下来对主驱动器进行分区。

出于稍后将变得明显的原因,我使用分区 3 作为交换,分区 4 作为加密设备。此专用驱动器上的分区 12 未使用。

现在我们有四个GPT分区分别位于这两个磁盘上:

单磁盘分区

要将所有内容放在一个磁盘上,必须创建四个分区:引导代码分区、/boot 分区、加密交换分区、加密文件系统分区。首先销毁磁盘的现有分区,并为GPT分区做准备。我们再次使用这个265GB磁盘。

系统需要一个未加密的启动器,包含PMBR和GPT启动代码。

/boot 创建分区 2 。这个分区只需要1GB空间。我们使用1MB对齐,以便在磁盘的开头有一点额外的空间。特别希望 /boot 位于分区 2 。分区 3 有4GB空间,用于交换。其余部分用GELI加密。

此时这个磁盘有四个分区:

安装 /boot

设置的其余部分归结为配置引导驱动器、配置GELI、创建文件系统以及在磁盘上安装FreeBSD。我们将首先创建引导驱动器,这样就有了一个放置关键文件的地方。在 /media 上挂载新分区,并将安装 /boot 目录复制到其中。

现在应该有了一个填充的 /mnt/boot 目录。进入该目录,创建一个以你要加密的分区命名的密钥文件:

现在在 /mnt/boot/loader.conf 中配置启动器。必须告诉启动器加载GELI内核模块并附加GELI设备,与上一节完全相同。

还需要在 loader.conf 中添加一条。FreeBSD默认从加载内核的任何分区加载根文件系统,但可以覆盖此设置。告诉FreeBSD使用 vfs.root.mountfrom 可调参数从 /dev/daop4.eli 上的UFS文件系统挂载其根文件系统:

未加密分区已经完成。一旦启动系统,并且知道一切正常,就可以将这些文件复制到ISO中并刻录到CD上。

安装加密分区

现在有了一个引导分区,可以在加密设备上安装FreeBSD。首先随机化GELI分区的内容,这样入侵者就无法轻易确定哪些块是加密的,哪些块是随机垃圾:

初始化GELI设备,并将密钥文件附加到未加密的分区上,使用 -b 选项告诉GELI它应该以单用户模式连接此设备。

【并不是说我在测试过程中多次忘记了 -b ,或者类似的东西。】

现在在加密设备上创建一个文件系统,并将其挂载到 /mnt 上:

现在有了文件系统,可以在上面安装FreeBSD文件。参阅本章前面的“手动安装FreeBSD”。

与未加密的系统一样,加密的根分区需要一个文件系统表 /etc/fstab 。文件系统表必须列出当前根分区、交换分区以及(可选)挂载未加密分区的位置。

如果你想将未加密的驱动器挂载到某个地方,请为它创建一个目录,此处我们将其挂载在 /clear 。也可以将其挂载到 /boot,或者将 /boot 设置为符号链接。

安装后设置和管理

您可以引导到加密的文件系统,但系统没有用户,也没有配置。FreeBSD安装程序在安装过程结束时为您做的所有这些友好的事情?你可以像其他手动安装一样,自己动手完成所有这些操作。您必须从头开始创建 /etc/rc.conf ,并运行 adduser(8) 来创建您的用户帐户。

使用只读介质进行 /boot 会使系统维护复杂化。FreeBSD的升级工具,如 freebsd-update(8)make installkernel ,不能写入只读介质——这就是重点。您的系统从【未加密的驱动器】启动内核,而不是GELI分区 /boot/kernel 中的内核。

我建议将只读介质安装在 /boot 以外的位置。这可以使升级正常工作。当您更改内核时,无论是通过构建自定义内核还是升级,您都必须手动更新启动介质。

这种加密程度将保护您的数据在偶然被盗的情况下不被泄露。如果你需要更强的保护,请参阅第7章。

扩展虚拟磁盘

大多数虚拟化系统都有扩展提供给访客的虚拟磁盘的选项。你如何告诉FreeBSD额外的空间?通过汇集几乎每一章的材料。

首先备份系统;任何时候,当你摆弄磁盘或文件系统时,数据丢失都是一个非常真实的风险。这是一个带有扩展虚拟磁盘的web服务器,为其提供了更多空间,但也存在一些问题。

这个VM在磁盘尾部有320GB的剩余空间。但为什么扩展磁盘1会损坏GPT表呢?GPT将分区表存储在磁盘的前面。它还在磁盘末尾保留一个备份副本。移动磁盘末端不会破坏备份副本,但会将其丢弃在错误的位置。使用 gpart recover 创建新的磁盘末端(end-of-disk)备份:

这将放置一个新的备份副本并清除损坏的警告。

现在决定如何处理这个空间。最简单的方法是在该空间中创建一个新分区并将一些文件移动到其中。我建议对服务器进行分区(正如您在第1章中看到的那样),但托管提供商给了我这个安装。如果你想保留一个大分区,你会怎么做?

首先,决定这些分区的排列方式。这个系统有三个分区:引导分区、根分区和交换分区。磁盘扩展后还是这三个分区,以及磁盘末尾的320GB空白空间。无法将根分区扩展到空白空间,因为交换空间挡在中间。

常见的建议是把交换空间放在磁盘的前部,因为那里是磁盘上最快的部分。但这个常见的建议无关紧要。虚拟化系统不在意底层磁盘,甚至完全不知道磁盘上最快的那部分实际上在哪里。最简单的方法是将交换空间移动到磁盘的末尾,并扩展根分区以填充空白的空间,最终得到:

gpart 命令不允许在磁盘末尾创建分区。每个新分区都会直接出现在任何现有分区之后。但它允许创建一个无实际意义的填充分区。

新的空白分区显示为320GB,但这里是四舍五入的。您希望至少有4GB的交换空间,但您有足够的磁盘空间,可以慷慨地使用。在这个虚拟机上,稍微过多的交换总比不够好。为这个新的交换分区分配5GB,并标记这个分区以提醒您它的用途和作用。

因此,您需要一个315GB的临时分区,并可以进行其余的交换。

现在使用剩余空间创建一个交换分区:

此时磁盘结构看起来是这样的:

编辑 /etc/fstab 使用新的交换分区替代旧的:

可以重启以激活新的交换空间。也可以按第八章的知识使用以下命令启用它:

系统交换空间看起来像这样:

旧交换空间是 /dev/label/swap0 ,以GEOM标签标记;新交换空间是 /dev/gpt/swap0 ,以GPT标签标记。你可能应该让名字更加清晰,但这是暂时的,所以只要你不把两者混淆,就没关系。而且旧的互换也不会持续太久了。关闭旧的交换空间。

旧的交换空间不用了,所以我们可以把它从痛苦中解脱出来。仔细检查 gpart show ,了解哪个分区是交换空间(3),哪个是临时占位符(4)。仔细检查这些数字。你将要删除分区,而由于你自己的草率而删除根分区会让你最不开心。

三重检查:根文件系统是否还在?FreeBSD有防止删除挂载分区的保护措施,但无论如何都要检查。

根据需要,交换空间位于磁盘尾部。中间有317GB自由空间,位于根文件系统之后。

再次检查你的备份,确定你有重建此服务器所需的一切。然后使用 gpart resize 扩展根文件系统,不用指定大小,新分区将扩展以填充所有可用的连续空间:

现在看看都有啥:

根分区现在是635GB,成功了。

嗯,接近成功。分区更大,但分区上的文件系统还是只有318GB。

扩展UFS文件系统,使用 growfs(8) 命令填充其分区。在FreeBSD9及更早版本中, growfs 仅适用于未安装的文件系统。在FreeBSD10及以后的版本中,growfs 适用于启用了软更新的已挂载文件系统。通过设备节点(/dev/vtbd0p2)或GPT标签(/dev/GPT/rootfs0)标识文件系统。

如果分区没有使用软更新,请重启到单用户模式,并在挂载之前扩展文件系统。

扩展文件系统后,重新应用GPT标签:

到此应该已经设置好了,但建议重启系统,以确保没有任何损坏。

现在分区看起来应该像这样:

所有可用磁盘空间现在都在使用中。任务完成!

如果你能在加密硬盘上自定义安装FreeBSD,并在实时系统上洗牌分区,那么你就了解了FreeBSD存储系统的基本原理。虽然总是有更多的东西需要学习——ZFS、unionfs(8) 、NFS等等——但你已经有了坚实的基础。恭喜你!

后记

FreeBSD的存储架构为您提供了其他类Unix操作系统无法比拟的灵活性。实际上,负责你的存储功能和行为会让你感到彻底的解放。

这本书并没有完全涵盖一切。如果你有特殊的存储硬件,如光纤通道或infiniband,你可以在几分钟内通过FreeBSD手册或维基了解管理该硬件的细节。这本书涵盖了每个系统管理员必须知道的内容,但并不是每个系统管理员都必须知道的所有内容。

然而,FreeBSD的存储系统不是GEOM或UFS。除了ZFS,还有 tmpfs(5)devfs(8) 和HAST,天哪!2015年,请在您最喜欢的书店查找我关于ZFS和专业文件系统的FreeBSD Mastery书籍,以及其他FreeBSD、BSD和一般系统管理主题。

如果你想自动知道我什么时候有新书出版,请注册我的科技图书公告邮件列表。我只在有东西要炫耀时才发信息,比如新标题或公开露面,或者(很少)一些随机但非常酷的东西。加入https://www.michaelwlucas.com

如果你想知道我脑子里闪过的每一个愚蠢的想法,请在推特上关注@mwlauthor。

现在去修理你的存储。