利用したもの
以下の3台のRaspberry Piを利用して、k3sのクラスタ環境を構築します。
- Raspberry Pi 3 Model B
- Raspberry Pi 4 Model B
- Raspberry Pi 4 Model B
細かい説明は省略しますが、PoE(Power over Ethernet)を利用して、電源供給とネットワーク接続をしています。重要なことは電源供給が安定していて、互いに通信できることです。
Raspberry Pi OS Liteのインストール
まずはOSイメージを記憶媒体に焼きます。公式のRaspberry Pi Imagerを利用します。
今回はRaspberry Pi OS Liteを利用します。
# raspberry pi imagerのインストール
brew install --cask raspberry-pi-imager
# raspberry pi imagerのアップデート
brew upgrade --cask raspberry-pi-imager
SSHでの接続が可能な設定とします。
Raspberry Pi ヘッドレスセットアップなどを参考にする。
事前準備(OSインストール後)
Raspberry Pi OS Liteをインストールしたら、初期設定を行います。
以下のコマンドを実行して、初期設定を行います。
apt
の更新とアップグレード
sudo apt update && sudo apt upgrade -y
固定IPアドレスの設定
/etc/dhcpcd.conf
を編集して、固定IPアドレスを設定します。
interface eth0
static ip_address=192.168.x.xx/24
static routers=192.168.1.1
static domain_name_servers=8.8.8.8
スワップ無効化
Kubernetes/k3sではスワップ使用は推奨されません。Raspberry Pi OSではdphys-swapfile.service
でスワップが管理されているので、以下でオフにします。
sudo swapoff --all
sudo systemctl disable dphys-swapfile.service --now
cgroupメモリサブシステム有効化
RPi OSのカーネルはデフォルトでcgroupのメモリ制御が無効なので、/boot/firmware/cmdline.txt
末尾に以下を追加し、再起動します。
改行をせずに1行で記述することに注意してください。
Kubernetes / k3s / Docker などがメモリ制限をできるようにメモリコントロールグループ(Memory cgroup)を有効にする必要があります。これにより、コンテナが使用できるメモリ量を制限できます。
cgroup_enable=memory cgroup_memory=1
設定後は再起動します。
sudo reboot
以下のコマンドでcgroupのメモリ制御が有効になっていることを確認します。
zgrep CONFIG_MEMCG /boot/config-$(uname -r)
出力がCONFIG_MEMCG=y
であれば有効です。
カーネルモジュールの確認
通常k3sサーバー起動時にこれらをロードしますが、事前にロードしておくと確実です。
モジュール名 | 役割 |
---|---|
overlay |
コンテナがファイルシステムのレイヤー化を行う際に使用 |
br_netfilter |
Linuxブリッジ経由のトラフィックを iptables で処理するために必要 |
net.ipv4.ip_forward |
Pod間通信や外部アクセスに必要(ルータ動作) |
/etc/modules-load.d/k3s.conf
を作成して起動時にロードするモジュールを指定します。
echo -e "overlay\nbr_netfilter" | sudo tee /etc/modules-load.d/k3s.conf
sudo tee /etc/sysctl.d/k3s.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
で設定を反映します。
sudo reboot
で再起動して確認してください。
lsmod | grep -E 'overlay|br_netfilter'
sudo sysctl net.bridge.bridge-nf-call-iptables
sudo sysctl net.ipv4.ip_forward
以下のような出力が得られればOKです。
br_netfilter 32768 0
bridge 282624 1 br_netfilter
overlay 143360 0
ipv6 573440 40 bridge,br_netfilter
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
k3s のインストール
k3sは軽量なKubernetesディストリビューションで、Raspberry Piのようなリソースが限られた環境でも動作します。
マスターノード (サーバー) のセットアップ
マスター(Control-Plane)ノードでは k3s サーバーをインストールします。以下のコマンドでインストーラを実行します。--write-kubeconfig-mode 644
を付けると、出力される kubeconfig ファイルのパーミッションが緩和され、一般ユーザでもアクセスできるようになります。
curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644
k3s サーバーのインストールと起動が完了します。ステータスは systemctl status k3s
で確認できます。
インストール完了後、初期状態ではマスター自身のみがクラスタに参加しており、kubectl get nodes
でノード一覧を確認できます。以下のような出力が得られれば成功です。
NAME STATUS ROLES AGE VERSION
pi-master Ready control-plane,master 77s v1.32.6+k3s1
ワーカーノードの参加
マスターで次のコマンドを実行し、参加トークンを確認します。
sudo cat /var/lib/rancher/k3s/server/node-token
出力されたトークンを控えたら、ワーカーノードに移動して k3s エージェントをインストールします。以下のようにマスターのURLとトークンを環境変数で指定します。
curl -sfL https://get.k3s.io | K3S_URL=https://<マスターのIP>:6443 K3S_TOKEN=<取得したトークン> sh -
全てのワーカーノードで同様の手順を実行します。
マスターノードで kubectl get nodes
を実行して、ワーカーノードが正常に参加していることを確認します。
以下のように、ワーカーノードが表示されれば成功です。
NAME STATUS ROLES AGE VERSION
pi-master Ready control-plane,master 8m28s v1.32.6+k3s1
pi-worker01 Ready <none> 48s v1.32.6+k3s1
pi-worker02 Ready <none> 69s v1.32.6+k3s1
クラスタ動作確認
ノード確認
kubectl get nodes
で全ノードが Ready になっているか確認します。
Pod確認
kubectl get pods -A
で全namespaceのPod一覧を確認します
k3s導入時にデフォルトで動くシステムコンポーネント(CoreDNS、metrics-server、local-path-provisioner、Traefik など)が Running 状態で立ち上がっていることを確認します。
kubectl の利用
k3s は /etc/rancher/k3s/k3s.yaml
に管理用の kubeconfig を生成しています。
マスターで kubectl を使う場合はデフォルトで参照されますが、別PCから操作する場合はこのファイルをコピーし、環境変数 KUBECONFIG を設定するなどしてリモートからアクセスできます。
[オプション]Kubernetes Dashboard の導入
Kubernetes公式のWebベースGUI。k3sにも対応しており、ノード・Pod・サービス・イベントなどをリアルタイムで確認・操作できます。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: v1
kind: Secret
metadata:
name: admin-user-token
namespace: kubernetes-dashboard
annotations:
kubernetes.io/service-account.name: admin-user
type: kubernetes.io/service-account-token
# 1. 管理者ユーザーを作成
kubectl apply -f ~/k8s-dashboard/dashboard-admin-user.yaml
# 2. トークンを取得
kubectl get secret admin-user-token -n kubernetes-dashboard -o jsonpath='{.data.token}' | base64 -d
# 外部からアクセスできるように0.0.0.0にバインド
kubectl port-forward -n kubernetes-dashboard service/kubernetes-dashboard 8443:443 --address 0.0.0.0
# これで https://<remoteアドレス>:8443 でアクセス可能