Raspberry Piクラスタを作る #1 - 準備

半年に一度くらい思い出したようにDockerを触っていて、やれCoreOSだ、やれrktだApache Mesosだとソフトウェアスタックがややこしいのにうんざりしていたのだけれど、とりあえずKubernetesを起点としてその関連の技術を学んでいけば間違いがなかろうという天啓を得たので『Docker/Kubernetes 実践コンテナ開発入門』を読んだところ、これが大変に面白かった。Kubernetesを個人で勉強するのであればGoogle Container Engine (GKE)でクラスタ環境を作るのが手軽なようなのだけど、せっかくだし分散コンピューティングの基礎的なアルゴリズムも学びたいという欲も出てきたりして、自宅でRaspberry Piクラスタを組むことにした。

Raspberry Piでクラスタを組むことについていえば結構先人がいて、YouTubeには制作動画が色々ある

部品

Raspberry Pi 3 Model B+

いわずと知れたシングルボードコンピュータ (SBC)の代表的な製品。演算性能だけ考えたときのコストパフォーマンスは2018年現在でそこまで抜きん出たものではないようで、競合製品との比較記事なんかでは韓国HardkernelのODROIDシリーズがドライバサポートなどの観点から勧められていたりする。最初から4台で構成されたクラスタとして販売されているODROID-MC1なんかは結構魅力的だったのだけれど、今回は余計なトラブルを避けるべくリファレンスマシンたるRaspberry Piのエコシステムに乗ることにした。その意味で欲を言えば本当はARMではなくx86のSBCが良かったけど、Up BoardLattePandaは4台買うにはちょっと高い。

Raspberry Piで基本的には問題ないのだけど、Gigabit Ethernet搭載といいつつ、内部バスがUSB 2.0のため最大速度が220Mbps前後なのだけはちょっと気になった。

Raspberry Pi用ヒートシンク

あまりCPU温度が上がるとクロック周波数が下げられるとのことなので一応購入。両面テープで貼るタイプのヒートシンクって、そもそも両面テープ自体の熱伝導性はどうなんだとか疑ってたけど、3Mが熱伝導性両面テープというものを売っているのを見つけて、そういうのもあるんだなと。今回買ったこのヒートシンクがそれを使っているかはわからない。

Multi-Pi Stackable Raspberry Pi Case

Raspberry Pi専用っぽいアクリル板を使って縦に積んでいるクラスタ制作事例をよく見かけるものの、このアクリル板がどこで買えるのかが意外とわからない。海外の制作事例で推薦されていたイギリスのModMyPiというショップのアクリル板を買ったのだけれど、たかだかアクリル板にそこそこ値段がする(2セット + 別売りのボルトセットで送料込み47ドル)なと思っていたら、注文を確定させた直後にAmazon.co.jpで超安い積層式ケースを普通に見つけた。なぜこれを見落としたのか自分でも分からないけど、ともかく異国情緒あふれるアクリル板(海外のダンボールってなんであんなに臭いんだろう)を使うことになった。

Raspberry Piクラスタの部品写真

Anker PowerPort 6

Raspberry Pi 3 Model B+はそこそこ電力を食うらしく、電源・ケーブルにしっかりしたものを使って5V/2.5A供給しないと不安定になるかもしれないという情報があり、ちょっと悩んだ (スイッチサイエンスの人が検証もしている)。TDKラムダとかの武骨なスイッチング電源買って使うのも面白いなとか、米BitScope社のQuattro Piとか面白そうとか思ったけど、電源周りで冒険して火事にでもなったら嫌だなと思い直し無難にUSB電源で給電することにした。たまたまPower over Ethernetに対応したネットワークスイッチが家にあったので、PoE給電も気になったけどRaspberry Pi対応のPoEボードが意外と高価だったり在庫状況が謎だったりしたので見送り。

SanDisk Ultra Fit USB 3.1 Memory Stick

Raspberry Piの標準的なストレージデバイスはmicroSDカードで、普通はそこにOSも入れるのだけど、microSDカードがストレージというのがどうにも気持ち悪くUSBフラッシュドライブをストレージにしたかった (どっちもどっちという気はする)。そのような理由で速度面で評判の良いこのUSBフラッシュドライブを買ったのだけど、結果的にその後OSのブートイメージを自分でビルドするはめになったので、変にこだわらずランダムアクセス性能が良いとされているApplication Performance Classに対応したmicroSDカードを選ぶのが無難だったと思う。でも買ってしまったものはしょうがない、当面はUSBフラッシュドライブでがんばる。

Quimat 3.5インチタッチスクリーン

別に必要はなかったのだけどRaspberry Pi で使えるポータブルモニタの決定版と紹介されている記事を見て欲しくなってしまったので購入。これを書いている時点で画面は映るもののタッチスクリーンは有効化できていない。

USBシリアル変換ケーブル

前述の通り素直にmicroSDカードをストレージに採用せずUSBフラッシュドライブをストレージを使ったばかりにOSが起動しないという事態に遭遇し、ブートシーケンスのデバッグ用に購入。USBシリアル変換ケーブルは積んでいるチップによって値段にかなり差がある。Windows 10に対応していてかつ比較的値段がリーズナブルな米adafruit社製のものを購入。

Raspberry Piクラスタの写真

Anker PowerLine Micro USB ケーブル

Raspberry Piへの電源供給用。カラフルなMicro USBケーブルを使っている海外の制作事例があって見た目が素敵なんだけど、どこで売ってるのか謎だったので、とりあえず安くて品質が安定してそうなAnker製にした。でもやっぱり本当はカラフルなケーブルにしたい。

エレコム ツメ折れ防止短尺LANケーブル

こっちも本当はカラフルなケーブルにしたかった。

NETGEAR GS108PE

