ラズパイ4で自宅にk3sクラスタを構築してみる

こんにちは。

皆様は先日のブラックフライデーで何かポチリましたでしょうか。
今年の僕はというと、EchoBot、HHKBにオーブンレンジ、そしてラズパイ2台を購入し、なんともメカメカしい生活をしております。
別に目的があって買ったわけでもないこのラズパイを使ってk3sの検証がてらクラスタを組んでみたいと思います。

# 環境
* 機材：
    * Rasberry Pi4 model B 8GBRAM
    * Rasberry Pi4 model B 4GBRAM
    * SDカード 64GB × 2
* OS: Ubuntu server 20.04

# 構成
今回はmaster1台, worker1台で構築します。

|  ホスト名  |  IP address  |
| ---- | ---- |
|  k3s-master  |  192.168.0.10  |
|  k3s-worker01  |  192.168.0.11  |

workerは今後増したいと思っているので、サフィックスに番号を添えておくことにしました。

# ラズパイの基本設定
SDカードにOSを書き込んで起動、初期セットアップをしていきます。
ここはmaster, workerに関係なく実施します。

## OSインストール
SDカードに書き込む際には公式が出している[Imager](https://www.raspberrypi.org/software/ "imager")というツールを使用しました。
シンプルで使いやすく特に迷うところはなかったです。
 
SDカードに挿して電源を入れると勝手に起動してきます。
## 事前準備
キーボード、モニターをつないで設定していきます。
Ubuntu serverを起動するとログインユーザとパスワードを聞かれます。初期状態のユーザ名とパスワードは両方`ubuntu`です。

### 作業用ユーザ作成
まずは作業用のユーザを作成して初期ユーザから脱却します。

```
$ sudo adduser <username>
// パスワードを聞かれるので、任意のものを入力してください
$ sudo adduser <username> sudo
$ sudo passwd -d ubuntu
```

### ホストネーム変更
次にホストネームを変更しておきます。

```
$ hostnamectl set-hostname k3s-master
```

### SSH鍵の生成・sshdの設定
ubuntu server20.04では、すでにsshdが起動していましたので、私は以降は作業用PCからSSH接続して設定を続けました。
まだ鍵の登録をしていないので、パスワード認証でSSH接続します。


パスワード認証でSSH接続できたら、SSH鍵の登録とssh_configの設定をします。
接続元で鍵を生成して、公開鍵を転送します。

```
$ ssh-keygen -t rsa -b 4096
$ ssh-copy-id -i ~/.ssh/id_rsa.pub <username>@192.168.0.10
```

さらにsshd_configの設定をします。

```
$ sudo vim /etc/ssh/sshd_config
// 以下の点を編集
Port 10022 // 未使用の任意のポート番号
PasswordAuthentication no
```

ポート番号の変更とパスワード認証による接続を禁止するよう設定しています。
最後にsshdを再起動します。

```
$ sudo systemctl restart sshd
```

### ネットワークの設定
私は無線接続することにしたので、wifiの設定をします。

```
$ sudo vim /etc/netplan/50-cloud-init.yaml
// 以下のように設定しました
ethernets:
  eth0:
    dhcp4: true
    optional: true
wifis:
  wlan0:
    dhcp4: true
    optional: true
    access-points:
      "<5GHz-ssid>":
        password: "<5GHz-password>"
      "<2.4GHz-ssid>":
        password: "<2.4GHz-password>"
version: 2
```

### /etc/hostsの編集
[k3sのバグ](https://github.com/k3s-io/k3s/issues/60 "k3sbug")に対するワークアラウンドとしてクラスタに含めるホストを`/etc/hosts`に追記します。
※現在は修正が入ったみたいです。僕は動作確認していないので、素直に`/etc/hosts`に明記しました。

```
$ sudo vim /etc/hosts
...
192.168.0.10 k3s-master
192.168.0.11 k3s-worker01
```

### cgroupの有効化
cgroupを有効にします。`/boot/firmware/cmdline.txt`に以下を追記します。
**スペース区切りで追記することに注意してください。**

```
cgroup_memory=1 cgroup_enable=memory cgroup_enable=cpuset
```

最後にrebootします。

```
$ sudo reboot
```

# k3sクラスタ構築
8GBRAMのラズパイをmasterにし、4GBRAMの方をworkerにしました。
理由はmasterの方がリソースを喰いそうな気がしたからです。k3s自体が軽量なので特に問題なさそうですが。

## master(k3s-master)の構築
k3sでは、コマンド1発でインストールできるように公式からスクリプトが用意されています。便利なところです。
おそらくパーミッションの問題だと思いますが、rootユーザでないとコマンドが止まってしまうようでしたので、ここはrootにログインして実行しました。

```
# curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644
```

コマンドに`--write-kubeconfig-mode 644`というオプションを追加しています。
将来的にRancherを導入するときに役立つということと、rootでなくてもkubectlコマンドが使用できるようにする目的があります。

以下のコマンドでnodeの情報が出れば問題ないかと思います。

```
$ k3s kubectl get nodes
NAME        STATUS   ROLES    AGE     VERSION
k3s-master   Ready    master   7d      v1.19.4+k3s1
```

## worker(k3s-worker)の構築
masterに接続するために使用するIPアドレスとトークンをメモしておきます。
トークンはmasterの以下のファイルを参照します。

```
$ sudo cat /var/lib/rancher/k3s/server/node-token
```

workerにもk3sをインストールします。

```
# curl -sfL https://get.k3s.io | K3S_URL=https://192.168.0.10:6443 K3S_TOKEN=K10d4a4533c19e7b7d7a1ad5a9d71669f2dcd4c045b887dce1125bf6a48ea3a3cad::server:fca919407917f4379214c2c0c4a575f1 sh -
```

workerが起動したら、master側で以下のコマンドを実行します。

```
$ k3s kubectl get nodes
NAME        STATUS   ROLES    AGE     VERSION
k3s-master   Ready    master   7d      v1.19.4+k3s1
k3s-worker01   Ready    worker   5d11h   v1.19.4+k3s1
```

workerの方も起動していたら大丈夫です。


# 終わりに
この記事ではk3sクラスタを構築していきました。自分用の手順メモの意味合いが強いので雑なのはお許しをば。
せっかくk3sクラスタを手に入れたので、Rancher導入や自宅用ポータルサイトデプロイなどいろいろ検証してみたいと思います。
また、workerが増えるたびにこの手順を実施するのも面倒なので、Ansible playbook書いておきたいですね。

**さあ、君だけの最強のクラスタを手に入れよう！**

# 参考文献
https://qiita.com/Tsu_hao_Zhang/items/7d4f5d62bed584766881