ラズパイ4 x 4台でホームKubernetesを作る(1) (2023年版)

Raspberry Pi 4を使ってKubernetesクラスターを構築します。2023年版ということでDebianのバージョンは12 (bookworm)、コンテナランタイムはcontainerd、CLIはnerdctl、Kubernetesのバージョンはv1.28を使用します。まずは1台目のRaspberry Pi OSとnerdctlのセットアップまで行います。

ハードウェア環境

品物詳細個数
ラズパイ本体Raspberry Pi 4 Model B 4GB4
PoE HATRaspberry Pi PoE board (UD-RPPOE)4
micro SDカードTranscend micro SDHC 32GB/64GB4
スイッチングハブTP-Link スイッチングハブ ギガ 5ポート PoEハブ (TL-SG1005P)1
その他積層式ケース、LANケーブル、電源ケーブルなど
最初のセットアップ時にはキーボードやHDMI接続ディスプレイも必要
ホームKubernetes環境

この中で調達が一番困難だったのはPoE HATでした。2021年頃に購入しましたが、コロナ禍の影響で在庫が無く、いろんな通販サイトを利用してどうにか4台調達しました。UD-RPPOEを調べると、2023年12月時点ではすでに生産終了(IODATA)になっているようですね。

4台のRaspberry Piは1台目をKubernetesのコントロールプレーンにして、2〜4台目をKubernetesのノードにします。公式によれば、かつてマスターノードと呼んでいたものは今はコントロールプレーンと呼ばれているようです。GitHubのmasterブランチがmainブランチに変名されたことと同じ理由でしょうか。ホスト名をコントロールプレーンにするのは長いので、GitHubに習ってmainを使うことにします。無線LAN側のIPアドレスはWi-Fiのアクセスポイントへ接続し、有線LAN側のIPアドレスはスイッチングハブ経由での通信に用います。

ホスト名無線LANのIPアドレス有線LANのIPアドレス
pi4main192.168.x.90/2410.0.0.1/22
pi4node1192.168.x.91/2410.0.1.1/22
pi4node2192.168.x.92/2410.0.1.2/22
pi4node3192.168.x.93/2410.0.1.3/22

Raspberry Pi OSのインストール(1台目)

まずはmicro SDカードにRaspberry Pi OSを書き込みますが、最初の1台目のmicro SDカードをある程度までセットアップしてから2〜4台目のmicro SDカードにコピーしていくことにします。Kubernetes用ですので、Lite版のイメージを使います。

公式のページからWindowsやUbuntu、macOS用のツール(Raspberry Pi Imager)を使えば簡単にできますが、初代Raspberry Piの頃は以下のようにddコマンドでmicro SDカードにイメージを書き込んでいました。以下はmacOSでのコマンドです。

diskutil list    # micro SDカードの/dev/disk[番号]をチェックする
diskutil eraseDisk FAT32 ボリューム名 MBR /dev/disk[番号]
diskutil unmountDisk /dev/disk[番号]
xz -d 2023-10-10-raspios-bookworm-arm64-lite.img.xz
sudo dd if=2022-01-28-raspios-bullseye-arm64-lite.img of=/dev/rdisk[番号] bs=16m

最初の1台目はHDMI接続ディスプレイとキーボードをつないでセットアップを行っていきます。最初に表示される画面で、キーボード配列を選択し、その後ユーザー名とパスワードを入力します。その後、Raspberry Pi OS Lite版ではコンソールの画面で「raspberrypi login:」が表示されるので、先ほど入力したユーザー名とパスワードでログインします。

Raspberry Pi OSにログインしたら、raspi-configコマンドでセットアップしていきます。

sudo raspi-config
第1階層第2階層説明
Updateraspi-configを最新版にバージョンアップします。
System OptionsWireless LAN無線LANの設定を行います。国はJP(日本)を選択して、SSIDとパスワードを入力します。
System OptionsHostname1台目のホスト名「pi4main」を入力します。
Interface OptionsSSHSSHを有効にします。
Localisation OptionsLocaleIPアドレスの設定が終わったら(nmtui)、ja_JP.UTF-8 UTF-8を選択します。
Localisation OptionsTimezoneAsiaを選択して、Tokyoを選択します。
Advanced OptionsBootloader VersionLatestを選択します。
再起動後、「sudo vcgencmd bootloader_version」コマンドでブートローダのバージョンを確認できます。
Advanced OptionsBoot OrderもしUSB接続したHDD/SSDから起動できるようにするのであれば、USB Bootを選択します。

最終的には4台分のSDカードを作成するので、今のうちにOSのアップグレードを行っておきます。

sudo apt update
sudo apt full-upgrade

1台目のIPアドレスを設定します。Debian 12 bookworm版のRaspberry PiではNetworkManagerを使っていますので、コンソール用の設定画面であるnmtuiコマンドでIPアドレスを設定します。

sudo nmtui

「Edit a connection」を選択してEnterキーを押すと「Ethernet」と「Wi-Fi」のリストが表示され、「Ethernet」の下には「Wired Connection 1」が表示されるので、これを選択したままEnterキーを押すとIPアドレスの入力画面になります。