家にたまたまあったネットワークスイッチ。NETGEAR製品はデザインが好きなんだけど、この機種はWindowsだけで動く専用アプリケーションじゃないと設定変更できないのがつらい。Webベースの設定画面が欲しい。

Movidius Neural Compute Stick

当初の目的から考えると明らかに不要なんだけど、画像認識とかやりたくなるんじゃないかという予感と今買わないとすぐ終売になるのではという恐怖感から購入。使いみちは後から考える。

Logicool C270 HD Webcam

前述の画像認識とかやりたくなるんじゃないかという予感にもとづいて購入。その後コンピュータビジョン系のタスクには2008年に発売されたPlayStation Eyeが適しているという話を見つけ、中古で1000円せず買えるのでちょっと気になっている。ちなみにガチの人は米FLIR社に買収されたカナダのPoint Grey社のカメラとか使うらしい。

OSの選定と準備

Raspberry PiのオフィシャルOSたるRaspbianを入れておけばだいたいOKのようなんだけど、Kubernetesを動かしたいならHypriotOSが良いという話を聞きつけ採用することにした。俺たち海賊だぜ反体制だぜウェーイみたいな雰囲気のWebサイトのわりにはコアメンバーがナイスミドル揃いなのが良い。ドイツでユーザーコミュニティがあるようで、なんとなく海賊党を想起するなどした。以下公式Webサイトで見つけた特徴を列挙すると

  • OSの設定がcloud-initで書ける
  • LinuxカーネルをDocker用にチューニングしている (inodeの最大値増やしたりしているらしい)
  • 比較的最新のDockerをプリインストールしている
  • Avahi/Bonjourサーバーをプリインストールしている
  • SSHサーバーをプリインストールしている
  • Portainerをプリインストールしている

ということでARMデバイス上でDockerを動かす目的に最適化されたOSという触れ込みになっている。

ブートイメージをUSBフラッシュドライブに書き込むのにはEtcherを使った。別に何を使っても良いのだろうけど、これはUIがシンプルかつモダンな感じで良い。

OS導入

組み立てについては大して問題もなかったので省略。

個人的な好みとしてまずは何もストレージをつけずに起動してBIOS設定画面が見たい。というわけでOSの入ったUSBフラッシュドライブを接続せずに通電したところHDMIケーブルで繋いだ外部モニタに何もうつらない。Raspberry Piの初期不良を掴んだかと思い、別の本体に外部モニタを接続するもやはり何もうつらない。ダメ元でOSの入ったUSBフラッシュドライブを刺すも何も起こらず。もうだめだ。俺にKubernetesは早すぎたんだ。

起動しない原因1

そもそもRaspberry Piで使われているBroadcomのSoCにBIOS/UEFIなんてものは使われていない。よって普通の意味でのBIOS設定画面なんてものもなかった。Raspberry PiはOSがないと少なくとも画面表示に関しては何もしないのだった。ちなみにブートプロセスについてはユーザフォーラムのRaspberry Pi boot processというトピックで解説されていて、GPUが先に起動してブートローダをキックするとのこと。

とりあえずHypriotOSの入ったUSBフラッシュドライブを刺して電源を入れ直したら、Linuxのブート画面のようなものがちょっと出て…エラーを吐いてフリーズした。

起動しない原因2

ただ、Raspberry Pi 3 Model B+はUSB Mass Storage Device(ここではUSBフラッシュドライブのこと)からのブートに標準で対応しているはずなので、OSの入ったUSBフラッシュドライブを刺せばちゃんと起動しても良かったはずである。なぜエラーを吐いてフリーズしたのか。しばらく悩んだ末、USBフラッシュにHypriotOSではなく標準的OSのRaspbianを入れて起動を試みたところ、あっさり起動した。どうやらRaspberry Piのファームウェア的にははUSBフラッシュドライブからの起動に対応しているのに、HypriotOSがUSBフラッシュドライブからの起動を考慮していないらしく、/etc/fstabでSDカード決め打ちのデバイス名/dev/mmcblk0を使っているらしい。解決策がGitHubのIssueにあったので、この情報にしたがって自分でブートイメージを作り直したら無事に起動した。

USB Mass Storage Deviceに対応したブートイメージ

topコマンドでプロセスごとのCPU使用率を見てみたらkworkerが9~10%程度使っている。気持ち悪いのでperfコマンドをインストールして原因を調べてみる。

$ sudo apt update
$ sudo apt install linux-tools
$ ls /usr/bin/perf_*
/usr/bin/perf_4.9

$ sudo /usr/bin/perf_4.9 record -g -a sleep 10
$ sudo /usr/bin/perf_4.9 report

時間食ってるのは以下の処理。

Children      Self  Command          Shared Object       Symbol
7.50%     3.69%  kworker/0:1      [kernel.kallsyms]   [k] arch_timer_read_counter_long
4.69%     4.67%  kworker/0:1      [kernel.kallsyms]   [k] arch_counter_get_cntpct
4.03%     4.03%  kworker/0:1      [kernel.kallsyms]   [k] _raw_spin_unlock_irqrestore
3.53%     3.49%  kworker/0:1      [kernel.kallsyms]   [k] finish_task_switch

更に深掘りしてみるとmmc_rescanあたりが怪しく、SDカードなしで起動しているとSDカードをスキャンしまくってCPUを食うという話も見つけた。本当USBフラッシュドライブブートなんてするもんじゃないな。sdtweak.dtboをダウンロードして/boot/overlays/配下に置き、/boot/config.txtの末尾に以下の一行を追加することで解決した。ちなみに同名ファイルsdtweak.dtboがすでに存在したけど、こいつだとダメみたいで、ダウンロードしたやつで置換しないと動かなかった。なんでだ。

dtoverlay=sdtweak,poll_once