引言
本文记录了我在树莓派上设计与使用 Rocky Linux、libvirt、Podman 搭建了一个家庭实验室服务器的完整过程。本文并非一步一教的教程,而是一份技术案例研究,包含规划思路、系统架构、硬件与软件限制,以及最终成型过程中所有关键的实际决策。
背景
第一次听说树莓派(Raspberry Pi)时,我就被它吸引。这是一款低成本、小型化单板计算机(SBC),用途极广,从创客项目到工业自动化都能胜任,再加上完善的文档与庞大的社区支持,我立刻就想拥有一台。
作为家庭实验室新手,在搭建这台服务器之前,我的设备包括:ALFA Network AWUS036ACS USB 网卡(用于 Wi-Fi 渗透测试)、运行在 Oracle VirtualBox 上的 Linux 与 Windows 虚拟机(VirtualBox 是 Windows 平台下的 2 类虚拟机管理程序),以及用于本地运行大语言模型的 Ollama 和 Open WebUI。这套方案用起来不错,但有一个致命问题:无法运行持久化服务 —— 只要关掉笔记本,所有服务都会消失。
就在那时,我决定入手新硬件,专门搭建一台服务器,最终我选择了树莓派。
选择理由
我最终选择了 16GB 内存版本的树莓派 5,原因很明确:低功耗、体积小、原生支持 Linux、便携性强。16GB 内存足以让它承担多种任务:运行容器、轻量级虚拟机,甚至小型大语言模型。
尽管近年来树莓派价格有所上涨,尤其受内存短缺影响,但树莓派 5 的性能功耗比与项目灵活性依然出色。我们可以通过计算直观理解它的能效:
计算树莓派5在峰值性能下运行一年的耗电量:
树莓派 5 8GB 版本峰值功耗约 12W,即 0.012kW:
12 W /1000 ≈ 0.012 kW
如果 24 小时不间断运行,全年耗电量约 105.12kWh:
(0.012kW * 24 hours) * 365 days ≈ 105.12 kWh
将树莓派5在峰值性能下运行一年的耗电量与10瓦路由器进行比较:
一台 10W 路由器年耗电 87.6kWh,对比可见,树莓派 5 能效与成本优势明显,它可以作为一台承载大量服务的服务器,甚至能替代一些付费订阅服务。
需要注意,以上为估算值,且假设全年满负荷运行。实际家庭实验室负载很少持续峰值,普通用户真实电费会更低,具体取决于负载情况。
虽然我以 8GB 版本峰值功耗作为参考,但 16GB 版本年耗电量基本接近,因此该估算仍有参考意义。
最终树莓派硬件配置
我的树莓派5服务器硬件配置如下:
需购买物品:
树莓派5 16GB内存版(理由如上所述)
Vilros 27W 5V/5A树莓派5电源(运行虚拟机、USB设备和散热时,树莓派5需要27W 5V/5A电源以稳定运行)
Vilros标准HDMI(母头)转Micro HDMI(公头)适配器线(因树莓派5使用Micro HDMI输出而非全尺寸HDMI)
带主动散热器的Argon Poly+5树莓派专用外壳(该外壳与树莓派扩展板兼容,并配备主动散热解决方案,对于在虚拟机和其他重负载任务下保持稳定性能至关重要)
带适配器的SanDisk 128GB Extreme microSDXC UHS-I存储卡(SanDisk Extreme microSDXC UHS-I 128GB支持UHS-I(SDR104),完美匹配树莓派5的microSD卡插槽支持的SDR104模式)
uni USB C和USB 3.0转SD/MicroSD读卡器(用于将microSD卡连接至计算机,以便将操作系统镜像写入SD卡)
存储说明:树莓派 5 通过 PCIe HAT 支持 NVMe 固态硬盘,但为了简化初期搭建,我先使用 microSD 卡。NVMe 读写速度更快,对虚拟机等高负载非常关键,但成本更高,且需要仔细匹配 PCIe 扩展板、SSD 与外壳兼容性。目前我先保留 microSD,后续计划升级 NVMe。
已有物品:
注意:外设优先选择有线设备,通常开箱即用,基本不会遇到驱动问题。
目标
最初构思此项目时,我的目标是:搭建配备虚拟机和容器的树莓派家庭实验室服务器。
我决定在服务器中使用虚拟机有两个原因:一是为软件环境隔离,二是能够同时运行不同操作系统。我知道通过容器化软件可以实现环境隔离,但容器无法让我运行完整的独立操作系统。不过,这并不意味着我不会使用容器化。我也将使用容器化来运行服务,并更好地理解它。
设计决策
初步想法
一开始,看到 Proxmox VE 在家庭实验室中非常流行,我也考虑使用它。Proxmox VE 是 1 类虚拟机管理程序,直接运行在硬件上,而非像 VirtualBox 那样依赖宿主系统,理论上非常适合本项目 —— 它自带操作系统与虚拟化套件,无需额外选择。
但我很快放弃了这个方案:Proxmox VE 仅支持 x86_64 架构的 AMD/Intel CPU,不支持树莓派的 ARM 架构。虽然有社区项目 Pimox 可以在树莓派上运行 Proxmox VE,但它属于非官方移植,没有官方支持,稳定性无法保证,因此我没有采用。
这让我产生了以下疑问:应使用哪种主机操作系统?
在选择操作系统时,我需要一款面向服务器的 Linux 发行版。虽然桌面版 Linux 也能以无头模式运行,但服务器版更稳定,也更贴近企业生产环境。
我最初考虑 Ubuntu Server,它基于 Debian,我比较熟悉,企业中也广泛使用。但我想尝试新东西,于是转向 RHEL(红帽企业 Linux)—— 它同样是企业主流,且不属于 Debian 系,可以让我学习新的发行版生态。
然而,2023 年 6 月后,红帽修改了源码分发策略,限制 RHEL 源码仓库公开访问,需要红帽账号与订阅才能使用。虽然可以通过免费开发者订阅获取 RHEL,但我还是决定寻找替代方案,更何况树莓派并不在 RHEL 官方支持硬件列表中。
最终我选择了Rocky Linux:一款完全开源、企业级、100% 兼容 RHEL 的系统。它由原 CentOS 创始人之一 Gregory Kurtzer 创立,目标是 “与 RHEL 完全 bug 级兼容”,为 RHEL 构建的软件可以直接在 Rocky 上运行。最重要的是,它提供 ARM 架构构建版,可直接在树莓派上运行。
Rocky Linux:https://rockylinux.org/
如何在Linux中运行虚拟机?
我需要一套虚拟化方案:配置完成后,可以直接在终端通过 SSH 管理虚拟机,无需图形界面。
在查阅 Rocky Linux 文档时,我在虚拟化章节找到了libvirt相关指南。libvirt 是一套强大的虚拟化管理 API,可以统一管理多台虚拟机。底层它使用 Linux 内核内置的 KVM 模块,让 Linux 变身 1 类虚拟机管理程序,运行多个相互隔离的虚拟机。硬件模拟部分(虚拟 CPU、内存、存储、网络)则由 QEMU 完成。
限制条件
虽然操作系统与虚拟化方案都已确定,但在树莓派上做虚拟化,仍有几个关键限制需要注意:
可运行虚拟机类型的限制:
树莓派 5 使用 aarch64(ARM64)CPU 架构,因此虚拟机最适合运行同架构操作系统。如果运行 x86_64 等不同架构系统,QEMU 必须进行全系统软件模拟,无法使用硬件虚拟化加速,导致资源占用极高、速度极慢。
因此,除非用于测试或特定软件需求,否则优先运行为 ARM 编译的操作系统。当客户机与宿主架构一致时,libvirt 可通过 KVM 实现硬件加速,虚拟机运行效率大幅提升。
同时运行虚拟机数量的限制:
树莓派 5 只有 4 核 CPU、16GB 内存。为保证宿主系统稳定,必须为 Rocky Linux 保留至少 1 核 + 4GB 内存。剩余可用资源:3 核 CPU + 12GB 内存。这意味着系统最多同时稳定运行 1–3 台虚拟机,具体取决于配置:
1 VM:VM1: 3 CPU Cores and 12 GB RAM2 VMs:VM1: 2 CPU Cores and 8-10 GB RAMVM2: 1 CPU Core and 2-4 GB RAM3 VMs:VM1: 1 CPU Core and 4 GB RAMVM2: 1 CPU Core and 4 GB RAMVM3: 1 CPU Core and 4 GB RAM
注意:这些资源分配为近似值,非严格限制。它们基于可用资源和运行如Ubuntu Server、Rocky Linux和Kali Linux等带图形用户界面的操作系统的平均内存推荐。
如何在主机操作系统内构建虚拟机和容器结构?
以下图表展示了下一节中将实施的结构:
树莓派5服务器架构:
Rocky Linux (Host OS), 1 CPU core & 4 GB RAM:Podman (Containerization):Pi-hole (Service: Network-wide ad blocker)libvirt (Virtualization)Raspberry Pi OS (VM: Development), 3 CPU cores & 12 GB RAMRaspberry Pi Connect (Service: Remote Access)
在本文前面部分,我解释了选择Rocky Linux和libvirt的原因。在本节中,我将解释为何选择Podman、Pi-hole和树莓派操作系统用于此系统。
Podman:我选择Podman作为容器化引擎而非Docker,原因有几点。
与依赖名为“dockerd”的root特权守护进程(后台服务)的Docker不同,Podman直接将容器作为启动它们的用户的子进程运行。这种无守护进程设计提高了安全性,因为没有长时间运行的特权守护进程可能在容器被攻破时被利用。
Podman也是RHEL及如Rocky Linux等RHEL兼容发行版的默认容器引擎。由于这种原生支持,Podman也与安全增强型Linux(SELinux)配合良好,SELinux是一种针对系统上应用、进程(包括容器)和文件的访问控制系统。这进一步增强了系统对容器被攻破的防护,并使服务器更接近企业级环境。
除这些安全优势外,Podman仍与Docker镜像使用的开放容器倡议(OCI)标准完全兼容。这意味着仍可使用Podman拉取并运行托管在如Docker Hub等注册表上的容器。
Pi-hole:什么是Pi-hole,我为何选择包含它?
Pi-hole是一款开源全网络广告拦截器,通过过滤DNS请求工作。当设备尝试解析域名时,Pi-hole会检查请求是否与已知广告和跟踪域名列表中的域名匹配。如果匹配,则阻止请求,防止广告或跟踪器加载。
一旦配置为网络的DNS服务器(通过路由器或手动通过每台设备的设置),单个Pi-hole服务器即可过滤连接到网络的所有设备的流量。
我选择在此项目中包含Pi-hole,既是为了探索DNS过滤的工作原理,也是为了使树莓派服务器对我的家庭网络有用。
树莓派操作系统:什么是树莓派操作系统,我为何选择包含它?
树莓派操作系统是一款由树莓派基金会专为树莓派计算机开发的基于Debian的Linux发行版。它轻量级且优化以在树莓派的ARM CPU架构上运行。
我选择使用树莓派操作系统作为主要开发虚拟机,因其与树莓派硬件兼容。它也将提供一个我熟悉的工作环境,因为我已经熟悉基于Debian的操作系统。这使我能够专注于完成任务,而无需临时学习新系统概念。
选择树莓派操作系统的最大原因是它包含树莓派连接,这是一款安全的远程访问服务,允许用户通过网页浏览器访问和控制树莓派。这使我无需依赖SSH或安装额外远程访问软件即可访问我的开发虚拟机。这使我几乎可以从任何计算机或网络连接到我的开发虚拟机,即使在无法安装远程访问工具或使用SSH的情况下也是如此。
实施系统架构:
安装Rocky Linux
我从Rocky Linux官方下载页面下载了树莓派的Rocky Linux镜像及对应的校验和文件。然后,在PowerShell中运行Get-FileHash后,我得到了一个与官方校验和文件中匹配的哈希值。这确认了镜像在下载过程中未被损坏或篡改。现在,镜像已验证,我使用Balena Etcher通过microSD转USB适配器将.xz镜像闪存到microSD卡上。
使用Balena Etcher将Rocky Linux闪存到microSD卡上。
闪存过程完成后,我将microSD卡插入树莓派,系统启动。
启动后,我使用包含在系统README文件中的默认凭据登录,并使用内置的sudo rootfs-expand命令扩展根文件系统,以便系统能够利用存储的全部容量。
使用rootfs-expand命令。
然后,我开始进行一些基本的系统加固工作,包括更改默认rocky用户的密码,并创建一个新的管理账户,将其加入wheel组以给予新用户sudo访问权限。在验证新账户具有管理特权后,我选择锁定默认rocky用户账户,防止其用于登录。在通过以太网永久将树莓派连接到互联网之前,我想检查Wi-Fi是否工作,因此我使用nmcli连接到我的网络。之后,我使用DNF包管理器更新系统包,并在系统更新后重启。
系统更新后重启,在用户登录时,终端反复显示brcm_set_channel错误。
登录时的brcm_set_channel错误
经过调查,我在树莓派的Stack Exchange上发现了关于树莓派和Pinebook Pro设备上类似brcmfmac故障的报告。一些用户通过修改驱动程序配置并在加载brcmfmac模块时禁用某些硬件功能解决了问题。利用论坛的建议和AI辅助(因为这超出了我的技术能力),我选择了一个更简单的方法:完全禁用Wi-Fi驱动程序。我可以这样做,因为我打算将此系统作为仅以太网服务器运行。作为额外好处,禁用Wi-Fi驱动程序还通过移除未使用的无线接口及其驱动程序减少了系统的攻击面。重启后,我不再遇到这些错误,这意味着该模块已不再存在。这通过lsmod | grep ‘brcmfmac’确认,且运行ip link | grep -E ‘wlan0|wl’时未出现wlan0接口。然后,通过以太网连接树莓派后,我恢复了网络连接。
现在,操作系统已更新且稳定,我通过运行更多配置完成了基线服务器设置:
设置主机名:sudo hostnamectl set-hostname example-host-name并重新加载shell:exec bash。
通过静态IP设置一致地址(我本希望使用DHCP保留,但我的路由器不允许):通过sudo nmtui配置,并使用sudo systemctl restart NetworkManager应用。启用企业版Linux额外软件包(EPEL),它提供了企业版Linux发行版默认仓库中未包含的额外软件包:sudo dnf install epel-release和sudo /usr/bin/crb enable以启用CodeReady Builder,这是一个包含开发库、构建依赖项和许多EPEL软件包依赖的额外系统库的仓库。
使用timedatectl检查我所在地区的环境时间和日期设置是否正确,并使用sudo timedatectl set-timezone America/place更改以匹配我所在地区。
通过检查OpenSSH守护进程是否已启用并活跃来验证服务器是否可通过SSH访问:sudo systemctl status sshd
设置dnf-automatic以进行自动更新:安装它sudo dnf install dnf-automatic,启用它sudo systemctl enable --now dnf-automatic.timer,并确保它已启用systemctl status dnf-automatic.timer。
设置虚拟化
要将虚拟化通过libvirt引入我的服务器,我基于Rocky Linux的设置libvirt指南进行了设置。我安装了必要的软件包,其中一些最重要的包括:qemu-kvm、libvirt、virt-install、bridge-utils,以及我未来可能使用的额外工具,如virt-manager、virt-viewer和virt-top。
sudo dnf install -y bridge-utils virt-top virt-viewer qemu-kvm libvirt virt-manager virt-install
安装完成后,我将我的用户添加到libvirt组,以便我无需不断使用root即可管理虚拟机。然后,我启用并启动了libvirtd守护进程,以便虚拟化在我的会话中工作,并在启动时自动运行。
接下来,我为虚拟机设置了网络。这一步很重要,因为我希望虚拟机使用桥接连接,以便虚拟机在我本地网络上表现得像真实设备,而非隔离在NAT后面。在遵循Rocky Linux指南并交叉参考libvirt的网络维基时,我了解到无线接口无法附加到Linux主机桥接器,这意味着如果主机通过使用Wi-Fi的接口连接到网络,桥接网络将无法工作。幸运的是,由于我之前遇到的Wi-Fi驱动程序问题,我已经将树莓派切换到了以太网。因此,我继续遵循Rocky Linux指南:
使用nmcli,我为libvirt创建了网络桥接接口。我为桥接器分配了静态IP、网关地址和DNS地址,以便主机在网络上易于找到。之后,我将树莓派的主要以太网连接作为桥接从属接口添加到桥接器,并启动了连接。
为允许QEMU使用桥接器,我更新了/etc/qemu-kvm/bridge.conf。最后,我重启了libvirtd守护进程,以便网络更改生效。
最初,在为虚拟机设置网络后,我想使用树莓派操作系统作为开发虚拟机。因此,我下载了ARM64镜像,解压了它,为镜像增加了存储,并尝试使用virt-install导入它,参考了Rocky Linux指南、RHEL文档和Arch文档。
我尝试设置虚拟机:
virt-install --name pi-dev-vm --memory 12288 --vcpus 3 --disk path=/var/lib/libvirt/images/raspios-vm.img,format=raw --import --os-variant debian13 --network bridge=br0,model=virtio --graphics none --console pty,target_type=serial --extra-args 'console=ttyS0,115200n8' --boot hd
然而,虚拟机未能启动,我被送入了UEFI shell。
因此,我使用CTRL + ]退出了shell。回想起来,那是我的一大疏忽,因为树莓派操作系统和树莓派的操作系统构建是为在实际树莓派硬件和固件上启动而设计的,而非QEMU和libvirt提供的标准虚拟化环境。因此,我放弃了使用树莓派操作系统作为开发虚拟机的想法,转而选择ARM64架构的Debian。Debian对我来说是合乎逻辑的选择,因为我对Debian很熟悉,且它非常稳定。
不使用树莓派操作系统的唯一真正权衡是我无法再使用树莓派连接作为我的基于浏览器的远程访问解决方案。然而,在寻找替代方案的过程中,我发现了一篇由John Graham-Cumming撰写的文章,标题为“通过浏览器、Cloudflare隧道和可审计终端SSH连接到我的树莓派400”。文章描述了如何通过Cloudflare隧道将树莓派连接到Cloudflare,并通过基于浏览器的SSH终端访问。阅读他的指南也指引我查阅了官方Cloudflare文档。在那里,我了解到这种基于浏览器的访问是一种名为客户端无访问(ZTNA)服务的部署选项,称为无信任网络访问。这种零信任优先策略使此解决方案非常安全,因为只有授权用户才能访问基于浏览器的终端,且即使有人入侵,他们仍需要输入用户和密码。
现在,我已经找到了开发虚拟机操作系统和远程访问解决方案的替代品,我删除了失败的虚拟机(virsh undefine pi-dev-vm --nvram --remove-all-storage),并实施了新的解决方案:
下载了Debian ARM64 ISO和校验和文件。然后,我验证了ISO的校验和与校验和文件中的匹配。
使用virt-install创建了虚拟机:
virt-install --name deb13-dev-vm --memory 12288 --vcpus 3 --disk path=/var/lib/libvirt/images/disks/debian13/debian13-dev.qcow2,size=40 --location /var/lib/libvirt/images/isos/debian13/debian-13.3.0-arm64-netinst.iso --os-variant debian13 --network bridge=br0,model=virtio --graphics none --console pty,target_type=serial --extra-args 'console=ttyS0,115200n8'
在虚拟机内,完成Debian安装后,我按照Cloudflare的文档设置了客户端无访问。
这是我使用客户端无访问访问我的开发虚拟机的样子:
登录Cloudflare Access。
登录Cloudflare Access后的可用终端。
注意:我确实需要购买一个域名才能设置客户端无访问。
使用Podman设置容器化
首先,我安装了podman和podman-compose。然后,我创建了~/containerization来存放如podman-compose或docker-compose文件等文件。在那里,我创建了~/containerization/pihole来存放Pi-hole的docker-compose文件。
我根据GitHub上Pi-hole的Docker设置文档创建了Pi-hole的compose文件,但为Rocky Linux和Podman对其进行了修改。修改包括以下内容:
配置为使用docker.io/pihole/pihole:latest镜像。
将Pi-hole数据目录映射为卷,并使用:Z标签,以便容器能够实际写入,否则SELinux会导致错误。
必须使用主机网络(network_mode: host)而非默认网络配置,以避免与Podman的内部DNS服务(Aardvark-dns)冲突。使用network_mode: host允许Pi-hole直接绑定到主机上所需的端口(80/tcp、443/tcp、53/tcp和53/udp)。
杂项:配置时区和禁用可选功能,因为我不需要它们。
现在,docker-compose文件已适合Rocky Linux,我使用sudo podman-compose up -d部署了它。尽管我赞扬了Podman的无sudo特性,但我不得不使用sudo来部署Pi-hole容器,因为Pi-hole为DNS和其网页控制面板使用了特权端口。为确保容器已启动,我运行了sudo podman ps -a,并使用sudo podman logs pihole来确保没有发生错误。
由于我使用了network_mode:host配置,然后我必须使用firewall-cmd配置系统防火墙,以允许端口80/tcp、443/tcp、53/tcp和53/udp上的入站流量。
然后,我在路由器中将我的Pi-hole服务器IP地址添加为DNS服务器。我将其同时添加为主DNS和次DNS服务器,因为我的路由器要求我设置两个。
为检查Pi-hole是否工作,我尝试访问默认阻止列表中的几个网站,它们未加载。这意味着Pi-hole正在工作!
Pi-hole网页仪表板。
结论
我成功实现了目标:在树莓派 5 上搭建了一台基于 Rocky Linux、支持 libvirt 虚拟化与 Podman 容器化的家庭实验室服务器。
过程中遇到了驱动报错、虚拟机系统不兼容、容器网络冲突、硬件资源受限等一系列问题,但我都逐一找到解决方案。解决这些挑战的过程,也让我更深入理解了企业级 Linux 服务器、网络、虚拟化与容器技术。
这并不是终点,而只是一个起点。我后续计划:将存储从 microSD 升级为 NVMe SSD,扩展更多容器服务,持续优化系统安全,最终我可以确定:只要设计合理,树莓派 5 完全可以成为一台实用、灵活、低功耗的家庭实验室服务器。
官方网站:https://edatec.cn/zh/cm0
淘宝店铺:https://edatec.taobao.com/
128