同様の手順でWi-FiのIPアドレスも固定IPアドレスに変更します。

IPv6は不要なのでDisabledにしますが、NetworkManagerの設定だけでは完全にIPv6を無効化できない(localhostに::1が残る)ので、/boot/cmdline.txtにIPv6無効化の設定を追加します。

sudo nano /boot/cmdline.txt
ipv6.disable=1 console=serial0,115200 console=tty1 root=・・・

Debian 11 bullseyeまでは/etc/sysctl.confにIPv6無効化の設定を追加していましたが、Debian 12 bookwormでは無効にできなくなったので要注意です。

# Disable IPv6                                                                                      
net.ipv6.conf.all.disable_ipv6=1

再起動後、SSHで接続できるようになるので、SSH公開鍵認証でログインできるようにします。

# macOSからid_rsa.pubをコピーする
ssh-copy-id -i ~/.ssh/id_rsa.pub pi@192.168.x.90

PoE HATのファンが回りっぱなしになるため、ファンの回転温度を変更します。ついでに使用しないBluetoothも無効にしておきます。

sudo nano /boot/firmware/config.txt

ファイルの末尾に以下の設定を追加して再起動します。

dtoverlay=rpi-poe
dtparam=poe_fan_temp0=70000,poe_fan_temp0_hyst=1000
dtparam=poe_fan_temp1=75000,poe_fan_temp1_hyst=5000
dtparam=poe_fan_temp2=80000,poe_fan_temp2_hyst=5000
dtparam=poe_fan_temp3=82000,poe_fan_temp3_hyst=2000

dtoverlay=disable-bt

もし、無線LANの接続が不安定になるようでしたら、無線LANの電源管理を無効化するとよいかもしれません。

sudo apt install wireless-tools
sudo nano /etc/rc.local
# exit 0の前に挿入する
/usr/sbin/iwconfig wlan0 power off
sudo systemctl restart rc-local
iwconfig wlan0	# Power Management:off を確認する

gitやtmuxなどのツールをインストールしておきます。通信の確認用にiperfも入れています。NFSクライアントやSMBクライアントはKubernetesクラスターのノードからNFSサーバやSMBサーバに接続できるようにあらかじめインストールしておきます。

sudo apt install tmux iperf
sudo apt install nfs-common    # NFSクライアント
sudo apt install cifs-utils smbclient  # SMBクライアント
sudo apt install build-essential libbz2-dev libdb-dev \
libreadline-dev libffi-dev libgdbm-dev liblzma-dev \
libncursesw5-dev libsqlite3-dev libssl-dev \
zlib1g-dev uuid-dev tk-dev automake asciidoc git

containerdとnerdctlのセットアップ

コンテナランタイムをセットアップするため、containerdやrunc, CNIなどが同梱されているnerdctlのFull版をインストールします。2023年12月現在、最新版はv1.7.1です。

sudo apt install iptables arptables ebtables
sudo nano /boot/cmdline.txt
cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 ・・・

再起動後、nerdctlのリリース一覧を見てARM64のFull版をダウンロードし、/usr/local配下に展開します。

mkdir ~/temp
cd ~/temp
wget https://github.com/containerd/nerdctl/releases/download/v1.7.1/nerdctl-full-1.7.1-linux-arm64.tar.gz
sudo tar Czxvf /usr/local nerdctl-full-0.20.0-linux-arm64.tar.gz

Kubernetesのコンテナランタイムとして使うための設定を行います。

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
sudo nano /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  ...
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true

この後1台目にはプライベートレジストリを立ち上げるので、/etc/containerd/config.tomlにプライベートレジストリを追加するための設定も行います。

[plugins."io.containerd.grpc.v1.cri".registry]
  config_path = "/etc/containerd/certs.d"

/etc/containerd/certs.dディレクトリにDocker Hubのレジストリとプライベートレジストリの設定を追加します。

sudo mkdir -p /etc/containerd/certs.d/docker.io
sudo nano /etc/containerd/certs.d/docker.io/hosts.toml
server = "https://registry-1.docker.io"
[host."https://registry-1.docker.io"]
sudo mkdir -p /etc/containerd/certs.d/10.0.0.1:5000
sudo nano /etc/containerd/certs.d/10.0.0.1:5000/hosts.toml
server = "http://10.0.0.1:5000"
[host."http://10.0.0.1:5000"]
  capabilities = ["pull", "resolve", "push"]
  skip_verify = true

containerdをRootfulモードで起動し、hello-worldで動作確認します。「Hello from Docker! (以下略)」と表示されれば成功です。

sudo systemctl enable --now containerd
sudo nerdctl run hello-world	# テスト実行

nerdctl buildが使えるようにBuildkitを動かします。

sudo mkdir -p /etc/buildkit
sudo nano /etc/buildkit/buildkitd.toml
[worker.oci]
  enabled = false

[worker.containerd]
  enabled = true
  # namespace should be "k8s.io" for Kubernetes (including Rancher Desktop)
  namespace = "default"
sudo systemctl enable --now buildkit

kubeadm、kubelet、kubectlのインストールは次回やります。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする