Kubernetes on Rapsberry Pi Part 2: ハードウェアと事前準備

Contents

Part1から随分と経ってしまいましたが、いよいよk8sクラスタを組んでいきたいと思います。

執筆開始時点(2022/01/17)での最新バージョンであるKubernetes 1.23を利用しているので、これから自前でクラスタを組んでみたいという方にも参考になればと思います。

製品 個数 役割等
Raspberry Pi 4 4GB 3 Control Plane (HA)
Raspberry Pi 4 8GB 1 Worker Node 1
Raspberry Pi 4 4GB 4 Worker Node 2-5
ほんとは全部8GBにしたい
Raspberry Pi 4 4GB 2 ロードバランサー for HA
4GBもいらないと思う
Micro SD 32GB 10 ラズパイの数だけ
SSD化だったりPXEブートなんかもあるみたいだけど、せっかくのHA構成なので壊れてなんぼと言い聞かせる
PoE+ HAT 3 電源ケーブルを減らしたかった
Control Plane用
PoE+対応スイッチ 1 クラスタネットワーク用
せっかくのラズパイ4なのでギガビット対応がおすすめ
中古のスマートL2スイッチが異様に安かったので買った
Anker PowerPort 10 1 Hatをかぶれないラズパイ用の電源
1ポートの出力電流が3Aに届いていないので別の商品のほうがいいかも
USB A to Cケーブル いっぱい 電源にあわせて選ぶ
LANケーブル いっぱい PoE+を使いたければCAT5e以上で
GeeekPi Raspberry Pi4 Cluster Case 2 よくみるやつ
8台あるので2セット

この構成はあくまで私が使ったものなので、使用機器やPoEの利用は利用目的や予算と相談して決めてみてください。

ラズパイのメモリに関しては(特にWorkerノードでは)4GB以上が無難だと思います。

/posts/raspberry-pi-k8s-cluster/part2/hats.jpg /posts/raspberry-pi-k8s-cluster/part2/POEHAT.jpg ラズパイにかぶせることで、LANケーブルから電源供給してくれるすごいやつです。

ラズパイ4(w/ HAT)で利用できるPoE規格は2種類あり(下記参照)、見ての通りPoE+はその内の強いほうです。

通称 規格名 最大給電電力 対応商品
PoE 802.3af (802.3at Type 1) 15.4W PoE HAT
PoE+ 802.3at Type 2 30.0W PoE+ HAT

ただ正直今回の目的であれば通常のPoE Hatでも十分だと思いますし、何よりハットや対応スイッチが割高なので、そもそもPoEをわざわざ使う必要もないと思います。

ケーブルをなるべく減らしたいミニマリストな方はぜひご検討ください。

ではハードの話はこのくらいにして、OSのインストールから始めていきましょう!

今回使用するOSはUbuntu Server 20.04.3 LTSになります。

採用理由としてラズパイスペシフィックでは無い、かつ最新のLTS対応64bitOSであったことです。

とはいえ所詮は実験環境なので、最新の21系統を使ってもいいと思います。ここからの手順も問題なくこなせるはずです。(あくまで自己責任で)

それでは、ここからOSインストールの手順になります。

  1. Raspberry Pi ImagerをMicro SDカードを使える環境にダウンロード、インストール
    /posts/raspberry-pi-k8s-cluster/part2/imager0.png
  2. Imagerを起動し、CHOOSE OS -> Other general purpose OS -> Ubuntu -> Ubuntu Server 20.04.03 LTS ... 64-bit serverを選択(ローカルにあらかじめOSを用意していた場合、CHOOSE OS -> Use customから選択) /posts/raspberry-pi-k8s-cluster/part2/imager1.png
  3. CHOOSE STORAGEから、OSをインストールしたいSDカードを選択(他の外部ストレージを選択しないよう注意!
  4. WRITEから書き込み(SDのデータ消えちゃうけど大丈夫?といった感じの注意が出てくる)
  5. 書き込みが完了したら、キーボートとディスプレイを接続したラズパイに挿入し、起動
  6. (本体に問題がない限り)CUIのログイン画面にたどり着くと思うので、Ubuntuの初期ユーザでログイン
    user password
    ubuntu ubuntu
  7. ログインするとubuntuユーザのパスワード変更を要求されるので、変更
  8. 台数分繰り返す

自動化が全くできない部分なので一番めんどくさいです。
PXEブートをするにしろ結局一度はSD等物理ストレージからブートする必要があるようなので、この作業はほぼ必須になるんじゃないかなと思います。
ラズパイを5000台買ってk8sクラスタの限界に挑戦したい方は頑張ってください。

無事OSがインストールできたら、簡単な初期設定を行います。sshdはプリインストールされていると思うので、上記の手順でubuntuユーザにパスワードさえ設定できていればリモート接続できると思います。

まずはrootのパスワードを設定してしまいましょう。というのもUbuntuでは初期設定されていないのです。

1
2
3
4
5
6
$ sudo passwd root
[sudo] password for ubuntu:   # 設定したubuntuのパスワード
New password:                 # rootのパスワード
Retype new password:          # 確認

passwd: password updated successfully

次に、Kubernetes全般の操作用にユーザを作りましょう。
実験環境だし別にubuntuユーザで進めてしまってもいいと思うのですが、まあ分かりやすくなるので作っておきましょう。

1
2
3
4
$ sudo adduser k8s

グループ名をKubernetesにしたい場合(グループオプション)
$ sudo adduser k8s kubernetes

対話式でパスワードなど設定できます。

Redhat系のOSを普段利用している人はついついuseraddしてしまいますが(してしまった)、Ubuntuだとデフォルトでホームディレクトリが作成されないので気を付けましょう。

タイムゾーンをJSTに変更したい場合は以下のコマンドで簡単に設定できます。

1
$ sudo timedatectl set-timezone Asia/Tokyo

ここから、この記事で一番重要な部分であるネットワーク設定を行っていきます。

Kubernetes等の分散システムではノードのIPを固定化することが通例(固定IPのほうが楽)なので、各ノードに固定IPを設定しましょう。

Ubuntuサーバでは17.10からネットワークの設定にNetplanを利用することになっています。

これは/etc/netplan以下のyamlファイルをもとにネットワーク設定を行ってくれる機能であり、今回のインストール方法だとおそらく/etc/netplan/50-cloud-init.yamlというファイルが読み込まれているはずです。

このファイルを書き換えることも一応可能ですが、そもそもこのファイルはcloud-initという環境設定フレームワークによって自動生成されたものであるので、書き換えるのではなく新しい設定ファイルを作成するのが無難であるようです。(詳しくはここに

ということで新しく設定ファイルを作成しましょう。/etc/netplan下の番号の若いものから読まれていき、後から読まれた設定が上書きされる仕組みであるため、50-cloud-init.yaml50より高い番号で設定しましょう。通例99から始まるファイル名にします。

私は以下のように設定しました。

1
$ sudo vim 99-custom.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
network:
    ethernets:
        eth0:
            dhcp4: false
            set-name: eth0
            match:
                    macaddress: NICのMACアドレス
            addresses: [設定したいIP]
            gateway4: デフォルトゲートウェイのIP
            nameservers:
                    addresses: [デフォルトゲートウェイのIP, 8.8.8.8, 8.8.4.4]
            optional: true
    wifis:
        wlan0:
            dhcp4: false
            access-points:
                    "WiFiのSSID":
                            password: "WiFiパスワード"
            addresses: [設定したいIP]
            nameservers:
                    addresses: [デフォルトゲートウェイのIP, 8.8.8.8, 8.8.4.4]
    version: 2
    renderer: NetworkManager

wifiに関してはIPを固定する必要ありませんが、私は管理用のマシンから無線でつなぐため簡単にアクセスできるよう設定しました。

設定項目の一つにrendererというものがありますが、これは実際にネットワークの設定を行うシステムデーモンを指定する箇所です。

というのも、実はnetplan自体はあくまでユーザ用のガワでしかなく、yaml内の記述を元にデーモンが利用する設定ファイルを生成するだけなのです。

そして実際の設定を行うのがsystemd-networkd(Ubuntu Serverではデフォルト)または私が設定しているNetworkManager(Ubuntu Desktopではデフォルト)になります。

今回の設定ではどちらでも問題ありませんが、私はNetworkManagerに慣れていたのでnm系コマンドで管理できるようNetworkManagerを設定しました。

yamlファイルを作成出来たら、設定を反映するべく以下のコマンドを実行します。リモートでつないでいる場合接続が切れる可能性があるのでご注意ください。(多分切れない)

1
$ sudo netplan apply

今回はKubernetesクラスタを作成する前段階について説明しました。

次回(1月中には書きたい…)はいよいよクラスタ作成を行っていきます。

https://kubernetes.io/blog/2021/12/07/kubernetes-1-23-release-announcement/ https://kubernetes.io/docs/setup/best-practices/cluster-large/ https://www.differencebetween.com/difference-between-adduser-and-vs-useradd/ https://netplan.io/ https://qiita.com/yas-nyan/items/9033fb1d1037dcf9dba5 https://www.komee.org/entry/2018/06/12/181400