投稿日:
更新日:

Raspberry Pi で構築する Bare-Metal Kubernetes - 準備編

Authors

目次

overview.png

はじめに

クラウドネイティブ に注目が集まる昨今、コンテナオーケストレーションツールとして Kubernetes がデファクトスタンダードな基盤技術となっています。 Kubernetes を用いることで 宣言的な設定(Declarative Configuration)に基づいたアプリケーションのデプロイ、管理、運用の自動化、スケーラビリティの確保等を実現することができます。

Kubernetes によりサービス運用の効率化や高度な自動化を実現できますが、内部のアーキテクチャは非常に複雑なものになっており、コンピュータサイエンスの基本的な知識も必要になります。 運用に際して、インフラエンジニアやクラスタの管理者は Kubernetes の内部コンポーネントの詳細や、その挙動を熟知しておくことが重要です。

Kubernetes の有名な学習リソースの一つに Kubernetes The Hard Way というものがあります。 これは、手作業で一からクラスタを構築して Kubernetes の内部構造への理解を深めるというコンテンツです。

Kubernetes The Hard Way では、主に GCP の Compute Engine を用いますが、今回は Raspberry Pi をベースにベアメタルでクラスタを構築してみました。 いわゆる『おうち Kubernetes』というやつです。

今回は、RaspberryPi で Kubernetes をセルフホスティングする方法について 『準備編』『構築編』『エコシステム編』 の 3 編にわたり紹介したいと思います。

準備編では、機器類の準備、RaspberryPi の初期設定をします。 また、Kubernetes の構築に必要となる各種 OSS の選定や、ネットワーク構成およびインフラ全体の設計について固めます。

全体の流れ

以下の流れで作業します。


【準備編】準備・設計 ⭐️ 本ブログ ⭐️

  1. 機器類の準備: Raspberry Pi 等の必要機器を準備します。
  2. 技術選定:主に CRI / CNI / LB を選定します。
  3. ネットワーク設計:ネットワーク構成と IP アドレスレンジを決定します。
  4. Raspberry Pi の初期設定:OS のインストールとホストマシンの基礎設定をします。

【構築編】クラスタ構築

  1. Kubernetes のインストール:依存パッケージの追加とカーネルパラメータを設定します。
  2. Kubernetes の初期設定:Control-Plane / Data-Plane を構築します。
  3. アプリケーションのデプロイ:アプリケーションを追加して MetaLB で公開します。
  4. 【番外編】MetalLB の仕組み:MetalLB の仕組みについて紹介します。

【エコシステム編】エコシステム整備

  1. モニタリング基盤の整備:クラスタメトリクスを収集して監視基盤を構築します。
  2. GitOps の整備:GitHub とベアメタル Kubernetes を接続します。

1. 機器類の準備

モニターやキーボード、マウス等、最低限の周辺機器は所持しているものとして以下を準備します。

機材名個数値段(単価)
Raspberry Pi 4 Model B 8GB4 個¥56,080 ( ¥14,020 )
Raspberry Pi PoE+ HAT4 個¥15,920 ( ¥3,980 )
micro SD card 32 GB4 個¥6,600 ( ¥1,650 )
Raspberry Pi 4 クラスタケース 冷却ファン付き1 個¥2,499
PoE スイッチ - TL-SG1005P1 個¥7,047
LAN ケーブル 0.15m4 本¥3,520 ( ¥880 )
LAN ケーブル 1m1 本¥892
microHDMI-HDMI 変換ケーブル1 本¥562
アクリル板 100mm*100mm*2mm1 枚¥304
ネジ12 本¥927
両面テープ6 枚¥588

価格は購入当時(2022 年 4 月現在)の値段ですが、時期によって変動する場合があります。 全部で ¥94,939(≒ ¥95,000) ぐらいです。

Raspberry Pi 4 Model B

raspberrpy-pi-4-model-b.png

Raspberry Pi はイギリスの Raspberry Pi Foundation が開発している名刺サイズのシングルボードコンピュータです。 主に教育用途を想定して設計されましたが、低価格ながら高性能なスペックであることから、現在では小規模なサーバや IoT の開発、試作や研究分野でも広く利用されています。

