おうちk8sをしてみた話 (案の定k8sが上手くいかない #1)

スポンサーリンク
個人開発
スポンサーリンク

現在、webサービスを個人開発していますが、さくらのVPSを利用いたしまして、webサービスを運用しています。

現在メモリは2Gを使用しています。

しかしながら、当然2Gだとこれから限界が来るのは明白です。

8Gは欲しいなと思っています。

8G以上のさくらVPSの料金表は以下です。

https://vps.sakura.ad.jp/specification/ より引用

で、8Gとかに増やしていこうとすると月6400円以上払っていかないといけなくなるわけです。

そんな矢先、Qiitaでおうちk8sを勧める素晴らしい記事を見つけました。

エンジニアは全員おうちKubernetesをやるべし【Part 1:なぜやるのか】

ここでは(かなりざっくり書くと)お金が節約できることと、kubernetesをCDツールの採用することが書かれています。

たしかに、上記で記載したさくらVPSと比較すると、お金的にもかなり安く済むことになるのではないでしょうか。

ということで、将来的におうちk8s内で自前のサービスを動かせるように、おうちk8sを構築することにしました。

ちなみに、僕はk8sはほとんど触れたことはありません。

奮闘の様子をここに残します。

遭遇したエラーについても記録してますので、参考にしていただければと思います。

材料

構築の際に使用した材料を載せます。

✅Raspberry Pi 4 Model B (8GB)

(僕は元々あったラズパイ4GB1台を使ったので購入は2つでした。)

✅LANケーブル 0.15m ×4つ

✅マイクロsdカード 32GB ×3つ(以下のリンクのものは5枚入り)

✅両面テープ

✅USB Cケーブル30 cm ×3つ(以下のリンクのものは3つ入り)

✅スイッチングハブ

✅USB 無線LAN親機

✅USB 充電器

✅クラスターケース

(元からあった)

とりあえず写真を撮った。

構築していく

とりあえず、完成図を始めに載せておきます。

材料が揃ったら、構築をしていきます。

ラズパイの物理の構築や、初期設定は参考になるサイトがありますので、そちらを読んでいただければできますので、割愛します。

✅ラズベリーパイの物理の構築は以下が参考になります。

✅ラズベリーパイへのOSインストールは以下が参考になります。

で、ここからラズベリーパイにk8sを入れて構築していきますが、

案の定、エラー等で悶絶したので、その記録も載せておきます。というか、その記録をメインめで書いていきます。

参考になれば幸いです。

今回のk8s設定の参考にしたサイトは以下です。

このサイトで詳しく書かれているため、手順の詳しい説明は省きます。

masterマシン、workerマシン共通の設定

スワップの無効化

$ sudo dphys-swapfile swapoff
$ sudo systemctl stop dphys-swapfile
$ sudo systemctl disable dphys-swapfile

ホスト名の変更

★マスターのマシンの場合
$ sudo hostnamectl set-hostname k8s-master

★ワーカーその1のマシンの場合
$ sudo hostnamectl set-hostname k8s-worker1

★ワーカーその2のマシンの場合
$ sudo hostnamectl set-hostname k8s-worker2

IPの固定

$ sudo vi /etc/dhcpcd.conf
127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters

127.0.1.1       k8s-master
<固定するIP>     k8s-master
<固定するIP>     k8s-worker1
<固定するIP>     k8s-worker2

※上記はマスターマシンの例

kubernetesインストールに必要なツールをインストール

$ sudo apt install apt-transport-https curl ebtables arptables

iptablesの設定変更

$ sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
$ sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
$ sudo update-alternatives --set arptables /usr/sbin/arptables-legacy
$ sudo update-alternatives --set ebtables /usr/sbin/ebtables-legacy
$ sudo -i
# cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

# modprobe overlay
# modprobe br_netfilter
# cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# sysctl --system

CRI-Oのインストール

リポジトリの登録

# echo "deb https://ftp.gwdg.de/pub/opensuse/repositories/devel:/kubic:/libcontainers:/stable/Debian_11/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
# echo "deb https://ftp.gwdg.de/pub/opensuse/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/1.25:/1.25.1/Debian_11/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:1.25.1.list

# curl -L https://ftp.gwdg.de/pub/opensuse/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/1.25:/1.25.1/Debian_11/Release.key | apt-key add -
# curl -L https://ftp.gwdg.de/pub/opensuse/repositories/devel:/kubic:/libcontainers:/stable/Debian_11/Release.key | apt-key add -

# apt update

CRI-Oのインストール

# apt install cri-o cri-o-runc
# systemctl daemon-reload
# systemctl start crio
# systemctl enable crio

Kubernetesのインストール

リポジトリの登録

$ echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
$ curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

$ sudo apt update

上記を

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
$ cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF

$ sudo apt update

という風にすると、apt updateの際に以下のようなエラーが発生する可能性があります。

E: リポジトリ http://apt.kubernetes.io kubernetes-xenial Release には Release ファイルがありません。

💡参考:https://qiita.com/takahiro_bellcurve/items/f76e786208b262ea85f7

にして解決

$ sudo apt-get install -y kubelet kubeadm kubectl

バージョンの更新が無いように固定します。

$ sudo apt-mark hold kubelet kubeadm kubectl cri-o cri-o-runc

Masterマシンの設定

クラスタを作成。

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16

kubeadm initの際に出る可能性のあるエラー候補たち

【😈エラー】 [ERROR ImagePull]: failed

もしこの時にkubeadmの際に以下のようなエラーの場合、Dockerが入っていて、CRI-Oが入っていない場合が考えられる。

[ERROR ImagePull]: failed to pull image registry.k8s.io/kube-apiserver:v1.30.0: output: E0503 18:31:42.735285   84864 remote_image.go:180] "PullImage from image service failed" err="rpc error: code = NotFound desc = failed to pull and unpack image \"registry.k8s.io/kube-apiserver:v1.30.0\": no match for platform in manifest: not found" image="registry.k8s.io/kube-apiserver:v1.30.0"

