kubernetes(K8S) Worker nodeをRaspberry piで作る方法の話
今回は、kubernetes(略 K8S)においてWorker nodeをRaspberry piに作成する方法をメモしておきます…
我が家では8台のRaspberry piにて構築していますが、毎度メモ帳に書いている内容をぽちぽち書いています。
が、そのメモ帳を無くすと悲しいのでここにもメモを残します。
ついでに書きながら内容を再確認させています
ネット上ではさまざまな構成方法がありますが、なぜか我が環境では動かなかったので試行錯誤しました。
その結果のメモです…
今回のターゲットはworker node 3台目、マシン名 k8s-worker3です。
利用した環境
Raspberry pi : Raspberry Pi 4 Model Bだったはず (メモリ : 4GB)
OS : Raspberry pi OS 64bit . (Bulleyes)
早速作業します。
SDカードを作る
はじめに、Raspberry piのOSを書いたSDカードを作成します。
SDカードを作るには様々な方法がありますが今回はmacOSのRaspberry pi Imagerを使って作成します
ImagerのOSを押下して、OSを選択します。
今回は「Raspberry pi OS LITE (64-bit)」を利用します。
昔は書き込み後にごにょごにょ設定を変えていましたが、
Raspberry pi Imger v1.7から書き込み時に設定を入れることが可能になりました。
歯車にて設定ができますのでそこで設定します。
設定できる内容は以下の内容をです。
- ホスト名
- SSHを有効にする
- ユーザ名とパスワードを設定する
- Wifiを設定する
- ロケールを設定する
SSHの有効設定は以降の作業で必ず必要ですので有効にして作成してください。
ユーザ名は必ず設定しましょう。
デフォルトユーザのpiは非推奨です。
やめましょうねw
指定しないとユーザ作成の要求がきたかもしれません。(未確認)
デフォルトの “pi” ユーザーを削除し、代わりに新しくフラッシュした Raspberry Pi OS イメージを最初に起動したときにユーザーを作成するようにしました。
https://www.raspberrypi.com/news/raspberry-pi-bullseye-update-april-2022/
本体に接続して電源を入れる
ImagerにてSDカードを作成が完了すると
そのSDカードを挿してRaspberry piを起動させます!
起動を行うとSSHで作業をおこないます。
IPアドレスをまず取得しましょう。
IPアドレスの取得は、本体にKVMを付けて確認でも、DHCPサーバの払い出し一覧からとりだしてもOKです。好きな方法で取得しましょうw
IPアドレスが取得できましたら、SSHにて入ります。
ちゃんとOSが入っていることを確認します
wataru@k8s-worker3:~ $ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
おまじない的に最新にします
wataru@k8s-worker3:~ $ sudo apt-get update
wataru@k8s-worker3:~ $ sudo apt-get upgrade
ネットワークの設定を行う
ネットワークの設定って標準のnetplanを使えば?と思いでしょうがSystemd-networkを使います。
なぜかというと、Raspberry piにてNodeが上がらない不具合があったためです。
この不具合解消がnetplanではなくSystemdで指定すれば解決できます…
他の方法知りたいです
作業は 古いネットワーク設定(netplan)周りをざっくり削除して、Systemd-networkd周りをインストールすればOKです。
参考にしたサイトはこちらです。 https://raspberrypi.stackexchange.com/questions/108592/use-systemd-networkd-for-general-networking
古いネットワーク設定周りを削除する
wataru@k8s-worker3:~ $ sudo -i
root@k8s-worker3:~ # systemctl daemon-reload
root@k8s-worker3:~ # systemctl disable --now ifupdown dhcpcd dhcpcd5 isc-dhcp-client isc-dhcp-common rsyslog
root@k8s-worker3:~ # apt --autoremove purge ifupdown dhcpcd dhcpcd5 isc-dhcp-client isc-dhcp-common rsyslog
root@k8s-worker3:~ # rm -r /etc/network /etc/dhcp
systemd-networkdを設定・有効にします
wataru@k8s-worker3:~ $ sudo -i
root@k8s-worker3:~ # systemctl disable --now avahi-daemon libnss-mdns
root@k8s-worker3:~ # apt --autoremove purge avahi-daemon
root@k8s-worker3:~ # apt install libnss-resolve
root@k8s-worker3:~ # ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
root@k8s-worker3:~ # apt-mark hold avahi-daemon dhcpcd dhcpcd5 ifupdown isc-dhcp-client isc-dhcp-common libnss-mdns openresolv raspberrypi-net-mods rsyslog
root@k8s-worker3:~ # systemctl enable systemd-networkd.service systemd-resolved.service
有線LANの設定を書きます
パッケージを入れれば次に有線LANの設定を書きます
wataru@k8s-worker3:~ # touch /etc/systemd/network/04-wired.network
wataru@k8s-worker3:~ # vi /etc/systemd/network/04-wired.network
[Match]
Name=eth0
[Network]
Address=192.168.1.224/24
Gateway=192.168.1.254
DNS=192.168.1.254
wataru@k8s-worker3:~ # systemctl enable systemd-resolved.service
有線LANの設定を変更しましたので反映…
略、SSHなのでIPが変わるとアクセスできなくなるので、とりあえず再起動で対応します。
これで新しいIPアドレスにてSSHで入ればOKです
とりあえず不具合原因のファイルがあることを確認します
wataru@k8s-worker3:~ $ ls /run/systemd/resolve/resolv.conf
/run/systemd/resolve/resolv.conf
これでRaspberry piのネットワーク周りを設定しました。
K8sインストール前の事前設定
はじめに、K8sをインストールする前にRaspberry piの設定を変更します。
Swapをoffにしてcgroupのメモリをアレします。
Swapをoffにする
Raspberry piのK8sではSwapをonにすると動きません。
なのでSwapをOffにします。
wataru@k8s-worker3:~ $ sudo dphys-swapfile swapoff
wataru@k8s-worker3:~ $ sudo systemctl stop dphys-swapfile
wataru@k8s-worker3:~ $ sudo systemctl disable dphys-swapfile
cgroupsのメモリをアレする
wataru@k8s-worker3:~ $ sudo vi /boot/cmdline.txt
cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory
上をcmdlineの末尾に追記します。
再起動します。
ちゃんと反映されていることを確認
※ 確認ポイント : 末尾が1
wataru@k8s-worker3:~ $ cat /proc/cgroups | grep memory
memory 0 66 1
Dockerのインストール
解説略! Dockerをインストールします。
公式のスクリプトで入ります…
wataru@k8s-worker3:~ $ curl -sSL https://get.docker.com | sh
...
Server: Docker Engine - Community
Engine:
Version: 20.10.14
API version: 1.41 (minimum version 1.12)
Go version: go1.16.15
Git commit: 87a90dc
Built: Thu Mar 24 01:45:44 2022
OS/Arch: linux/arm64
Experimental: false
containerd:
Version: 1.5.11
GitCommit: 3df54a852345ae127d1fa3092b95168e4a88e2f8
runc:
Version: 1.0.3
GitCommit: v1.0.3-0-gf46b6ba
docker-init:
Version: 0.19.0
GitCommit: de40ad0
wataru@k8s-worker3:~ $ sudo usermod -aG docker wataru
kubernetesのインストール
解説略! リポジトリ追加して入れれば入ります
wataru@k8s-worker3:~ $ sudo apt-get update && sudo apt-get install -y apt-transport-https curl
wataru@k8s-worker3:~ $ sudo curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
K8sのリポジトリを追加する
wataru@k8s-worker3:~ $ sudo vi /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
リポジトリを更新する
wataru@k8s-worker3:~ $ sudo apt-get update
一式をインストールする
wataru@k8s-worker3:~ $ sudo apt-get install -y kubelet kubeadm kubectl
wataru@k8s-worker3:~ $ sudo apt-mark hold kubelet kubeadm kubectl
kubernetes(k8s)に参加する
一式インストールが終えたので今回のメインディッシュ K8sに参加します。
worker nodeの追加前にmaster nodeの状態を確認します
wataru@k8s-master:~ $ kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 126m v1.23.6
k8s-worker1 Ready <none> 123m v1.23.6
k8s-worker2 Ready <none> 88m v1.23.6
すでに作業済みのworker1 , worker2だけが追加されています…
参加!join!
本題である参加を発行します!
wataru@k8s-worker3:~ $ sudo kubeadm join 192.168.1.221:6443 --token ypnxoi.z03zcpkv51wj8udf --discovery-token-ca-cert-hash sha256:20fbb36fde703aaba4d823e0a506c3866fe66f2c818c5685c52034bdc2c908ea
...
This node has joined the cluster:
tokenを忘れた、昔すぎて覚えていない場合は再生成が必要になります。
こちらを参考ください : Kubernetes(k8s)での新しいnodeの追加方法の話 2022年3月24日
master nodeにて参加を確認する
worker nodeにてjoinをコマンド実行しましたのでmaster nodeにて確認します
wataru@k8s-master:~ $ kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 128m v1.23.6
k8s-worker1 Ready <none> 125m v1.23.6
k8s-worker2 Ready <none> 90m v1.23.6
k8s-worker3 Ready <none> 41s v1.23.6
今回作業したk8s-worker3が追加されることを確認しました。
早ければNoReadyなのでしばらくたってから再取得ください
参加できました。パチパチ…
動作を確認する
worker nodeがちゃんと動いていることを確認します。
手順はこちら : https://kubernetes.io/ja/docs/tasks/run-application/run-stateless-application-deployment/
手順がどうのは無視してnginxを4個動かせば3台のWorkerなので1台はworker3にて動くでしょう!
手順を全否定に近いねw
早速動かす
kubectl apply -f https://k8s.io/examples/application/deployment-scale.yaml
次に動いているpodを確認する!
wataru@k8s-master:~ $ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-9456bbbf9-2kl9s 1/1 Running 0 69s 10.244.3.5 k8s-worker3 <none> <none>
nginx-deployment-9456bbbf9-54jjc 1/1 Running 0 69s 10.244.1.5 k8s-worker1 <none> <none>
nginx-deployment-9456bbbf9-bzqnr 1/1 Running 0 69s 10.244.2.6 k8s-worker2 <none> <none>
nginx-deployment-9456bbbf9-mrwfg 1/1 Running 0 69s 10.244.2.7 k8s-worker2 <none> <none>
はい!k8s-worker3がRunningです。
個別にnginxの動作を確認しますと
wataru@k8s-master:~ $ curl 10.244.3.5
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
こいつ、動いているぞ!
動作を確認できましたので、お片付けはちゃんとしましょう
kubectl delete -f https://k8s.io/examples/application/deployment-scale.yaml
終いに
今回、Raspberry piのk8s worker nodeを追加する方法をメモしました。
下の不具合が原因でかなり試行錯誤しました。
次はRaspberry piのk8s master nodeを作成する方法かな…
Raspberry piのmaster nodeがReadyにならない不具合
worker nodeを参加させることができますが、NoReadyのまま上がらない不具合がありました。
wataru@k8s-master:~$ kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 77d v1.23.6
k8s-worker0 NotReady <none> 36d v1.23.6
Nodeの状態を確認すると…
wataru@k8s-master:~$ kubectl describe node k8s-worker0
... 略 ...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning listen tcp4 :31242: bind: address already in use 0s (x1 over 30s) kube-proxy can't open port "nodePort for default/hello-minikube" (:31242/tcp4), skipping it
Normal Starting 31s kube-proxy
Normal NodeHasSufficientMemory 15m (x2 over 15m) kubelet Node k8s-worker0 status is now: NodeHasSufficientMemory
Normal NodeHasNoDiskPressure 15m (x2 over 15m) kubelet Node k8s-worker0 status is now: NodeHasNoDiskPressure
Normal NodeHasSufficientPID 15m (x2 over 15m) kubelet Node k8s-worker0 status is now: NodeHasSufficientPID
Normal Starting 15m kubelet Starting kubelet.
Normal NodeHasSufficientMemory 15m kubelet Node k8s-worker0 status is now: NodeHasSufficientMemory
Normal NodeHasNoDiskPressure 15m kubelet Node k8s-worker0 status is now: NodeHasNoDiskPressure
Normal NodeHasSufficientPID 15m kubelet Node k8s-worker0 status is now: NodeHasSufficientPID
Normal NodeAllocatableEnforced 15m kubelet Updated Node Allocatable limit across pods
Normal Starting 15m kubelet Starting kubelet.
Warning CheckLimitsForResolvConf 15m kubelet open /run/systemd/resolve/resolv.conf: no such file or directory
らしいです…
確認すると…
pi@k8s-worker0:~ $ ls /run/systemd/resolve/resolv.conf
ls: cannot access '/run/systemd/resolve/resolv.conf': No such file or directory
ないです…
そもそも、resolveディレクトリからありません…
とりあえず、強制的にファイルを作りました
pi@k8s-worker0:~ $ sudo mkdir /run/systemd/resolve
pi@k8s-worker0:~ $ sudo ln -s /etc/resolv.conf /run/systemd/resolve/resolv.conf
pi@k8s-worker0:~ $ sudo systemctl restart kubelet
すると… ちゃんとReadyになりました!
wataru@k8s-master:~$ kubectl get node
NAME STATUS ROLES AGE VERSION
gitlab Ready control-plane,master 77d v1.23.6
k8s-node0 Ready <none> 36d v1.23.6
解決!にはなりません…
再起動するとresolve/resolv.confは無くなります…
それはダメなのでちゃんとsystemdから作るとこの問題は解消できます。