今回は Raspberry Pi 4 Model B 8GB を用います。

スペック情報
MachineRaspberry Pi 4 Model B
OSDebian GNU/Linux 12 (bookworm) 64bit
CPUCortex-A72 (ARMv8) BCM2711 @1.5GHz 4cores 4threads
ArchitectureARM (aarch64)
Memory8GB LPDDR4-3200 SDRAM
Storage32GB microSD

Control-Plane 1 台 / Data-Plane 3 台 の計 4 台の Raspberry Pi を使用します。 クラスタのスペックは 物理 CPU 12core(4core x3)メモリ 24GB(8GB x3)ストレージ容量 96GB(32GB x3)となります。

PoE+ HAT

poe-hat.png

PoE+ HAT を用いることで、電源供給をネットワークスイッチから Ether ケーブル一本で行うことが可能になります。 もちろん Type-C から給電することもできます。

また、RaspberryPi 4 Model B はプロセッサの処理能力が向上したことで消費電流も以前の機種と比べて大きくなっています。 財団公式より、RaspberryPi 4 Model B には 定格 5.1V / 3.0A DC 出力 15W 以上 が必要とされています。

また、排熱の観点からヒートシンクやファンを取り付けておいた方が良いですが、公式の Raspberry Pi PoE+ HAT には 25mm ファンが搭載されており、GPIO ピンを通じて SoC 温度に応じた回転制御機能もあります。

Raspberry Pi クラスタの構築

組み立て方法に関しては サイバーエージェント 青山さんの Develoer Blog を参考にします。

cluster-parts.png

配線をいい感じにしてアクリル板に固定します。

raspberrypi-kubernetes-cluster-1.png

2. 技術選定

まず、クラスタを構築するためのツールを選定します。

また、Kubernetes を動かすためには CRI(Container Runtime Interface)、CNI(Container Network Interface)、LB(Load Balancer)等のソフトウェアが必要になります。 今回は以下の OSS を採用します。

OSSコンポーネント説明
kubeadmControl-Plane / Data-PlaneKubernetes クラスタそのものの構築
containerdCRIPod を動かすためのコンテナランタイムとして機能
flannelCNIPod 間通信を確立
MetalLBLB(L4)クラスタに外部 IP アドレス(LAN IP)を付与

Control-Plane / Data-Plane

クラスタの構築・管理ツールには Kubernetes(CNCF)公式から提供されている kubeadm を用いることにします。 ただし、kubeadm は Rancher のような GUI は用意されていません。

kubeadm.png

kubeadm:
Kubeadm is a tool built to provide best-practice "fast paths" for creating Kubernetes clusters. It performs the actions necessary to get a minimum viable, secure cluster up and running in a user-friendly way. Kubeadm's scope is limited to the local node filesystem and the Kubernetes API, and it is intended to be a composable building block of higher level tools.

CRI:Container Runtime Interface

以前は dockershim で運用していましたが、Kubernetes v1.21 以降 Deprecate、v1.24 で Removal となったため、ネイティブな CRI をサポートする containerd を選定しました。 containerd を利用することで、Docker との互換性を維持しつつ移行作業が進められます。参考

containerd.png

containerd:
containerd is an industry-standard container runtime with an emphasis on simplicity, robustness, and portability. It is available as a daemon for Linux and Windows, which can manage the complete container lifecycle of its host system: image transfer and storage, container execution and supervision, low-level storage and network attachments, etc.

CNI:Container Network Interface

flannel は Kubernetes におけるコンテナネットワークを提供するための CNI プラグインで、他の OSS と比較して軽量かつシンプルな設計となっているのが特徴です。 Pod 間通信を実現するために、クラスタ内の各ノード上で VXLAN ベースのオーバーレイネットワークおよびルーティングを管理します。

flannel.png

