2022 年 6 月,我在Kickstarter上看到了一个关于一块可以同时容纳多达 4 个Raspberry Pi 4 计算模块的主板。
没过多考虑,我决定支持该项目并购买该主板。
快进两年,我的Turing Pi 2仍然未开封,放在架子上的盒子里。生活已经阻碍了它,我不确定为什么一开始要买它。
不过,我最终还是决定尝试一下。我想更多地了解集群,而且之前从未从头开始构建过完整的Kubernetes集群。因此,我开始花钱购买三台 Raspberry Pi 4(8GB RAM、8GB 内部存储)和一台Nvidia Jetson Nano (4GB)。
鉴于主板的多功能性,我可以混合使用不同的计算模块。我决定加入 Jetson Nano,认为它可能会让我在未来尝试 CUDA 驱动程序并深入研究机器学习。谁知道呢?我甚至可能最终在这个 Kubernetes 集群上托管我自己的 GPT 助手。
(Spoilers: It didn't happen)
我最初的计划包括 3 个 Pi 4 CM 和主板上的 Jetson Nano。此外,我还计划使用 1TB SSD 驱动器进行存储,并使用 Wi-Fi 卡进行互联网访问。然而,在 Jetson Nano 的设置过程中遇到许多困难及其糟糕的文档后,我决定退货。相反,我选择了第四个 Raspberry Pi 4。
此外,我还有一个带有 4GB RAM 的旧 Raspberry Pi 4,因此我决定将其作为第五个节点。
Turing Pi 2 是一款 Mini ITX 尺寸主板,可容纳最多四个 Raspberry Pi 计算模块(还兼容 Jetson Nanos 和 Turing 计算模块)。它具有一个 PCI Express 端口、两个 NVME 端口、两个 SATA 端口和一个用于刷新计算模块的 USB 端口。
节点 1 :
USB 2.0 端口(用于刷新计算模块)
HDMI 端口(用于调试)
PCI Express 端口(用于 Wi-Fi 卡)
节点 2 :
我会将这个用于 NVME 存储,但它与 Raspberry Pi 4s 不兼容。
节点 3 :
但是,SATA 端口可以在这里使用。因此,此节点将具有 NFS 共享驱动器。
节点 4 :
USB 3.0 端口(如果我需要的话)。
我的老树莓派:
我已经很久没有组装过电脑了,这是我第一次摆弄计算模块及其适配器,所以周末玩得很开心。由于我的钱包很热但还没有烧起来,我想,为什么不给它装个漂亮的外壳呢?
鉴于主板的 Mini ITX 外形尺寸,我可以将其装入我在亚马逊上找到的任何精美 ITX 机箱中。Qube 500让我完全满意。我已经在制作 DIY 集群,这种东西的最佳机箱也是 DIY 的。
我还添加了一个 650W 电源(完全过度了)、一张小型 Wi-Fi Mini PCI Express 卡和一个 1TB SATA SSD。
把这个“东西”组装起来相当简单。在计算模块和散热器之间涂一点导热膏,然后用适配器把它们粘在一起,然后按顺序把它们安装在图灵板上;
我提到顺序是因为它是项目的重要组成部分。Turing Pi 2 提供分布在整个计算模块中的端口管理。在这种情况下,PCI Express 1 由第一个节点管理,而 SSD 驱动器由第三个节点管理。第二个节点可以处理 NVME 端口,第四个节点可以处理另一个 SSD IIRC,但我现在用不到它们。
我以前安装过 Raspberry Pi,但从未安装过计算模块。Turing Pi 2 背面有一个 USB 端口,用于刷新计算模块。
不幸的是,我尝试使用 USB A 到 USB A 电缆,但它不是数据传输电缆,因此在等待亚马逊送货电缆时,我找到了另一种刷新计算模块的方法。
Turing Pi 2 有一个 CLI 工具,不仅可以用来刷新计算模块,还可以用来管理其电源、重置它们、检查一些统计数据等等。
用于安装计算模块的命令是:
tpi flash -i /path/to/image -n {nodes 1 to 4}
我心想这是一个相当简单的过程,后来我才意识到 Raspbian 映像默认没有启用 SSH。
当然,这不是图灵的责任。我应该等那封电报,但没关系。
为了解决这个问题,我必须在本地机器上安装映像,并在启动分区中添加一个名为ssh
的空文件。这将默认启用 SSH。
sudo mkdir /mnt/pi-boot sudo mount /dev/sdX1 /mnt/pi-boot sudo touch /mnt/pi-boot/ssh sudo umount /mnt/pi-boot
现在,我的所有 pi 都已准备就绪。我将它们连接到网络并开始配置它们。由于我打算将它们用作 Kubernetes 节点,因此几乎不需要配置。
但是 vim 和更新系统之类的东西是必要的。
这也给了我学习如何使用Tmux的机会。这是我最近学到的最好的工具。
如果您还记得上面的几段话,我提到第 3 个节点将用于 NFS 共享驱动器。我有一个 1TB SSD 驱动器,我将用它来做这个用途。我必须将其格式化并安装在第 3 个节点上。
但是我还需要在这个节点上安装 NFS 服务器并在其他节点上进行配置。这是否适合于生产环境?当然不,但这是一个家庭集群,所以我并不太担心。
以下是我配置 NFS 服务器的步骤:
pi@turing-03:/mnt/ssd/data $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 953.9G 0 disk /mnt/ssd mmcblk0 179:0 0 7.3G 0 disk ├─mmcblk0p1 179:1 0 512M 0 part /boot/firmware └─mmcblk0p2 179:2 0 6.8G 0 part / mmcblk0boot0 179:32 0 4M 1 disk mmcblk0boot1 179:64 0 4M 1 disk
首先,我检查驱动器是否已正确安装。然后我安装了 NFS 服务器:
sudo mkdir /mnt/nfs_share sudo mount /dev/sda /mnt/nfs_share
将其添加到 fstab 文件中以确保它在启动时被挂载:
(将以下行添加到/etc/fstab
文件)
echo '/dev/sda /mnt/ssd ext4 defaults 0 0' | sudo tee -a /etc/fstab
现在,安装 nfs-kernel-server:
sudo apt update sudo apt install nfs-kernel-server
并将我的驱动器添加到/etc/exports
文件:
echo '/mnt/ssd *(rw,sync,no_subtree_check,no_root_squash)' | sudo tee -a /etc/exports
现在,在其他节点上,我必须安装 nfs-common:
sudo apt update sudo apt install nfs-common
并将驱动器挂接到每个节点:
sudo mount -t nfs {IP-for-the-drives-node}:/mnt/ssd /mnt
因为我喜欢,所以在所有节点都安装了Neofetch 。
我之前从未从头开始设置过 Kubernetes 集群,但我一直在观看Jeff Geerling 关于这个主题的大量视频......这已经足够有经验了,对吧?
Jeff 引导我使用Ansible来使用K3s ,这是一个轻量级的 Kubernetes 发行版,非常适合我的家庭集群,并且具有预定义的安装方式,因为我没有预先要求,也不知道如何进行设置。
安装非常简单。我必须在所有节点上安装它,但我必须确保主节点是第一个安装的节点。
因此首先,我克隆了 k3s-ansible 存储库:
git clone https://github.com/k3s-io/k3s-ansible.git
然后我必须配置清单文件。正如我之前提到的,我的主节点是我的旧 Raspberry Pi 4。所以我必须确保它是清单文件中的第一个节点。我还必须确保其他节点位于正确的组中。:
k3s_cluster: children: server: hosts: 192.168.2.105: agent: hosts: 192.168.2.101: 192.168.2.102: 192.168.2.103: 192.168.2.104:
在同一个文件中,我必须设置一个加密令牌。该文件指示了如何执行此操作,因此我不会在这里详细介绍。
然后我必须运行剧本:
cd k3s-ansible ansible-playbook playbooks/site.yml -i inventory.yml
就是这样。就安装而言,我已经启动并运行了一个 Kubernetes 集群。我必须在本地机器上安装K9s来管理集群并将集群绑定到./kube/config
文件。
最后,我必须安装我想在集群中运行的应用程序。我对自己想要的东西有一些想法。
这就是我的存储库的用武之地。
对于媒体服务器,我决定使用:
作为示例,我将向您展示如何使用kubectl
安装 Sonarr。其他应用程序的安装方式类似。
对于每个应用程序,我创建了 3 个文件:
deployment.yaml
是运行应用程序的每个 pod 的配置
apiVersion: apps/v1 kind: Deployment metadata: name: sonarr spec: replicas: 1 selector: matchLabels: app: sonarr template: metadata: labels: app: sonarr spec: containers: - name: sonarr image: linuxserver/sonarr ports: - containerPort: 8989 env: - name: PUID value: "911" - name: PGID value: "911" - name: TZ value: "Europe/Amsterdam" volumeMounts: - mountPath: /data name: data - name: config mountPath: /config volumes: - name: data persistentVolumeClaim: claimName: nfs-pvc - name: config persistentVolumeClaim: claimName: nfs-config-pvc
service.yaml
是将应用程序公开给集群的服务的配置
apiVersion: v1 kind: Service metadata: name: sonarr spec: selector: app: sonarr ports: - port: 80 targetPort: 8989 type: ClusterIP
ingress.yaml
,这是入口的配置,它将应用程序暴露给我的网络
然后我们使用kubectl
部署它们全部:
kubectl apply -f sonarr/deployment.yaml kubectl apply -f sonarr/service.yaml kubectl apply -f sonarr/ingress.yaml
如您所见,我正在使用 NFS 支持的持久存储来保存数据和应用程序的配置。
在存储库中,您可以找到我用于创建 NFS 存储的nfs-pv.yaml和nfs-pvc.yaml文件。
虽然这个机箱看起来很棒,但对于 Raspberry Pi 集群来说还是有点太大了。Mini ITX 机箱也适合我的需求,但我不得不承认,我很喜欢 DIY 东西。
另外,一般来说,LED 吸盘。我没有在机箱上添加任何灯,但我认为主板已经做得很好了。不幸的是,风扇插针与主板不兼容,我没有购买风扇控制器或主板插针。我以后可能会买。
最后,Turing Pi 2 家庭集群已启动并运行,我的房子不再杂乱无章。
只有时间才能告诉我们我将如何处理这个集群。
不过,我一直在考虑添加Prometheus和Grafana ,以便获得一些指标和漂亮的图表来检查集群。
将我的所有 Kubernetes 文件迁移到Helm也是一个好主意。
最后,Retroarch 实例仍在开发中。考虑到 pod 处于 CrashLoopBackOff 状态,可能“正在开发”有点过于乐观。但我会做到的。
如果您已经读完了这篇文章,我感谢您抽出时间。我希望您和我一样喜欢这篇文章,无论是组装集群还是撰写文章。