【環境構築】Raspberry Pi 4台で作るKubernetesクラスタ
前書き:憧れのラズパイクラスタ
Raspberry Piでスパコンを構築する取り組みは昔からありましたが、最近は「Kubernetesクラスタを作ったよ」という報告が増えてきました。私もラズパイ4(8GB)を一台購入してラズパイが合計4台となったのをキッカケに、憧れのラズパイクラスタに手を出してみました!
本記事では「導入手順(ネットワーク接続などのセットアップ説明は除く)」や「ハマったポイント」を紹介します。
クラスタ材料(ハード、ソフト)
機器・ソフト | 個数 | 役割・備考 |
Raspberry Pi | 4台 | 本記事ではRaspberry Pi 3(2台)、Pi 4(2台)を使用。クラスタのMasterはメモリ使用量が大きいので、Pi4(RAM4GB以上)がオススメ。 |
microSD | 4枚 | 本記事では16GB〜64GBを使用。Class10、32GB以上がオススメ。16GBの場合、クラスタ構築が終わった段階で空き容量が不足するかもしれません。 |
LANケーブル | 5本 | 本記事ではCat6aを使用。 |
4層ラックケース | 1個 | Raspberry Piを縦に積み上げるタイプのケース。ファンとヒートシンクも付いてきて、お得感があります。私は1層タイプのケースも予備で買いました。 |
USB Type A to TypeC | X個 | Raspberry Pi4用の電源ケーブル。Pi4の数だけ必要。 |
microUSB to USB TypeA | X個 | Raspberry Pi3用の電源ケーブル。Pi4の数だけ必要。 |
microHDMIケーブル | 1個 | Raspberry Pi4用の映像出力ケーブル。 |
HDMIケーブル | 1個 | Raspberry Pi3用の映像出力ケーブル。 |
無線LAN親機(小型) | 1個 | 上流のルータに無線接続する時に使用しますが、有線接続の場合は不要。 |
スイッチングハブ | 1個 | Raspberry Pi 4台のLANと接続するスイッチングハブ。 |
USB充電器 | 1個 | 本記事では60W、6ポートのタイプを使用。 |
Raspberry Pi OS with Desktop | 1個 | Raspberry PiのOS。最終的にはデスクトップ環境は不要なので、Linuxが得意な人はLite版でも問題ありません。 |
自宅に余っているRaspberry Pi 2, 3とPi4 (RAM 8GB)を使って、ラズパイクラスタを作るぞ! pic.twitter.com/uxyBRukYqx
— Nao (@ARC_AED) June 4, 2020
上記のTweetでRaspberry Pi2を使ったと書いていますが、組み立て中にお亡くなりになっている事が判明したので、2から4に差し替えました。
ラズパイクラスタの最下段のお方(Pi2B)、天寿を全うされていました。
— Nao (@ARC_AED) June 6, 2020
手持ちのボードで代替すると、環境構築の難易度が上がるので、ラズパイ4を補充します。 pic.twitter.com/8Dj84by4vb
Raspberry Piの基本的なセットアップと組み立て
Raspberry Piの基本的なセットアップおよび組み立て方法は、本記事では説明しません。想定している基本的なセットアップ内容を以下に示します。
- Raspberry Pi用のOSをmicroSDカードに書き込み
- Raspberry Piを起動し、キーボードや時刻の設定
- Raspberry Piを無線もしくは有線でネットワーク接続
- Raspberry Piが使用できるmicroSDの領域を拡大
- OSのアップデート
組み立てに関しては、説明書に図が多いため、1〜2時間で完了すると思われます。
ラズパイクラスタ組み立て中。 pic.twitter.com/iUtDxoin4W
— Nao (@ARC_AED) June 4, 2020
全てのRaspberry Piを固定IP化
DHCP設定の場合、Raspberry Piの再起動に伴い、IPアドレスが変わってしまいます。この状態では、Host環境からRaspberry PiにSSH接続する際に不便ですので、IPアドレスを固定化します。
以下の記事を参考にIPアドレスを固定化します。SSH接続する際にIPアドレスが必須なので、メモしてください。
Raspberry Piに固定IPを割り当てる方法
全てのRaspberry PiのHost名を変更
この手順は必須ではありません。SSH接続した際に、どのRaspberry Piにログインしているか(およびクラスタのMaster<->Slaveの関係)を分かりやすくするために、Host名を変更します。
Host名は、任意です。よく見られる命名規則は都市の名前、ディズニーキャラ名、太陽系の惑星名などを使用するケースです。私は、スラッシュメタル四天王(Big4)の名前を付けました。この名付けによって、ラズパイクラスタへの愛着が増します。
以下、Host名とRaspberry Piの組み合わせです。
機器 | Host名 | 役割 |
Raspberry Pi4(8GB) | metallica | ラズパイクラスタのMaster |
Raspberry Pi3 Model B | megadeth | ラズパイクラスタのSlaveその1 |
Raspberry Pi3 Model B | slayer | ラズパイクラスタのSlaveその2 |
Raspberry Pi4(2GB) | anthrax | ラズパイクラスタのSlaveその3 |
Host名を変える際は、hostnamectlコマンドを使用します。hostnamectlコマンドだけでは、unknown hostエラーが出るため、/etc/hostsファイルも修正します。なお、/etc/hostsは、Host名とIPアドレスを対応させる役割を持つファイルです。
1 2 3 4 5 6 |
(注釈):Host環境からRaspberry PiにSSH接続 # ssh pi@$(Raspberry PiのIPアドレス) (注釈):ここからの手順はRaspberry Pi上で実施 $ sudo hostnamectl set-hostname $(任意のHost名) $ sudo vi /etc/hosts |
1 2 3 4 5 6 7 |
(注釈) 以下の記述(ファイル末尾)を変更する。 ※変更前 127.0.1.1 raspberrypi ※変更後 127.0.1.1 $(任意のHost名) |
上記の手順を全てのRaspberry Piに実行したら、”$ sudo reboot”などで再起動します。
Raspberry Piに新規ユーザを追加し、piユーザを削除
Raspberry Piのデフォルトユーザ(piユーザ)は、パスワードが知れ渡っているため、セキュリティリスクがあります。そのため、新規ユーザ(任意のユーザ名)を作成し、piユーザを削除します。
【セキュリティ対策】Raspberry Pi4に新規ユーザを追加し、piユーザを削除
SSH接続設定(セキュリティ対策含む)
デフォルト設定では、Raspberry PiはSSHが無効化されています。
SSHを有効化するには、Raspberry Piの/bootディレクトリにsshファイル(空ファイル)を置くか、もしくは以下のコマンドをRaspberry Pi上で実行してください。
1 2 3 4 5 6 7 8 |
$ sudo raspi-config ※ Raspberry Pi Software Configuration Tooki(raspi-config)画面で、以下の順番で選択 [5 Interfacing Options] ⇓ [P2 SSH] ⇓ [SSHを有効化するかどうかの質問に対して"Yes"] |
デフォルトのSSH接続設定は脆弱なので、以下の記事を参考にセキュリティ対策を実施してください。
Raspberry Pi3向けのセキュアSSH接続設定(公開鍵認証、rootアクセス禁止、ログインユーザ設定など)
Dockerのインストール
ここまでの手順を実施すれば、Kubernetesのインストールまであと一歩です。
DockerとDocker Composeをインストールしますので、別記事を参照してください。
Raspberry Pi3/4にDockerとdocker-composeをインストールする方法
Kubernetesのインストール
ここまでの手順で、Kubernetesインストールのための前準備が完了しました。以降の手順は、(ようやく)Kuberbetesの環境構築となります。
まずは、Kubernetes用パッケージマネージャであるHelmをインストールします。インストールスクリプトを利用した以下の手順は私の環境で失敗したので、後述するsnapパッケージマネージャを利用して入れました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
※ !!! 注意:以下の手順は失敗する可能性があるため、参考情報としてみてください !!! ※ Helmインストールスクリプトの取得 $ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 $ ls get_helm.sh ※ 実行権限の付与 $ chmod a+x get_helm.sh ※ インストールの実行 $ ./get_helm.sh Downloading https://get.helm.sh/helm-v3.3.0-linux-arm64.tar.gz tar: linux-arm64/helm: Wrote only 3072 of 10240 bytes tar: linux-arm64/LICENSE: Cannot write: No space left on device ※ 容量は足りているが、本エラーが出る。 tar: Exiting with failure status due to previous errors Failed to install helm For support, go to https://github.com/helm/helm. |
snapパッケージマネージャを利用したHelmインストール手順は、以下の通りです。
1 2 3 4 |
$ sudo apt update $ sudo apt install snapd $ sudo reboot $ sudo snap install helm --classic |
次に、Kubernetesクラスタの構築に用いるkubeadmin(クラスタ起動コマンド)、KubernetesをCLIで操作するkubectl、Pod管理エージェントのkubelet(Podやコンテナを起動するコンポーネント)をインストールします(公式サイトの手順もリンクしておきます)。
インストール前にレガシー版のiptablesに関する設定を行います。2020年にRaspberry Pi OS(正確にはDebian10以降)は、iptablesは内部的にnftablesを使用しており、nftablesとkubeadminに互換性がない問題があります。この問題を回避するために、iptablesをレガシーモードで使用します。
1 2 3 4 5 6 7 8 |
(注釈) レガシーツールをインストールする $ sudo apt install -y iptables arptables ebtables (注釈) レガシー設定を有効化 $ sudo update-alternatives --set iptables /usr/sbin/iptables-legacy $ sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy $ sudo update-alternatives --set arptables /usr/sbin/arptables-legacy $ sudo update-alternatives --set ebtables /usr/sbin/ebtables-legacy |
kubeadmin、kubectl、kubeletをインストールします。また、これらのパッケージはapt-markコマンドを用いて、パッケージ更新対象外とします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
(注釈) 依存パッケージのインストール $ sudo apt update $ sudo apt install -y apt-transport-https curl (注釈) kubernetesの公開鍵を追加 $ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - $ cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list deb https://apt.kubernetes.io/ kubernetes-xenial main EOF (注釈) インストール処理および更新対象外設定 $ sudo apt-get update $ sudo apt-get install -y kubelet kubeadm kubectl $ sudo apt-mark hold kubelet kubeadm kubectl |
Masterノードの構築
CNI(コンテナネットワーキング)プラグインは、Flannelを使用します。
1 2 |
(注釈) Flannelの場合、10.244.0.0/16を指定する。 $ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 |
kubeadm initを実行後、kubectlの設定方法が出力されるので、その内容を順に実行します。また、kubeadm joinに関する設定方法も出力されるので、そちらもメモしておきます(私はメモを無くしてしまいました…)。
1 2 3 4 |
(注釈) kubectlの設定 $ mkdir -p $HOME/.kube $ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config $ sudo chown $(id -u):$(id -g) $HOME/.kube/config |
Pod Network Addonをインストールします。
1 |
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml |
Workerノードの構築
今回はWorkerノードが3台あるため、その3台に対して以下の手順を実行し、Workerノードをクラスタに参加させます。
入力するコマンドは、Masterノードkubeadm initコマンド実行後に表示されたkubeadm joinコマンドです。
1 2 |
(注釈) 環境によって入力するコマンドが異なる。 $ sudo kubeadm join 192.168.13.2:6443 --token vpmuze.ina6swjhlxh57lds --discovery-token-ca-cert-hash sha256:fcda1034ebb1374f0a0b487cd349b29ac1c253e83e6344b4d567cf61123a509c |
全てのWorkerノードがクラスタに参加した後、”$ kubectl get nodes”で各ノードのステータスを確認できます。STATUS部分がREADY以外の場合は、上手く設定できていない可能性があります。
最後に
Kubernetesクラスタ環境構築は面倒くさい部類であり、一日近くの時間を要します。
さらに、特に動かしたいDockerコンテナアプリがない場合は、「ここから先、どうすればいいんだ?」と手が止まります。少なくとも私は、何も考えずに作ったクラスタの使い道に困っています。
ハード購入費用もそこそこするので、よく考えてから手を出しましょう(戒め)。
ロシア人と国際結婚した地方エンジニア。
小学〜大学院、就職の全てが新潟。
大学の専攻は福祉工学だったのに、エンジニアとして就職。新卒入社した会社ではOS開発や半導体露光装置ソフトを開発。現在はサーバーサイドエンジニアとして修行中。HR/HM(メタル)とロシア妻が好き。サイトに関するお問い合わせやTwitterフォローは、お気軽にどうぞ。