Raspberry PI シリーズで分散環境構築(その1:モデル別、ディスクレスクライアント化の可否まとめ)

# 連載リスト
アップ済みの連載リストはこちら
1. [Raspberry PI シリーズで分散環境構築(その1:モデル別、ディスクレスクライアント化の可否まとめ)](https://qiita.com/p_cub/items/e81dd0f49b3f6fb024a5)
2. [Raspberry PI シリーズで分散環境構築(その2: PiServer の解析と代替システムの設計まで)](https://qiita.com/p_cub/items/69fa32a9a62890ca1d04)
3. [Raspberry PI シリーズで分散環境構築(その3: dnsmasq のインストールと設定)](https://qiita.com/p_cub/items/e7c889b0f92a868a6c20)
4. [Raspberry PI シリーズで分散環境構築(その4: NFSサーバの構築とクライアント用OSのインポート)](https://qiita.com/p_cub/items/dd682de7de28276129e6)
5. [Raspberry PI シリーズで分散環境構築(その5: クラスタノード向け Raspberry PI OS のカスタマイズ(1))](https://qiita.com/p_cub/items/ecf4c48b7ecb08d971b1)
6. [Raspberry PI シリーズで分散環境構築(その6: クラスタノード向け Raspberry PI OS のカスタマイズ(2))](https://qiita.com/p_cub/items/73dc833302c3f064dc39)
7. [Raspberry PI シリーズで分散環境構築(その7: 各ラズパイ向けの tftp ルート設定と起動試験)](https://qiita.com/p_cub/items/ecef742e86ab2991c1b0)
8. [Raspberry PI シリーズで分散環境構築(その8: Webクラスタ構築のケース(前半))](https://qiita.com/p_cub/items/10751e2daa2d3b74c5d5)
9. [Raspberry PI シリーズで分散環境構築(その9: Webクラスタ構築のケース(後半))](https://qiita.com/p_cub/items/c4c837a57e6487a076d4)

本稿は上記リストの「その1」となります。

# 注意点
本稿は以下の条件を満たすラズパイを対象としたものです。

- ストレージにmicroSD を採用し
- 有線LANの口を持つ

従って

- 初代は関係ない
- Zero系、Compute Module も関係ない

ことになります。

# 保有する Raspberry PI シリーズの枚数が多くなると出てくる問題と解決方針

新しいラズパイが登場すると、安価故につい買ってしまうものですよね? 更に私の悪い癖なんですが、冗長性を考えて、2枚同時に買うのが常なのです。そんなこんなで、2B以降3B,3B+,4B,がそれぞれ2枚ずつ、手持ちのラズパイが計8枚にもなってしまった私が直面した問題がこちら。

## 問題その0: 物理的問題(解決済み)
<dl>
<dt>置き場所</dt>
<dd>全部にケース+ファンだとかさばって仕方がない → スタック化</dd>
</dl>
![68747470733a2f2f696d616765732d6e612e73736c2d696d616765732d616d617a6f6e2e636f6d2f696d616765732f492f373142685957657668644c2e5f41435f534c313530305f2e6a7067.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267238/a6b4551c-4645-ba27-6c9e-ab32d5f9dbc6.jpeg)
<dl>
<dt>LAN/電源用USBケーブルの配線</dt>
<dd>スパゲティは流石にまずい → スタック化で端子の向きが同一になり、まとめやすくなったので結束バンドで。</dd>
<dt>HDMIケーブル/キーボード・マウス用USBケーブルの配線</dt>
<dd>SSH アクセスが前提なので不要。挙動がおかしい奴を再起動する時だけ挿せば良い</dd>
<dt>消費電力/発熱</dt>
<dd>目をつぶるしかない</dd>
<dt>電源関連</dt>
<dd>1枚のラズパイに1個のUSB-AC アダプタなんてどう考えても無理。→いいのがあった</dd></dl>
![68747470733a2f2f696d616765732d6e612e73736c2d696d616765732d616d617a6f6e2e636f6d2f696d616765732f492f3631253242664574326b36424c2e5f41435f534c313030305f2e6a7067.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267238/c227b8d2-fba8-176d-4b28-de0e9dda552c.jpeg)


ここまではオマケでして、本題はここから。

## 問題その1: microSD メディア/OS管理の問題

- ダメになった microSD (死骸)の枚数も多くなる。完全に消耗品。
- 空き容量とか OS のバージョンとか個別に microSD を管理することは超面倒
- **(ふと我に返る)1枚1枚 OSアップデートするのは馬鹿じゃね?**



## 問題?その2: 複数枚持っている人間ならではの好奇心
うっかり、以下のどれかを作ってみたくなりますよね・・・

- HPC(MPI)のクラスタを組んでプライベート貧弱スパコン
- kubernetes 等でPaaS/SaaS向けプライベート貧弱クラウド
- 分散コンパイル環境

**でも、同一内容で多数の microSD をコピーしまくるのは時間の無駄では?**


## 上記の問題1,2を一発で解決する方法は・・・

**ラズパイをディスクレスクライアント化/ネットワークブート化する以外無い**訳でして・・・
ディスクレスクライアント/ネットワークブートに関してまとめてみたのが本稿ということになります。

# 歴代ラズパイのディスクレス化への長い道のり

## Step1:「PiServer」の存在を知る

まず最初に、[日経のこの記事](https://xtech.nikkei.com/atcl/nxt/column/18/00079/00004/) を見つけたわけですよ。
「余剰 PC なり VMWare 仮想ホストにこいつをインストールすれば一発じゃね? 楽勝」って思いますよね。普通。

## Step2: PiServer を試す
<dl>
<dt>1. インストール中</dt>
   <dd>あー、カーネルは x86_64 なのに glibc が 32bit i386 の Debian なのね・・・</dd>
<dt>2. クライアントに配布するOSの管理画面</dt>
<dd>Raspbian 以外のディストリビューションの登録は超面倒くさいぞ。どうやら自分で boot.tar.xz と root.tar.xz を作る必要がある感じだな。</dd>
<dt>3. クライアントに配布するOSの設定・更新</dt>
<dd>クライアント向けOSのアップデートは PiServer 上の qemu-arm-static で行うのね。
あ、そういえば 32bit版 glibc だから aarch64 版ディストリビューションはアップデートできねーじゃねーか。</dd>
<dt>4. 実際に microSD を抜いた状態で各機に電源投入</dt>
<dd>あれ? 3B+ 以外のクライアントを全く発見できないぞ? DHCP のブロードキャストを投げてないの? (この現象の理由は後に述べる)</dd>
</dl>

この段階で、**PiServer は全体としてクソ**。という暫定的な判断を下し、
あとで PiServer の機能を解析して、他の実現方法がないか考えてみよう、とメモ。

## Step3: 一瞬だけローカルにインストールした U-boot でどうにかならないか考える

「ローカルの microSD の第1パーテーションに U-boot を入れて、tftp サーバに置いてNFSマウント」という記事も結構出て来たので一瞬だけ考えて試してみたものの、
モデルによって SoC が違うから U-boot をコンパイル+イメージ生成する回数が増えて面倒すぎる・・・何よりディスクレスを目指しているんだから本末転倒じゃん、と気づいて最終的に却下。U-boot 使うなら tftp サーバに置いたやつでしょ、と。

## Step4: モデルによってPXEブート実現可能化への方法が異なることを知る

Google で「Raspberry PI ネットワークブート」 で検索してみるといろいろな方法が出てきますけれど・・・

電源投入直後のブートシーケンス内で、microSD が挿入されていない際、PXE ブートに挑戦するかしないか、というの最終判断結果はモデル(発売時期)によって全く異なるということ、しかも PXE ブートに挑戦するように挙動を変更するための準備方法もモデルによって全く違う、ということにやっと気づいたわけですよ。

## Step5: 各モデルのサマリとそれぞれ準備(2020/06/02時点での方法)

### Raspberry PI 2 Model B (V1.1,V1.2)
<dl>
<dt>発売時期</dt>
<dd>2015/02 発売の無印(V1.1)は 32bit armv7。</dd>
<dd>2016/07 マイナーチェンジ(V1.2)後は 64bit armv8</dd>
<dt>完全ディスクレスは不可能</dt>
<dd>ネットワークブートなんて一切考えていなかった時期に発表されたモデルなので、完全なディスクレスクライアント化には対応していない。</dd>
<dt>ネットブート化への方法</dt>
<dd>元来対応していないモデルだったものの、現在は中の人たちが頑張って、Raspberry PI OS(旧名 Raspbian) のブートパーテーションに含まれる bootcode.bin ファイルが
microSD の第1パーテーションに存在すればネットワークブートが可能、という状況にまで改善されている。
よって、Raspbian のイメージから bootcode.bin をコピーした microSD を挿して起動する必要がある。</dd>
</dl>
[参考(Qiita)](https://qiita.com/ysugi/items/ee88eed56e0234028228)

### Raspberry PI 3 Model B(無印)
<dl>
<dt>発売時期</dt>
<dd>2016/03</dd>
<dt>購入後、1度だけ実行しなければならないコマンドがある。</dt>
<dd>デフォルト状態のままではネットワーク/USBブートに対応していないが、1回だけ Raspbian のブートパーテーションにある cmdline.txt ファイルを変更して再起動するとファームウェアのフラグが変更されて、ディスクレスブートが対応可能となる。</dd>
<dt>実際に行う作業</dt>
<dd>本家チュートリアルを参考にしてください。</dd>
</dl>
[参考(本家チュートリアル,英語)](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/net_tutorial.md)

### Raspberry PI 3 Model B+
<dl>
<dt>発売時期</dt>
<dd>2018/03</dd>
<dt>何もしないでもディスクレス化可能</dt>
<dd>2020/06/01 現在、最もディスクレスクライアント化が簡単なモデル。それで PiServer はこいつを見つけたわけだ</dd>
</dl>

### Raspberry PI 4
<dl>
<dt>発売時期</dt>
<dd>2019/06</dd>
<dt>購入後、やはり1度だけ実行しなければならないコマンドが(後戻りかよ)</dt>
<dd>3B系までの起動シーケンスとは設計が全く異なるものになり、
3B系までの起動時に必要だった bootcode.bin に相当するプログラムがオンボードのEEPROMに格納されるようになったモデル。
本来なら何もしなくてもディスクレス化が実現可能なはずなのに、初期状態では microSD での起動に失敗したら
全てを諦めてしまう状態で出荷されている不親切なモデル。</dd>
<dt>実際にやるべきこと</dt>
<dd>下記リンクがうまくまとめられていますので参考にしてください。
</dd>
</dl>
[参考(あっきい日誌)](https://akkiesoft.hatenablog.jp/entry/20200506/1588750846)

## Step6 改めて PiServer で Raspbian (32bit) の PXE ブートを確認
やっと手持ちの全モデルで PXE ブートが実行できた。
そしてクソ(仮の判断)な PiServer をどうやってリプレースするか、という次の段階へ

というわけで、今回はここまで。[その2](https://qiita.com/p_cub/items/69fa32a9a62890ca1d04) へと続きます。