time="2024-05-03T18:31:42+09:00" level=fatal msg="pulling image: rpc error: code = NotFound desc = failed to pull and unpack image \"registry.k8s.io/kube-apiserver:v1.30.0\": no match for platform in manifest: not found"

, error: exit status 1

これはそもそもDockerをサポート無くなったことが原因だと思われるエラー。

解決方法は、Dockerはアンインストールしなくて良いので、上記手順のCRI-Oをインストールする必要があります。

【😈エラー】[ERROR SystemVerification]: missing required cgroups: memory

以下のようなエラーが発生した場合、

error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR CRI]: container runtime is not running: output: time="2024-05-02T16:01:31+09:00" level=fatal msg="validate service connection: validate CRI v1 runtime API for endpoint \"unix:///var/run/containerd/containerd.sock\": rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService"
, error: exit status 1
        [ERROR SystemVerification]: missing required cgroups: memory

これは以下のように、/proc/cgroupsを確認すると、memoryが0(=disable)になっているため。

$ cat /proc/cgroups
#subsys_name    hierarchy       num_cgroups     enabled
cpuset  0       48      1
cpu     0       48      1
cpuacct 0       48      1
blkio   0       48      1
memory  0       48      0
devices 0       48      1
freezer 0       48      1
net_cls 0       48      1
perf_event      0       48      1
net_prio        0       48      1
pids    0       48      1

以下のように、「/boot/firmware/cmdline.txt」を編集して再起動すれば直る。

# cat /boot/firmware/cmdline.txt
console=serial0,115200 console=tty1 root=PARTUUID=0319b699-02 rootfstype=ext4 fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles cfg80211.ieee80211_regdom=JP cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory

見やすいように整形文も載せておきます。

# cat /boot/firmware/cmdline.txt
console=serial0,115200 console=tty1 root=PARTUUID=0319b699-02 rootfstype=ext4 fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles cfg80211.ieee80211_regdom=JP cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory

「cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory」を追加

以下コマンドで再起動を実行して反映します。

$ sudo reboot
😈【エラー】rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService

以下のようなエラーが発生した場合。

error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR CRI]: container runtime is not running: output: time="2024-05-02T16:21:11+09:00" level=fatal msg="validate service connection: validate CRI v1 runtime API for endpoint \"unix:///var/run/containerd/containerd.sock\": rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService"
, error: exit status 1

