[メモ]k8sをraspberry pi 4にインストール(2024/9月版)

# 始めに
　k8sをRaspberry Piに載せてみる試みは数年に一度やっているのですが、毎回やり方が違います。最初はRaspberry Pi2とか3でやるのにいろいろなものをビルドするという方法しかなかったのですが、Raspberry Pi4ではネイティブなインストーラが整備されて何となく簡単にできるようになってきたなと思ったら、Docker回りがややこしくなり、情報が錯綜して地雷を踏むことが多くなり現在に至っているような気がします。毎回何かしら方法が違いそうなので、とりあえずうまくいったバージョンを記しておきます。

# 参考ページ

[How to Install Kubernetes Cluster on Ubuntu 22.04](https://www.linuxtechi.com/install-kubernetes-on-ubuntu-22-04/)
基本的にはこれに沿ってやればいいが、amd64向けの記事なので一か所arm64に変更が必要なのと、k8sのインストール部分は本家でやったほうが良いらしい

[Install and Set Up kubectl on Linux](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/)
本家のインストール方法でkubectlについて書いてあるので、kubeadmとkubeletに拡大する

# 前提システム
- Raspberry Pi 4を3台
- SDカード 32GBくらいのやつ3枚　Ubuntu Server 22.04.5 LTSをインストール済み

# 手順

最初の方は[How to Install Kubernetes Cluster on Ubuntu 22.04](https://www.linuxtechi.com/install-kubernetes-on-ubuntu-22-04/)に沿ってインストールを進めます。（少々アレンジをしています。）

### 1. 初期セットアップ
まずはマシン名を決めます。今回はマスターノードをk8s-master、ワーカーノードをk8s-worker1、k8s-worker2とします。SDカード作成時に先にマシン名決めてしまった場合は必要ありません。

```
$ sudo hostnamectl set-hostname　k8s-master
```
```
$ sudo hostnamectl set-hostname　k8s-worker1
```
```
$ sudo hostnamectl set-hostname　k8s-worker2
```

すべてのマシンの/etc/hostsに以下を追加

```
[マスターのipアドレス]  k8s-master
[ワーカー1のipアドレス] k8s-worker1
[ワーカー2のipアドレス] k8s-worker2
```

DHCPの場合、毎回リセットされてしまうので、以下のページの方法を使うとよいかもしれません。
[cloud-initが動いていると/etc/hostsの変更が再起動で元に戻ってしまう](https://qiita.com/honma-h/items/f7ec6b0619af9ebfe9e6)

### 2.Swapの無効化とカーネルパラメータの変更

k8sはスワップを無効化しないと動きません。全マシン共通です。
```
$ sudo swapoff -a
$ sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
```

カーネルパラメータを変更します。以下のファイルを開きます。
```
$ sudo vi /etc/modules-load.d/containerd.conf
```
以下を書きこんでください。
```
overlay
br_netfilter
```
以下を実行。
```
$ sudo modprobe overlay
$ sudo modprobe br_netfilter
```
以下のファイルを開きます。
```
$sudo vi /etc/sysctl.d/kubernetes.conf 
```
以下を書き込んでください。
```
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
```
以下を実行。
```
$ sudo sysctl --system
```

### 3. Containerdのインストール
ここも全ノードで行います。
オリジナルの記事とは、アーキティクチャをarch=amd64からarch=arm64に変更しています。

```
$ sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
$ sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
$ sudo add-apt-repository "deb [arch=arm64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt update
$ sudo apt install -y containerd.io
```
Cgroupを変更します。
```
$ containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
$ sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
```
Containerdの再起動とイネーブルをします
```
$ sudo systemctl restart containerd
$ sudo systemctl enable containerd
```
### 4. k8sのインストール
ここも全てのノードで行います。こちらは本家のページの方法を使います。
前提ライブライのインストールとk8sのパッケージインデックスをインストールします。
```
$ sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
$ curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
$ sudo chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg 
$ echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] 
```
aptレポジトリの追加。バージョンv1.31のが書かれているので、その時に使いたいバージョンに変更する。
```
$ https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
$ sudo chmod 644 /etc/apt/sources.list.d/kubernetes.list
```
アップデートとインストール。
```
$ sudo apt-get update
$ sudo apt install -y kubelet kubeadm kubectl
$ sudo apt-mark hold kubelet kubeadm kubectl
```

### 5.クラスタの設定
ここはマスターノードのみでおこないます。クラスターの初期化をします。

```
$ sudo kubeadm init --control-plane-endpoint=k8s-master
```
少し時間がかかり、メッセージがバラバラ出てきます。エラーになることが多いので、対処してください。特にDHCPの場合、/etc/hostsが消えていることがあります。
メッセージがOKなら、メッセージ内にあるkubeadm joinn ..のコマンドをメモしておきます。
次の実行をします。
```
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
```
これでkubectlがsudo無しで使えるようになります。以下で確認。
```
$ kubectl cluster-info
$ kubectl get nodes
```
2行目のコマンドで自分のノードがReadyになるまで待ちます。

fannelを起動し、pod間の通信が機能するようにします。
```
$ kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
```

### 6.ワーカーノードの追加
ここは、上記kubeadm initのメッセージ内で出てきてメモをしたものを、下記のようなコマンドをワーカーノードで実行します。sudoを付けないとエラーになります。

```
$ sudo kubeadm join k8smaster.example.net:6443 --token vt4ua6.wcma2y8pl4menxh2 \
   --discovery-token-ca-cert-hash sha256:0494aa7fc6ced8f8e7b20137ec0c5d2699dc5f8e616656932ff9173c94962a36
```
joinコマンドをメモしていなかった場合は以下のコマンドで再度表示が可能です。
```
$ kubeadm token create --print-join-command
```

あと、ワーカーノードでもfannelを起動してください。
```
$ kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
```
エラーがなければマスターから見えるはずです。

これ以降の使用方法などは、k8sの使い方のページがたくさんあるので、そちらを参考にしてください。

# 最後に
　k8sをPCで組もうとするとLinux PCが3台は必要になるので、ハードル高いです。その点Raspberry Pi4だと少し部屋が散らかる程度(配線がぐちゃぐちゃになります・・・)で済むので、k8s試してみたい方にはおすすめです。
　たぶん現在成功していてもまた陳腐化すると思うので、気づいたら更新します。