k3sをラズパイで構築してみた

k8sのラズパイクラスタを遊ばせていたので、k3sのクラスタを組んでみました。

構築手順

使ったもの

Raspberry Pi環境の構築

raspbian streachのダウンロード

busterも出ていたのですが、自分のローカルにstreachがあったのでこちらを利用することに。

公式だと最新版しかなく、またダウンロードに時間がかかるため、以下の日本のミラーサイトを利用した方が良いです。 http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian/images/raspbian-2019-04-09/

raspbianの書き込み

SDカードへの書き込みはEtcherを使いました。

imageは先ほど用意したraspbianのzipファイルを指定し、書き込み先に差し込んだSDカードを指定すればOKです。 5分ほどで書き込み完了します。

書き込んだ後はSSHをするために以下のファイルをtouchしておきます。

$ touch /Volumes/boot/ssh

raspberry piへのssh接続

自宅にモニターもマウスもキーボードもないので、wifi経由で繋げるようにします。 よくあるラズパイクラスタを作成する際はハブで接続すればOKだと思います。

①LANケーブルをRaspberry PIWi-Fiルータに接続する

Wi-Fiルータのサイトにアクセスして、IPを取得する
自分の場合は192.168.1.1など。ルータによって変わると思います。

自分の場合、raspberry piは192.168.1.170でした。

sshで接続

$ ssh pi@192.168.1.170
## 初期パスワードはraspberry

④cmdline.txtの書き換え
cgroupsの設定を反映しないと、k3sを起動させるときに失敗します。

$ sudo vi /boot/cmdline.txt

変更前

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=10437ae6-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles

変更後

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=10437ae6-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory

Wi-Fi設定

$ sudo raspi-config 

raspberry piの設定画面が表示されるため、以下を設定します。

  • 「2 Network Options」 → 「N2 Wi-Fi」→ 「国設定:Japan」 → 「SSID:ルータのSSIDを入力」 → 「パスワード:ルータのパスワードを設定」
  • 「2 Network Options」 → 「N1 HostName」 → 「ホスト名を適当に変更する(master/workerわかりやすいように)」

両方終わったら「Finish」を押す。rebootするかと言われるので、rebootを行います。

で、この間に有線LANを抜いておきます。 先にLANを抜くともちろん操作ができなくなるので、その際はraspberry piの電源を抜き差ししましょう。

Wi-Fi経由での接続
Wi-Fiルータのサイトにアクセスして、IPを取得します。 IPが170→114に変わってました。

sshで接続

$ ssh pi@192.168.1.114
## 初期パスワードはraspberry

⑧3台のraspberry piで上記設定をやっておく。
ホスト名は以下にしました。

  • raspberry-master
  • raspberry-worker-1
  • raspberry-worker-2

k3sのインストール(3台のraspberry piで実施)

raspberry pisshした後、以下のコマンドを実行します。およそ数分かかります。

curl -sfL https://get.k3s.io | sh -

完了後、以下のコマンドでk3sのインストールを確認します。

$ k3s kubectl get nodes
NAME               STATUS   ROLES    AGE   VERSION
raspberry-master   Ready    master   90s   v1.14.6-k3s.1

workerの接続

worker-1/worker-2はworkerノードとして参加させたいので、以下を実施します。

masterで実施

$ cat /var/lib/rancher/k3s/server/node-token
[tokenが表示されるので、コピーしておく]

workerで実施

$ sudo service k3s stop
$  sudo k3s agent --server https://[masterのIP]:6443 --token [masterで表示されたtoken]

クラスタの確認

$ sudo k3s kubectl get nodes
NAME                   STATUS   ROLES    AGE   VERSION
raspberry-master       Ready    master   55m   v1.14.6-k3s.1
raspberrypi-worker-1   Ready    worker   33m   v1.14.6-k3s.1
raspberrypi-worker-2   Ready    worker   21m   v1.14.6-k3s.1

完成!

実験

raspberry piの良いところは物理的な故障を手軽に試せるところかなと思っています。

今回はstorage故障(SDカードを引っこ抜く)を試してみます。

masterでdeployment/svc作成

$ kubectl run nginx --image=nginx
$ kubectl expose deploy nginx --port=80 --type=NodePort

疎通確認

$ kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.43.0.1      <none>        443/TCP        59m
nginx        NodePort    10.43.182.60   <none>        80:32157/TCP   25s

ブラウザでhttp://[masterのIP]:32157でnginxへのアクセスができることを確認。

storage故障を起こす

$ get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP          NODE                   NOMINATED NODE   READINESS GATES
nginx-7db9fccd9b-68vbc   1/1     Running   0          26m   10.42.2.3   raspberrypi-worker-1   <none>           <none>

worker-1に紐づいているので、worker-1のSDカードを抜いてみます。

$ k3s kubectl get nodes
NAME                   STATUS     ROLES    AGE   VERSION
raspberry-master       Ready      master   63m   v1.14.6-k3s.1
raspberrypi-worker-1   NotReady   worker   40m   v1.14.6-k3s.1
raspberrypi-worker-2   Ready      worker   28m   v1.14.6-k3s.1

worker-1がNotReadyになりました。

その間はwatch kubectl get podsで様子をみます。

NAME                     READY   STATUS              RESTARTS   AGE   IP          NODE                   NOMINATED
NODE   READINESS GATES
nginx-7db9fccd9b-28lxc   0/1     ContainerCreating   0          27s   <none>      raspberrypi-worker-2   <none>
       <none>
nginx-7db9fccd9b-68vbc   1/1     Terminating         0          32m   10.42.2.3   raspberrypi-worker-1   <none>
       <none>
NAME                     READY   STATUS        RESTARTS   AGE   IP          NODE                   NOMINATED NODE   READINESS GATES
nginx-7db9fccd9b-28lxc   1/1     Running       0          74s   10.42.3.2   raspberrypi-worker-2   <none>           <none>

worker-1のPodが削除されて、worker-2にPodが再作成されました。

しかしworker-1のPodがTerminateされるまで5分かかりました。そのため、

  • Kubeletが死んでいることを確認するまで少し時間がかかる
  • Kubeletが死んでいることを確認してから、Podが移動する
  • replica: 1の場合疎通ができなくなるため、replica: 2以上とし、Podは別々のノードに反映されるように設定をすべき

という挙動が確認できました。

最後に

k8sの時とは違って、IoTを前提に作られているのでインストールは簡単でした。

k3sはetcdの代わりにsqliteが使われており、現在multi masterができなそう?な感じだったりします。 k8sとの違いなんかも少しずつ見ていこうと思います。

参考

qiita.com

kenfdev.hateblo.jp