k3sをラズパイで構築してみた
k8sのラズパイクラスタを遊ばせていたので、k3sのクラスタを組んでみました。
構築手順
使ったもの
- raspberry pi model B+ ×3
- macbook pro 13inch 2015 ealry
- 5ポートモバイルバッテリー
- Wi-Fiルータ
- LANケーブル
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 PI ⇄ Wi-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 piにsshした後、以下のコマンドを実行します。およそ数分かかります。
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との違いなんかも少しずつ見ていこうと思います。