flannel:
Flannel runs a small, single binary agent called flanneld on each host, and is responsible for allocating a subnet lease to each host out of a larger, preconfigured address space. Flannel uses either the Kubernetes API or etcd directly to store the network configuration, the allocated subnets, and any auxiliary data (such as the host's public IP). Packets are forwarded using one of several backend mechanisms including VXLAN and various cloud integrations.

LB:Load Balancer

MetalLB は Kubernetes で type: LoadBalancer のサービスを動かすための Addon コンポーネントです。 特に、オンプレミス環境(ベアメタル) やセルフホスティングされたクラスタにおいて L4 の負荷分散機構を提供します。

日本では サイボウズ - Neco プロジェクト での導入事例が有名です。

metallb.png

MetalLB:
Bare-metal cluster operators are left with two lesser tools to bring user traffic into their clusters, “NodePort” and “externalIPs” services. Both of these options have significant downsides for production use, which makes bare-metal clusters second-class citizens in the Kubernetes ecosystem. MetalLB aims to redress this imbalance by offering a network load balancer implementation that integrates with standard network equipment, so that external services on bare-metal clusters also “just work” as much as possible.

3. ネットワーク設計

まず、アーキテクチャとクラスタのネットワークを設計します。

全体構成

Raspberry Pi を以下の通り構成・配置して、IP アドレスを割り振ります。

cluster-network.png

Raspberry Pi の eth0 I/F は PoE L2 スイッチングハブに接続して、そこからブロードバンドルータに接続します。 ブロードバンドルータには TP-Link Deco M9 Plus を使用しています。

Raspberry Pi には PoE+ Hat を取り付けているため、ネットワークスイッチ(IEEE 802.3at PSE)から Ether ケーブル一本で給電するとともに、ノード間で通信するための IP アドレスを割り当てます。

また、SSH 接続やトラブルの際のバックアップリンクとして IEEE 802.11 系で wlan0 I/F にもアドレスを付与しておきます。

今回はプライベートネットワーク(LAN)内からのアクセスに限定し、アドレスファミリは IPv4 のみを用います。 各種ソフトウェアのインストール時は、ブロードバンドルータで NAPT してインターネットへ出します。

  • ネットワーククラス:クラス C(192.168.68.0/24)
    • ネットワークアドレス:192.168.68.0
    • ブロードキャストアドレス:192.168.68.255
    • サブネットマスク:255.255.255.0
      • CIDR:/24
      • 収容台数:1-254(254 台)
  • デフォルトゲートウェイ:192.168.68.1/24
  • DNS サーバ:192.168.68.1/24
ホスト名ノード IP(eth0)管理用 IP(wlan0)
master192.168.68.200/24192.168.68.210/24
node01192.168.68.201/24192.168.68.211/24
node02192.168.68.202/24192.168.68.212/24
node03192.168.68.203/24192.168.68.213/24

クラスタネットワーク

次にクラスタ内で使用する IP アドレス範囲を決めます。

  • Pod の IP アドレスレンジ
    • 10.16.0.0/12(1,048,574 個)
    • ローカルネットワーク内で使用していない IP アドレスを選択する
  • クラスタサービス の IP アドレスレンジ
    • 10.1.0.0/20(4,094 個)
    • ローカルネットワーク内で使用していない IP アドレスを選択する
  • MetalLB が利用する静的 IP アドレスの予約
    • 192.168.68.230 - 192.168.68.250(20 個)
    • DHCP でプライベート IP を払い出すので 192.168.68.0/24 サブネットレンジから選択する
    • Deco の場合は IP アドレスはデフォルトで 192.168.68.100 - 192.168.68.250 から払い出される
cluster-architecture.png

設定用 PC(Cluster Admin / Developer の部分)には macOS を用います。

4. Raspberry Pi の初期設定

設計が固まったら、早速以下の工程に基づいて Raspberry Pi の初期設定を行います。

SD カードのフォーマット

microSD カードを、設定用の PC(macOS)に接続してフォーマットします。 今回は SD Card Formatter というメモリフォーマッタを使用します。

sd-card-formatter-app.png
sd-card-formatter.png

32GB の SD Media が接続されていることを確認して『上書きフォーマット』を実行します。 ボリュームラベルは BOOT としておきます。

OS インストール

次に、RaspberryPi を起動するための OS をインストールします。 Raspberry Pi には Raspberry Pi OS(Raspbian)と呼ばれる Debian 派生の Linux を使用します。

raspberrypi-os.png

こちらのサイト から『RaspberryPi OS with desktop 64bit』を選択してディスクイメージ(.img)をダウンロードします。

raspberrypi-download.png

ダウンロードした OS イメージを SD カードに焼きます。 今回は手取り早く GUI で操作できる balenaEtcher を使用します。

balenaetcher-app.png
balenaetcher.png

SD カードを Raspberry Pi に挿入してから PoE ケーブルを接続して起動します。

以下のようなデスクトップが表示されれば OS のインストール作業は完了です。

raspberrypi-desktop.png

リモート接続

Raspberry Pi にリモート接続できるようにします。

左上の Raspberry Pi アイコン > Preferences > Raspberry Pi Configuration > Interfaces

SSH(Secure Shell)と VNC(Virtual Network Computing)を有効化します。

raspberry-pi-configuration.png

リモート接続できることを確認します。

スペック確認

作業の前に、意図したスペックであるかを確認しておきます。

ホスト名変更

以下の二つのファイルをそれぞれ変更します。 各コンポーネントに応じた名前を付与します。

  • $ sudo vim /etc/hostname
  • $ sudo vim /etc/hosts

IP アドレス設定

Debian12(bookworm)は NetworkManager が標準となっています。 もし、Debian11(bullseye)以前から OS をアップグレードしている場合は、ネットワークデーモンが dhcpcd5 と競合しないように辻妻を合わせてください。

まず、nmcli で有線接続(Ethernet)を作成しておきます。

以下 2 つのファイル(Ethernet / Wi-Fi)を修正します。 なお、今回はブロードバンドルータとして TP-Link Deco M9 Plus を使用しているため、無線接続名は TP-Link Deco M9 Plus.nmconnection となっていました。 こちらは接続先ルータの情報に合わせて適宜変更してください。

また、デバイスの UUID と割り当てる IP アドレスは各コンポーネント毎に適切なパラメータを設定してください。

  • Wi-Fi:$ sudo vim /etc/NetworkManager/system-connections/TP-Link\ Deco\ M9\ Plus.nmconnection
  • Ethernet:$ sudo vim /etc/NetworkManager/system-connections/Wired\ connection\ 1.nmconnection

また、今回は IPv6 アドレスを使用しないため、ホームネットワークが IPv6 に対応している場合は、以下のコマンドで明示的に IPv6 アドレスの割り当てを無効化します。

  • $ sudo vim /etc/sysctl.conf

Raspberry Pi を再起動して意図した IP アドレスが割り当てられていることを確認します。

SSH キーの登録

IP アドレスを固定できたら、証明書認証でリモート接続できるようにします。

1. 接続元 PC(macOS)

macOS の SSH Config に登録します。

  • $ sudo vim ~/.ssh/config

2. Raspberry Pi

3. 接続元 PC(macOS)

SSH キーで Raspberry Pi に接続できるか確認します。

リモートデスクトップ設定

リモートデスクトップが利用できるように VNC を設定します。 実際、デスクトップを使用する機会は殆どないのでスキップしても構いません。

Debian11(bookworm)以降、デスクトップのウィンドウマネージャーは X11 から WayVNC に変更となったみたいです。

  • $ sudo vim ~/.config/wayvnc/config

RealVNC で wlan0 に割り当てた管理用 IP アドレスに VNC 接続できることを確認します。

real-vnc-connect-configuration.pngreal-vnc-overview.png

以上で基本的な Raspberry Pi の初期設定は終了です。 この作業をパラメータを変えて 4 台分行います。

まとめ

今回は、Kubernetes The Hard Way に則り Raspberry Pi でベアメタル Kubernetes をセルフホスティンングするための準備を行いました。 今回のブログでは、機器類の準備、RaspberryPi の初期設定、Kubernetes の構築に必要となる各種 OSS の選定や、インフラ全体の設計を固めました。

Raspberry Pi で Debain12 を利用する場合、以前のバージョンと設定内容が異なっていたり、カーネルやデーモンの主要機能が変わっていたりするので、適宜ドキュメントを確認しながら作業を進めてください。

次回のブログでは、早速 kubeadm を用いて Kubernetes クラスタを構築していきます。

参考・引用