2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ラズパイ5でお家k8sを構築する

Last updated at Posted at 2024-11-30

はじめに

tosaken1116 Advent Calendar 2024 1日目担当の土佐犬です

最近raspberry pi 5を手に入れる機会があったので今回はそれを使ってお家k8sを構築するという話です

必要材料

  • raspberry pi 5 何台でも
  • LANケーブル ラズパイの数分
  • 電源ケーブル ラズパイの数分
  • ラズパイ用ケースタワー ラズパイの数に応じた大きさのもの
  • 電源ハブ 電源ケーブル分のポートがあるもの
  • LANハブ LANケーブル分のポートがあるもの
  • SDカード

ざっとこんな感じです

私は以下を購入しました

LANケーブルと電源ケーブルは長さがギリギリだったので15cm2と30cm2とかをお勧めします

電源に関してraspberry 5は5V 3Aの電源が必要ですが調べたところ専用アダプターしか出てこず使うコンセントをひとつにしたかったのでACアダプターからtype Cで給電しています

LANケーブルは今のところCAT 6Aを使っていますCAT7?8?知らんな

10Gbpsはロマンありますが今のところそれ以外のところがボトルネックなので買いませんでした

ラズパイケースタワーは6段のものを買いました

今後拡張する可能性と今家にあるraspberry4を乗せるようですね

組み立て

組み立てていきます

IMG_6662.jpg

とは言ってもそこまで複雑なものはありません

スペーサーつけて

IMG_6664.jpg

ベースに乗せて

IMG_6665.jpg

組み立てて完成

IMG_6666.jpg

ちなみにここでヒートシンクを貼り忘れてたことに気づいたので1回バラしました

配線完了

IMG_6667.jpg

一番上はラズパイ4です

この子の電源は隣のankerの 8 in 1のアダプターから来てます

まぁまぁ使いやすいのでお勧めです

ソフトウェアの方

OS書き込み

ということで組み立てが終わったのでSDカードにOSを書き込んでいきます

OS書き込みはRaspberry Pi Imagerを使いました

ラズパイといったらこれですね

書き込んだOSはRaspberry pi liteにしました

RancherOSというDockerに特化したOSがあるそうですが今回は一旦これで

ここら辺スクショ撮ってませんでしたが、Raspberry Pi Imagerでデフォルトのユーザーとパスワードの設定ができるのでそこでしておきました

IP固定

基本的に何もしなければパソコンというものは起動するたびにルーターからプライベートIPが割り振られます。(実際はリース期間というものがあり一定期間のうちは同一IPが割り振られるが恒久的ではない)

sshするときに毎回プライベートIPを探し出すのは面倒なのでプライベートIPを固定しちゃいます

プライベートIPを固定する方法は2種類あります

  1. ルーターから固定する
  2. /etc/network/interfacesを書き換える

今回は1のルーターから固定するでエイヤ!しました

うちはBuffaloのルーターを使っているのでこれの管理画面に入り特定のMACアドレスに対し、特定のIPを割り振ることができました

  1. まずはarp -aコマンドを使って同一ネットワーク内の端末に割り振られているIPに適当にsshを仕掛けていく
  2. 当たったらラッキー そのIPを覚えておく
  3. ルーターの管理画面からIPが設定してあるデバイスに対し固定するIPを設定する

ssh接続確認 ・ 公開鍵認証

次にssh接続をしていきます

最初はOSを入れるときに指定したユーザー名とパスワードを用いて認証を行います

ssh <username>@<private-ip>

接続が確認できたら、ゲストマシン側(ラズパイじゃない方)で公開鍵を作ります

ssh-keygen -t rsa -b 4096 -f ./.ssh/<鍵の名前>

次に生成した公開鍵をラズパイ側にコピーします

ssh-copy-id -i ~/.ssh/<鍵の名前>.pub <username>@<private-ip>

一旦疎通確認をします

ssh -i ./.ssh/<鍵の名前> <username>@<private-ip>

接続が確認できたらsshの設定ファイルを書き換えてめんどくさいコマンドを省略します

sudo vim ~/.ssh/config
~/.ssh/config
Host <接続名>
        HostName <接続先 private ip>
        User <username>
        Port <ssh port:デフォルト`22`>
        IdentityFile <sshキーの場所 さっきのコマンド通りだと`~/.ssh/<鍵の名前>`>

これで

ssh <接続名>

で接続できるようになりました

疎通確認ができたらラズパイ側のパスワード認証を閉じておきます

sshd_configをいじる

sudo vi /etc/ssh/sshd_config

この行を変える

# To disable tunneled clear text passwords, change to no here!
- #PasswordAuthentication yes
+ PasswordAuthentication no

sshdを再起動

systemctl restart sshd

これでパスワード認証は弾かれて公開鍵認証が通ればOKです

dockerを入れていく

まずはdockerを入れます

これはk8sが管理するコンテナランタイムです

ここをみてぽちぽちしていくだけです

ここで私はubuntu系のインストールページを見てやったためエラーが出ました

E: The repository 'https://download.docker.com/linux/ubuntu bookworm Release' does not have a Release file.

アーキテクチャはちゃんと見ようね!

raspberry os liteはdebian系みたいです

kubernetesをインストールする

さていよいよkubernetesをインストールします

そもそもkubernetesとは何かって話ですがkubernetesとはコンテナ化されたアプリケーションをデプロイ、スケーリング管理するためのプラットフォームです。(私も調べた限りの内容なので間違えてたらすみません)

公式サイト:https://kubernetes.io/ja/

何が嬉しいのって話ですが、簡単にいうと

  • コンテナのスコープを絞れる
    • 特定のコンテナの間だけ通信できるようにできたりする
  • コンテナが落ちても自動で再起動する
    • 障害が起きても安心
  • トラフィックに応じて自動でスケーリングされる
    • 急なトラフィック増加、減少にも柔軟に対応

※筆者はフロントエンド専門なのでインフラは初心者です。これから頑張ります

kubernetesを構築するにあたり次の3つのツールをインストールします

kubelet ノードの管理をするエージェント

kubeadm クラスタのセットアップや管理を行う

kubectl クラスタを操作するCLI

ここでノードクラスタという概念が出てきましたが

ノードとはポッドを動かすマシン

クラスタとは複数のノードを管理する単位,概念(??)

ポッドとは1つ以上のコンテナをまとめた単位 最小デプロイ単位

ポッドはノードに内包され、ノードはクラスタに内包されるといった感じです

でとりあえずこれらのツールをインストールします

インストールにはこちらの公式サイトを参考にしました

全てのラズパイにkubeadmとkubectlとkubeletのインストールをした後マスターノードのみkubeadm initを実行します

sudo kubeadm init

まぁ大体一発でうまくいくことってないんですよね

[init] Using Kubernetes version: v1.31.3
[preflight] Running pre-flight checks
W1121 07:39:45.421312    3965 checks.go:1080] [preflight] WARNING: Couldn't create the interface used for talking to the container runtime: failed to create new CRI runtime service: 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
    [WARNING Swap]: swap is supported for cgroup v2 only. The kubelet must be properly configured to use swap. Please refer to https://kubernetes.io/docs/concepts/architecture/nodes/#swap-memory, or disable swap on the node
    [WARNING SystemVerification]: missing optional cgroups: hugetlb
error execution phase preflight: [preflight] Some fatal errors occurred:
    [ERROR FileContent--proc-sys-net-ipv4-ip_forward]: /proc/sys/net/ipv4/ip_forward contents are not set to 1
[preflight] If you know what you are doing, you can make a check non-fatal with --ignore-preflight-errors=...
To see the stack trace of this error execute with --v=5 or higher

以下のコマンドを実行して多少どうにかなりました

sudo containerd config default | sudo tee /etc/containerd/config.toml
sudo vim /etc/containerd/config.toml
SystemdCgroup = true
sudo systemctl restart containerd
sudo vim /etc/sysctl.conf
net.ipv4.ip_forward=1
sudo sysctl -p

あとはここを見逃していました

どうやらswapなるものを切っておかなきゃいけないらしいです

sudo swapoff -a

なんやかんやあり

Your Kubernetes control-plane has initialized successfully!

やったぜ!control-planeを初期化できた!!!!!!!!!

kubectl config viewを実行してみる

apiVersion: v1
clusters: null
contexts: null
current-context: ""
kind: Config
preferences: {}
users: null

configがないですね

本来だったらここで長々とconfigが出てくるはずなんですが出てきませんでした

デフォルトではこのコンフィグは~/.kube/configを読むようになっていますが、ファイルの存在も確認できました

設定コピーもし直したりしてみました

mkdir -p ~/.kube
sudo cp /etc/kubernetes/admin.conf ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config

治りません!!!!!

全部ドカーン!!して最初からやり直しました。

やり直したあとkubectl config view

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://<private ip>:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED

うまくいってそうです

それじゃぁこれをマスターノードとしてワーカーノードとの接続をします

ワーカーノードとマスターノードの接続はとても簡単です

kubeadm initを実行した時のログに

kubeadm join <private ip>:6443 --token <token> 	--discovery-token-ca-cert-hash <hash>

これをワーカーノードで実行するだけでマスターノードに接続できます

簡単!!

kubectl get nodes

imagewm.png

繋がりました

でもまだ全部NotReadyですね

インフラ強強な後輩に土下座して(してません)聞いたところCNIが入ってないんじゃないかと言われました

CNIとはポッド間通信をするためのものです

ということでCNIプラグインを入れます

CNIプラグインの代表的なものにCalicoとFlannelというものがありますが今回はCalicoを入れました

kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/calico.yaml

imagecni.png

やったぜ

無事kubernetesが動くようになりました

なんか動かす

動くようになったからには動かしたいですよね

ということでみんな大好きnginxを動かします

デプロイの作成をします

kubectl create deployment nginx --image=nginx

デプロイとはポッドとその管理をするオブジェクトです

デプロイを作成することによってReplicaSetが作成されます。

ReplicaSetによりポッドの増減やポッドのアップデートをすることができます

実際に作られたデプロイとReplicaSetを見てみましょう

kubectl get deployment 
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   0/1     1            0           7s
 kubectl get replicaset
NAME               DESIRED   CURRENT   READY   AGE
nginx-676b6c5bbc   1         1         1       7s

deploymentとreplicasetがそれぞれ一つずつ生成されています。

deploymentがREADYになっていませんがちょっとするとREADYになります

NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   1/1     1            1           11s

さてこれでデプロイが作れましたがこのままではアクセスすることができません。

アクセスできるようにするにはサービスというリソースが必要になります

サービスは作成したデプロイメントのpodを外部に公開するための機能です。

以下のコマンドを実行してnginx デプロイをサービスとして扱います

kubectl expose deployment nginx --type=NodePort --port=80

NodePortとはノードのポートを解放することで外部からポッドにアクセスできるようにするサービスの種類です。

ここでは80番ポートにアクセスできるようにしています

kubectl describeコマンドを使ってサービスの詳細を覗きます

kubectl describe svc nginx
Name:                     nginx
Namespace:                default
Labels:                   app=nginx
Annotations:              <none>
Selector:                 app=nginx
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.107.23.138
IPs:                      10.107.23.138
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30357/TCP
Endpoints:                172.16.204.206:80
Session Affinity:         None
External Traffic Policy:  Cluster
Internal Traffic Policy:  Cluster
Events:                   <none>

ここで

NodePort:                 <unset>  30357/TCP

とあるので
http://<worker nodeのprivate ip>:30357
にアクセスします

image.png
見慣れたnginxの画面が出てきました

このポートも指定できるらしいですが今回はとりあえず動かしてみたかっただけなので割愛します

終わりに

ということで無事にお家kubernetesの構築ができました!!!!!

残念ながら筆者の家は賃貸でポート開放ができないので外部に公開とかはできませんが、そのうち引っ越すのでそれまではkubernetesの勉強だったりをするのに使いたいと思います

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?