見やすいように整形した文もおいておきます。

error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR CRI]: container runtime is not running: output: time="2024-05-02T16:21:11+09:00" level=fatal msg="validate service connection: validate CRI v1 runtime API for endpoint \"unix:///var/run/containerd/containerd.sock\": rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService"
, error: exit status 1

これは以下で解決。

$ sudo rm /etc/containerd/config.toml
$ sudo systemctl restart containerd

参考: https://kenzo0107.github.io/2022/05/13/2022-05-14-fix-unknown-service-runtime.v1alpha2.runtimeservice/

configファイルの用意

$ 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

workerマシンの設定

masterで「kubeadm init」を実行したら以下のようなトークンと共にjoinコマンドが表示される。

kubeadm join 192.168.3.7:6443 --token vcig17.twnoe6ltm56tttttt \
        --discovery-token-ca-cert-hash sha256:b073fc0b166tttttc8cfea4e67a50468391395c2c02aecbe9b444782ee5cf6

これをworkerマシン上で実行する。

$ kubeadm join 192.168.3.7:6443 --token vcig17.twnoe6ltm56tttttt --discovery-token-ca-cert-hash sha256:b073fc0b166tttttc8cfea4e67a50468391395c2c02aecbe9b444782ee5cf6

kubeadm joinの際に出る可能性のあるエラー候補

😈【エラー】Get “http://localhost:10248/healthz”: context deadline exceeded

以下のようなエラーが発生した場合

Unfortunately, an error has occurred:
        The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' returned error: Get "http://localhost:10248/healthz": context deadline exceeded


This error is likely caused by:
        - The kubelet is not running
        - The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)

If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands:
        - 'systemctl status kubelet'
        - 'journalctl -xeu kubelet'
error execution phase kubelet-start: The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' returned error: Get "http://localhost:10248/healthz": context deadline exceeded

見やすいように整形した文もおいておきます。

Unfortunately, an error has occurred:
        The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' returned error: Get "http://localhost:10248/healthz": context deadline exceeded


This error is likely caused by:
        - The kubelet is not running
        - The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)

If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands:
        - 'systemctl status kubelet'
        - 'journalctl -xeu kubelet'
error execution phase kubelet-start: The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' returned error: Get "http://localhost:10248/healthz": context deadline exceeded

この場合、スワップの無効化がされていない可能性があります。

上記に記載のスワップの無効化をしてみると解消するかと思います。

確認作業

masterノードにて確認

$ kubectl get node
NAME          STATUS   ROLES           AGE   VERSION
k8s-master    Ready    control-plane   14d   v1.30.0
k8s-worker1   Ready    worker          11d   v1.30.0
$ kubectl get pod -A
NAMESPACE        NAME                                 READY   STATUS    RESTARTS   AGE
kube-flannel     kube-flannel-ds-q6676                1/1     Running   0          14d
kube-flannel     kube-flannel-ds-rjvtg                1/1     Running   0          11d
kube-system      coredns-7db6d8ff4d-rhgv8             1/1     Running   0          14d
kube-system      coredns-7db6d8ff4d-tzjj7             1/1     Running   0          14d
kube-system      etcd-k8s-master                      1/1     Running   0          14d
kube-system      kube-apiserver-k8s-master            1/1     Running   0          14d
kube-system      kube-controller-manager-k8s-master   1/1     Running   0          14d
kube-system      kube-proxy-76ksr                     1/1     Running   0          14d
kube-system      kube-proxy-9nlc8                     1/1     Running   0          11d
kube-system      kube-scheduler-k8s-master            1/1     Running   0          14d
metallb-system   controller-f68d6fd4f-m2nb4           1/1     Running   0          46h
metallb-system   speaker-fpgmk                        1/1     Running   0          11d
metallb-system   speaker-sbgvj                        1/1     Running   0          11d
$ kubectl get node
NAME          STATUS   ROLES           AGE   VERSION
k8s-master    Ready    control-plane   14d   v1.30.0
k8s-worker1   Ready    worker          11d   v1.30.0

以上で、初期構築終了。

タイトルとURLをコピーしました