2022 年 6 月、最大 4 つのRaspberry Pi 4 Compute Module を同時に搭載できるボードに関するKickstarterを見つけました。
あまり熟考することなく、私はプロジェクトを支援してボードを購入することにしました。
それから2年が経ち、私のTuring Pi 2は未開封のまま箱に入ったまま棚に置かれていました。人生のさまざまな出来事が邪魔をして、そもそもなぜ購入したのか分からなくなっていました。
しかし、ついに試してみることにしました。クラスタリングについてもっと学びたかったのですが、これまでKubernetesクラスタをゼロから構築したことがありませんでした。そこで、出費モードに切り替え、Raspberry Pi 4(8GB RAM、8GB内部ストレージ)を3台とNvidia Jetson Nano (4GB)を1台購入しました。
ボードの汎用性を考えると、さまざまなコンピューティング モジュールを組み合わせることができます。将来的には CUDA ドライバーを試したり、機械学習を詳しく調べたりできるかもしれないと考え、Jetson Nano を含めることにしました。どうなるかわかりません。この Kubernetes クラスターで独自の GPT アシスタントをホストすることさえあるかもしれません。
(Spoilers: It didn't happen)
当初の計画では、3 台の Pi 4 CM と、ボード上にホストされた Jetson Nano を用意していました。また、ストレージには 1 TB SSD ドライブ、インターネット アクセスには Wi-Fi カードを使用する予定でした。しかし、Jetson Nano のセットアップ プロセスで多くの問題に遭遇し、ドキュメントも不十分だったため、返品することにしました。代わりに、4 台目の Raspberry Pi 4 を選択しました。
さらに、4GB の RAM を搭載した古い Raspberry Pi 4 が手元にあったので、それを 5 番目のノードとして組み込むことにしました。
Turing Pi 2 は、最大 4 つの Raspberry Pi コンピューティング モジュール (Jetson Nano および Turing コンピューティング モジュールとも互換性あり) を搭載できる Mini ITX フォーム ファクタ ボードです。PCI Express ポート、2 つの NVME ポート、2 つの SATA ポート、およびコンピューティング モジュールをフラッシュするための USB ポートを備えています。
ノード1 :
USB 2.0 ポート (コンピューティング モジュールのフラッシュ用)
HDMIポート(デバッグ用)
PCI Express ポート (Wi-Fi カード用)
ノード2 :
これを NVME ストレージに使用しますが、Raspberry Pi 4 とは互換性がありません。
ノード3 :
ただし、SATA ポートはここで使用できます。したがって、このノードには NFS 共有ドライブが存在します。
ノード4 :
USB 3.0 ポート (必要な場合)。
私の古いラズベリー:
最終的には、いくつかのアドオンを備えたメディア サーバーをホストするというアイデアです。
コンピューターを組み立てるのは久しぶりで、コンピュート モジュールとそのアダプターをいじったのは初めてだったので、週末は十分楽しめました。財布は熱くなっていましたが、まだ燃えるほどではなかったため、素敵なケースを追加してもいいかなと思いました。
ボードのフォーム ファクタが Mini ITX なので、Amazon で見つけたどんな高級 ITX ケースにも収まりました。Qube 500 は私を完全に満足させました。私はすでに DIY クラスターを作っていましたが、そのようなものに最適なケースも DIY でした。
また、650W 電源 (完全に過剰)、小型の Wi-Fi Mini PCI Express カード 1 枚、および 1TB SATA SSD も追加しました。
この「もの」を組み立てるのはかなり簡単でした。コンピューティング モジュールとヒートシンクの間に熱伝導グリスを少し塗り、アダプターでしっかりと固定してから、Turing ボードに順番に取り付けます。
順序について言及したのは、それがプロジェクトの重要な部分だったからです。Turing Pi 2 は、コンピューティング モジュール全体に分散されたポートの管理を提供します。この場合、PCI Express 1 は最初のノードによって管理され、SSD ドライブは 3 番目のノードによって管理されました。2 番目のノードは NVME ポートを処理でき、4 番目のノードは別の SSD で処理できたと思いますが、現時点ではそれらを使用する予定はありませんでした。
これまでに Raspberry Pi をインストールしたことはありますが、Compute Modules をインストールしたことはありませんでした。Turing Pi 2 には、Compute Modules をフラッシュするために使用される USB ポートが背面にあります。
残念ながら、データ転送ケーブルではない USB A から USB A へのケーブルを使用しようとしたため、Amazon がケーブルを配達するのを待っている間に、Compute Modules をフラッシュする別の方法を見つけました。
Turing Pi 2 には、Compute Module のフラッシュだけでなく、電源の管理、リセット、統計の確認などにも使用できる 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 共有ドライブ用に使用されると述べました。この目的で使用する予定だった 1 TB 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 は、私のホーム クラスターに最適な軽量の Kubernetes ディストリビューションであるAnsibleを使用してK3s を紹介してくれました。また、私には前提条件がなかったり、他の方法でセットアップする方法がわからなかったりしたため、インストール方法が事前に定義されていました。
インストールは非常に簡単でした。すべてのノードにインストールする必要がありましたが、マスターノードが最初にインストールされるようにする必要がありました。
そこでまず、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 クラスターが稼働していました。クラスターを管理し、クラスターを./kube/config
ファイルにバインドするには、ローカル マシンにK9sをインストールする必要がありました。
最後に、クラスターで実行したいアプリケーションをインストールする必要がありました。何が必要かはいくつか考えていました。
ここで私のリポジトリが役に立ちます。
メディア サーバーには以下を使用することにしました。
例として、 kubectl
使用して Sonarr をインストールする方法を紹介します。他のアプリケーションも同様の方法でインストールされました。
アプリケーションごとに 3 つのファイルを作成しました。
deployment.yaml
、アプリケーションを実行する各ポッドの設定です。
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
は、アプリケーションをネットワークに公開するIngressの設定です。
次に、 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 Cluster には少し大きすぎます。Mini ITX ケースでも私のニーズには合っていたでしょうが、私は DIY に夢中なのを認めざるを得ません。
また、LED 全般に目がない。ケースにライトを追加しなかったが、ボードはすでに優れた機能を果たしていると思う。残念ながら、ファン ピンはボードと互換性がなく、ファン コントローラーやマザーボード用のピンを購入しなかった。将来的には購入するかもしれない。
そしてついに、Turing Pi 2 ホーム クラスターが稼働し、私の家はもう散らかっていません。
このクラスターで何をするかは、時間が経てばわかるでしょう。
ただし、クラスターをチェックするためのメトリックと優れたグラフを取得するために、 PrometheusとGrafana を追加することを考えています。
すべての Kubernetes ファイルをHelmに移行することも良い考えです。
最後に、Retroarch インスタンスはまだ作業中です。ポッドが CrashLoopBackOff 状態にあることを考えると、作業中というのは少し楽観的すぎるかもしれません。しかし、私はそこに到達します。
この投稿の最後までお読みくださった方、お時間をいただきありがとうございました。クラスターの組み立てとそれについての記事の執筆を私と同じくらい楽しんでいただけたなら幸いです。