てっくらのーとは、触れた技術のメモと日常の記録が少し合わさった個人のサイトです。
ラズパイでk8s clusterを構築した
経緯
お正月休みにラズパイを触りたいなーと思っていて意気揚々とこの製品キットをポチっていたんですけど、その後おうちk8sの記事が2つ3つ目に飛び込んできたためか自分も作りたくなってしまったので、ラズパイとその他必要なものを追加でポチるという非常に計画性皆無な姿を晒していたのがお正月休み直前の私の姿となります。
ちなみに私のラズパイ経験は昔なんとなく触った経験しかないゼロに等しいものです。
準備
というわけでポチったものです。一部自宅に転がっていたものがあります。
名称 | 製品 | 個数 | 備考 |
---|---|---|---|
Raspberry Pi4 | TRASKIT Raspberry Pi 4 Model B | 1 | 製品キット、箱型ケースは未使用 |
Raspberry Pi4 | Raspberry Pi4 ModelB 8GB | 2 | - |
積層式ケース | 積層式ケース for Raspberry Pi 4 / Pi 3 Model B+ | 1 | - |
MicroSDカード | KEXIN MicroSDカード 32GB(2個セット) | 1 | 計2個 |
ルーター | BUFFALO 無線LAN親機 WMR-433W2-BK | 1 | - |
USB充電器 | AUKEY USB充電器 50W/10A ACアダプター 5ポート | 1 | - |
USB TypeC ケーブル | SUNGUY USB C ケーブル【0.3m*2】 | 2 | 計4本、ラズパイその他給電用 |
LANケーブル | エレコム LANケーブル 0.15m×2本 | 2 | 計4本 |
スイッチングハブ | BUFFALO スイッチングハブ LSW4-GT-5NS/BK | 1 | 自宅に転がっていたもの、ホコリがすごかった |
前述の通り、当初は製品キットのみ購入予定でしたが追加でラズパイ*2を購入しました。本体を追加購入したのは良かったものの冷却関連の購入をすっかり忘れていて、追加購入分のヒートシンクが無いことに気づいたのは組み上げる途中でした。ああまた追加購入だよ年末に頼んでいつ来るのかな…、と憂いていたら積層式ケース一式の中に予備のヒートシンクがあってホッとしたという一幕がございました。よく知らないまま中身も確認しないとこうなります。
製品キットですがUSB-C SDカードリーダーなども付属されていて意外に重宝しています。また日本語に訳された付属マニュアルの翻訳具合が中々いい味を出していて好きです。この辺は販売しているところなどでガラっと変わるのかな。(今製品ページを改めて読んだら製品説明文からいい味出してた)
スイッチングハブは家に転がっていたものを再利用しました。購入する場合はスイッチングハブもUSB給電仕様のものにした方が楽になると思います。
組み立て
積層式ケースの説明書の言う通りに組み立てて行きます。組み立て自体はそこまで難しいものではありませんでした。各層にラズパイボードを固定して組み立てた後だとヒートシンクを貼りつけるのに難儀するので最初に貼り付けてしまった方がよいです。そういえば説明書のヒートシンクの場所が3B+ぽいものでした。4だと場所が異なるので適当にWebを探しつつ貼り付けましょう。
組み終わると「ルータ+USB充電器+ラズパイ3段重ね+ハブ」みたいなミニタワーが完成します。この時点で結構な充実感があります。ただこれ、全体として一つに固定されていないのでケーブルの抜き差しをするときなどに予想外にモノも一緒に動くので「ああっ」とか言います。不器用さを全開に出しつつ言いました。結束バンドのようなもので固定すると中々よい塩梅になるかもしれません(まだ試してない)。
起動
OSはこちらのRaspberry Pi OS Liteを使用しました。デスクトップ環境は要らないかなと思ったので入れていません。…とか言っていますが実態は少し違っており、正確には「デスクトップ環境で起動させたかったけど上手くいかなかったのでLiteに切り替えた」となります。悲しい。
製品キットのSDカードにはNOOBSがプリインストールされていて、NOOBS起動->RaspberryPiデスクトップ環境Install->起動 という流れで進むはずなのですがインストール後どうもうまくデスクトップ環境が起動できない。解決を目指し色々策を弄したのですが結局ダメでまさにNoob。そのことに一人自嘲的に笑うも状況は全く改善されるはずもなく上記の方向に舵を取りました。
起動後にSSHを有効にするには、書き込んだイメージを一回マウントして「SSHという名のファイル」を作成することで解決します。Web上にあるMacでの操作例を見つつ、Windowsではどうやるんだろ…とか思っていたのですが、前述のカードリーダーで認識させたところ自動でマウントされまして、ファイル作成することで難なく解決しました。よかった。
ネットワーク
購入したルータ(WMR-433W2-BK)は他の方のおうちk8s構築記事でもよく使用されているものです。こちらはワイヤレスワンモードというモードにして使用します。無線LAN環境から1つIPアドレスをもらい、ローカルIPアドレスとNATみたくして通信を確立している感じでした。ローカルIPアドレス帯は192.168.13.0/24
がデフォルトで決まっており、特に設定変更はできないようです。
Internet ------- Router ---- 無線LAN(AP) ---- WMR-433W2-BK ---- ハブ ----- ラズパイ*3
-- パブリックIP --> | <------ 無線LAN環境IP ----> | <--- ローカルIP -----> |
-- パブリックIP --> | <------- 192.168.1.XX ------> | <--- 192.168.13.YY ---> |
上の図となっている場合、WMR-433W2-BK のIPアドレスはそれぞれ、
- 無線LAN環境IP: 192.168.1.4
- ローカルIP: 192.168.13.1
となります。 まとめるとこのような感じとなりました。
ホストネーム | 役割 | IPアドレス | 備考 |
---|---|---|---|
- | k8s用無線ルータ | 192.168.13.1 | 無線LAN環境側IPアドレスは192.168.1.4 |
k8s-master | Controll-node | 192.168.13.2 | - |
k8s-node-1 | Worker-node | 192.168.13.5 | - |
k8s-node-2 | Worker-node | 192.168.13.6 | - |
なお、ラズパイ自身も無線LANを使用できる(と思う)のでそのような方針で構成もできるのかと思いますが特に試していません。
構築
ラズパイ3台についてSSHでログインして各種設定を行います。詳細はWebにもあるので参照されたい方はそちらを。
- 作業用ユーザの作成
- SSHパスワード認証から公開鍵認証へ
- 初期ユーザ/パスワードは
pi/raspberry
。ログインするとパスワード変更しろとお達しが表示される。
- 初期ユーザ/パスワードは
- ホストネーム設定
- タイムゾーン設定
- ロケール設定
- /etc/hosts設定
- controller-node*1, worker-node*2
- iptablesは
iptables-legacy
を使用するようにするsudo update-alternatives --set iptables /usr/sbin/iptables-legacy
- swapoff
swapoff -a
- パッケージ更新
sudo apt update
sudo apt upgrade
Dockerインストール
$ curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | sudo apt-key add -
$ echo "deb [arch=armhf] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
$ sudo apt update
$ sudo apt install docker-ce
Kubernetesインストール
$ curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg|sudo pt-key add -
$ echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee etc/apt/sources.list.d/kube.list
$ sudo apt update
$ sudo apt install kubelet kubeadm kubectl
Kubernetes クラスタ作成
Kubernetes init
ラズパイ3台について設定完了後、Controller-node でコマンドからクラスタを作成します。コマンドが成功すると出力される kubeadm join XXX.XXX.XXX.XXX:6443 --token=XXXX --discovery-token-ca-cert-hash sha256:XXX
はWorkerノードを追加するときに必要となるのでメモしておきます。
$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=all
(中略)
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
(中略)
最初、sudo kubeadm init --pod-network-cidr=10.244.0.0/16
で実行したところ、以下応答が返却されました。
[ERROR Mem]: the system RAM (1 MB) is less than the minimum 1700 MB
こちらはこのissueにて報告されている問題で、v1.21で改善される予定だそう。今回はissue内にもコメントあるように--ignore-preflight-errors
を付与して回避しています。出力された以下も併せて実行します。
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
ネットワークプラグイン
ネットワークプラグインのflannelを適用します。
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds create
-f
の引数が与えているyamlはドキュメントで指定されている通りのものを使用しています。
Worker追加
先ほどメモしたkubeadm join
コマンドをWorker-nodeで実行します。
$ kubeadm join XXX.XXX.XXX.XXX:6443 --token=XXXX --discovery-token-ca-cert-hash sha256:XXX
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the master to see this node join the cluster.
なお、--token=XXX
は24h経過すると無効になります。そのような場合はController-nodeで再払い出しをしましょう。
$ sudo kubeadm token create
34osle.1we29eimvlo3ieu
$ sudo kubeadm token list
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
34osle.1we29eimvlo3ieu 23h 2021-01-04T22:30:43+09:00 authentication,signing <none>
--discovery-token-ca-cert-hash
の値は以下コマンドで分かります。
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
Worker が追加されると、kubectl get nodes
に表示されます。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 4d19h v1.20.1
k8s-node-1 Ready <none> 4d19h v1.20.1
k8s-node-2 Ready <none> 4d18h v1.20.1
気になるところ
ということで無事 k8s cluster を構築できた。色々触ってみて理解を深めていきたい。現段階で少し気になったところ。
- 時々コマンドが蹴られる
偶にこうなる。
$ kubectl get nodes
The connection to the server 192.168.13.2:6443 was refused - did you specify the right host or port?
Controll-node のCPU使用率が比較的高いときに蹴られているように見えるのだけど、明確には何が原因か分かっていない。
参考
参考にさせていただいた記事です。ありがとうございました。