构建一个 家庭实验室 可以是一种有趣的娱乐方式,同时学习新概念和尝试新技术。 感谢以 Raspberry Pi 为首的单板计算机 (SBC) 的普及,在家中舒适地构建一个多计算机实验室比以往任何时候都更容易。 创建“家庭私有云”也是接触云原生技术的好方法,与尝试使用主要云提供商复制相同的设置相比,成本要低得多。
本文解释了如何修改 Raspberry Pi 或其他 SBC 的磁盘映像,预配置主机以进行 SSH(安全外壳)连接,并禁用首次启动时强制交互配置的服务。 这是使您的设备“启动即用”的好方法,类似于云实例。 稍后,您可以使用 SSH 连接通过自动化流程进行更专业、更深入的配置。
此外,当您向实验室添加更多 Pi 时,修改磁盘映像可以让您只需将映像写入 SD 卡,将其放入 Pi 中即可!

解压缩并挂载映像
对于这个项目,您需要修改服务器磁盘映像。 我在测试期间使用了 Fedora Server 31 ARM 映像。 下载磁盘映像并 验证其校验和 后,您需要将其解压缩并挂载到主机计算机文件系统上的某个位置,以便您可以根据需要对其进行修改。
您可以使用 xz 命令,使用 --decompress 参数来解压缩 Fedora Server 映像
xz --decompress Fedora-Server-armhfp-X-y.z-sda.raw.xz
这将为您留下一个原始的、解压缩的磁盘映像(它会自动替换 .xz 压缩文件)。 这个原始磁盘映像正如其名称所示:一个包含格式化和安装磁盘上所有数据的文件。 这包括分区信息、引导分区、根分区和任何其他分区。 您需要挂载您打算工作的分区,但要做到这一点,您需要了解该分区在磁盘映像中的起始位置以及磁盘扇区的大小,以便您可以将文件挂载到正确的扇区。
幸运的是,您可以像在真实磁盘上一样轻松地在磁盘映像上使用 fdisk 命令,并使用 --list 或 -l 参数来查看分区列表及其信息
# Use fdisk to list the partitions in the raw image:
$ fdisk -l Fedora-Server-armhfp-31-1.9-sda.raw
Disk Fedora-Server-armhfp-X-y.z-sda.raw: 3.2 GiB, 3242196992 bytes, 6332416 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xdaad9f57
Device Boot Start End Sectors Size Id Type
Fedora-Server-armhfp-X-y.z-sda.raw1 8192 163839 155648 76M c W95 F
Fedora-Server-armhfp-X-y.z-sda.raw2 * 163840 1163263 999424 488M 83 Linux
Fedora-Server-armhfp-X-y.z-sda.raw3 1163264 6047743 4884480 2.3G 83 Linux
您需要的所有信息都在此输出中。 第 3 行指示扇区大小,包括逻辑扇区大小和物理扇区大小:(512 字节 / 512 字节)。
设备列表显示了原始磁盘映像内部的分区。 第一个,Fedora-Server-armhfp-X-y.z-sda.raw1 毫无疑问是引导加载程序分区,因为它是第一个,很小(只有 76MB),并且类型为 W95 FAT32 (LBA),由 Id "c" 标识,这是一个用于从 SD 卡启动的 FAT32 分区。
第二个分区也不是很大,只有 488MB。 此分区是 Linux 原生类型分区(Id 83),它可能是包含内核和 initramfs 的 Linux 引导分区。
第三个分区可能是您想要的:它有 2.3GB,因此它应该包含大部分发行版,并且它是 Linux 原生分区类型,这是预期的。 这应该包含您想要修改的分区和数据。
第三个分区从扇区 1163264 开始(在 fdisk 的输出中的“Start”列中指示),因此您的挂载偏移量为 595591168,计算方法是将扇区大小 (512) 乘以起始扇区 (1163264)(即,512 * 1163264)。 这意味着您需要以 595591168 的偏移量挂载文件才能在挂载点处于正确的位置。
掌握(明白我的意思了吗?)这些信息后,您现在可以将第三个分区挂载到您主目录中的目录
$ mkdir ~/mnt
$ sudo mount -o loop,offset=595591168 Fedora-Server-armhfp-X-y.z-sda.raw ~/mnt
$ ls ~/mnt
直接在磁盘映像中工作
一旦磁盘映像被解压缩并挂载到主机计算机上的某个位置,就可以开始修改映像以满足您的需求了。 我认为,对映像进行更改的最简单方法是使用 chroot 将会话的工作根目录更改为已挂载映像的根目录。 但是,这里有一个棘手的地方。
当您更改根目录时,您的会话将使用新根目录中的二进制文件。 除非您是从 ARM 系统执行所有这些操作,否则解压缩的磁盘映像的架构将与您正在使用的主机系统的架构不同。 即使在 chroot 内部,主机系统也无法使用具有不同架构的二进制文件。 至少,不是原生方式。
幸运的是,有一个解决方案:qemu-user-static。 来自 Debian Wiki
“[qemu-user-static] 提供了用户模式仿真二进制文件,以静态方式构建。 在此模式下,QEMU 可以启动在一个 CPU 上为另一个 CPU 编译的 Linux 进程……如果安装了 binfmt-support 软件包,qemu-user-static 软件包将注册提供的仿真器可以处理的二进制格式,以便可以直接运行外部二进制文件。”
这正是您需要在 chroot 中非原生架构中工作所需要的。 如果主机系统是 Fedora,请使用 DNF 安装 qemu-user-static 软件包,并重启 systemd-binfmt.service
# Enable non-native arch chroot with DNF, adding new binary format information
# Output suppressed for brevity
$ dnf install qemu-user-static
$ systemctl restart systemd-binfmt.service
这样,您应该能够将根目录更改为已挂载的磁盘映像,并运行 uname 命令以验证一切正常
sudo chroot ~/mnt/ /usr/bin/uname -a -r
Linux marvin 5.5.16-200.fc31.x86_64 #1 SMP Wed Apr 8 16:43:33 UTC 2020 armv7l armv7l armv7l GNU/Linux
从更改后的根目录运行 uname 显示输出中的 armv7l — 原始磁盘映像的架构 — 而不是主机。 一切都按预期工作,您可以继续修改映像。
修改磁盘映像
现在您可以直接更改到基于 ARM 的磁盘映像并在该环境中工作,您可以开始对映像本身进行更改。 您希望设置映像,使其可以启动并立即访问,而无需直接在 Raspberry Pi 上进行任何其他设置。 为此,您需要安装并启用 sshd(OpenSSH 守护程序)并添加 SSH 访问的授权密钥。
为了使其行为更像云环境并实现家庭私有云的梦想,请添加一个本地用户,为该用户提供 sudo 权限,并且(就像云巨头一样)允许该用户在没有密码的情况下使用 sudo。
因此,您的待办事项清单是
- 安装并启用 SSHD(SSHD 已在 Fedora ARM 映像中安装并启用,但您可能需要为您的发行版手动执行此操作)
- 设置本地用户
- 允许本地用户使用 sudo(可选,无需密码)
- 添加授权密钥
- 允许 root 使用授权密钥进行 SSH 连接(可选)
我使用 GitHub 功能,该功能允许您上传您的公共 SSH 密钥并使其在 https://github.com/<your_github_username>.keys 上可用。 我发现这是分发公钥的一种便捷方式,尽管我足够多疑,总是会检查下载的密钥是否与我期望的密钥匹配。 如果您不想使用此方法,您可以直接从主机计算机将您的公钥复制到 chroot 中,或者您可以将您的密钥托管在您控制的 Web 服务器上,以便使用相同的工作流程。
要开始修改磁盘映像,请再次 chroot 到挂载的磁盘映像中,这次启动一个 shell,以便可以运行多个命令
# Output of these commands (if any) are omitted for brevity
$ sudo chroot ~/mnt /bin/bash
# Install openssh-server and enable it (already done on Fedora)
$ dnf install -y openssh-server
$ systemctl enable sshd.service
# Allow root to SSH with your authorized keys
$ mkdir /root/.ssh
# Download, or otherwise add to the authorized_keys file, your public keys
# Replace the URL with the path to your own public keys
$ curl https://github.com/clcollins.keys -o /root/.ssh/authorized_keys
$ chmod 700 /root/.ssh
$ chmod 600 /root/.ssh/authorized_keys
# Add a local user, and put them in the wheel group
# Change the group and user to whatever you desire
groupadd chris
useradd -g chris -G wheel -m -u 1000 chris
# Download or add your authorized keys
# Change the homedir and URL as you've done above
mkdir /home/chris/.ssh
curl https://github.com/clcollins.keys -o /home/chris/.ssh/authorized_keys
chmod 700 /home/chris/.ssh
chmod 600 /home/chris/.ssh/authorized_keys
chown -R chris.chris /home/chris/.ssh/
# Allow the wheel group (with your local user) to use suso without a password
echo "%wheel ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/91-wheel-nopasswd
这通常是首次启动时设置 SSH 进入 Raspberry Pi 或其他单板计算机所需完成的全部操作。 但是,每个发行版都有其自身的怪癖。 例如,Rasbian 已经包含一个本地用户 pi,并且不使用 wheel 组。 因此,对于 Raspbian,最好使用现有用户或删除 pi 用户并将其替换为另一个用户。
对于 Fedora ARM,映像会提示您在首次启动时完成设置。 这破坏了您上面所做更改的目的,尤其是在完成设置之前它会完全阻止启动的情况下。 您的目标是使 Raspberry Pi 像私有云基础设施的一部分一样运行,并且该工作流程包括在启动时通过 SSH 远程设置主机。 禁用由服务 initial-setup.service 控制的初始设置
# Disable the initial-setup.service for both the multi-user and graphical targets
unlink /etc/systemd/system/multi-user.target.wants/initial-setup.service
unlink /etc/systemd/system/graphical.target.wants/initial-setup.service
当您处于更改根目录时,您可以对系统进行任何其他您可能想要的更改,或者就此为止,并遵循首次启动后通过 SSH 进行配置的云原生工作流程。
重新压缩并安装修改后的映像
完成对系统的这些更改后,剩下的就是重新压缩磁盘映像并将其安装到 Raspberry Pi 的 SD 卡上。
确保退出 chroot,然后卸载磁盘映像
$ sudo umount ~/mnt/
正如您最初解压缩映像一样,您可以再次使用 xz 命令来压缩映像。 通过使用 --keep 参数,xz 将保留原始映像,而不是清理它。 虽然这会占用更多磁盘空间,但保留未压缩的映像允许您对您正在处理的映像进行增量更改,而无需每次都解压缩它们。 这对于在测试和调整图像以满足您的喜好时节省时间非常有用
# Compress the raw disk image to a .xz file, but keep the raw disk image
xz --compress Fedora-Server-armhfp-31-1.9-sda.raw --keep
压缩需要一段时间,因此请利用这段时间站起来,伸展一下,让您的血液再次流动起来。
压缩完成后,新的、修改后的磁盘映像可以复制到 SD 卡以与 Raspberry Pi 一起使用。 将映像复制到 SD 卡的标准 dd 方法可以正常工作,但我喜欢使用 Fedora 的 arm-image-installer,因为它在处理未编辑的映像时提供了选项。 它也适用于编辑过的映像,并且比 dd 命令更用户友好。
确保检查 SD 卡在哪个磁盘上,并将该磁盘用于 --media 参数
# Use arm-image-installer to copy the modified disk image to the SD card
arm-image-installer --image=Fedora-Server-armhfp-X-y.z-sda.raw.xz --target=rpi3 --media=/dev/sdc --norootpass --resizefs -y
现在您已经为 Raspberry Pi 或其他单板计算机设置了新的、修改后的 Fedora Server ARM 映像,可以启动并立即通过 SSH 连接到您的修改。 此方法也可用于进行其他更改,如果您喜欢 Fedora,也可以将其与其他发行版的原始磁盘映像一起使用。 这是一个开始构建家庭私有云实验室的良好基础。 在以后的文章中,我将指导您使用云技术和自动化设置家庭实验室。
进一步阅读
为了学习本文中的内容,我做了大量的研究。 我发现学习如何自定义磁盘映像和使用非原生架构的两个最有用的来源列在下面。 它们对于我从“我不知道自己在做什么”到“好的,我可以做到!”的转变非常有帮助。
4 条评论