RaspberryPiで「alpinelinux」

144Labの入江田です。

最近、RaspberriPiを筆頭にLinuxが動作可能な安価なデバイスが増えてきました。 しかし、LinuxディストリをSDカード上でちゃんと運用するためには それなりの調整が必要です。

何も考えずにPCディストリをSDカードに入れた場合、 毎日のようにパッケージ更新をチェックし システムログをSDカードに細かく頻繁に書き込み続けます。 設定によりますが半年~1年ほど経てば 細かい高頻度の書き込みと断片化、寿命による性能劣化が急速に進みます。 運用寿命を数年以上に引き上げるためにはとにかくSDカードへの書き込み頻度を減らすことが重要です。

そこで組み込み用途向けディストリというものがあります。

もちろん「Raspbian」もその一つです。 超有名どころとしてはルーター用ディストリとして発展した「OpenWRT」がありますが、 ここでは「alpinelinux」をお勧めします。

なぜalpinelinux?

RaspbianはPC向けDebianをほんの少し組み込み用途向けに調整してある程度です。 パッケージの自動更新を止めログをtmpfs(オンメモリFS)に向けたくらい?

OpenWRTはLiveCDと同じ技術でSDカードへの書き込みを減らします。 しかしそれぞれ触ったことがあれば歴然なほど体感できますが、 alpinelinuxは「依存解決がほんと簡単」だし、 「ソースからビルドが必要になることがほんとに少ない」のです。

  • alpinelinuxはdockerの基礎イメージとしての採用で利用者が急増中
  • 公式にRaspberryPi対応イメージを配布している
  • イメージが80MB程度なのでセットアップが短時間で済む
  • PC向けとほぼ同じレベルの新しいパッケージがそろっている
  • 組み込み運用に向くディスクレスモードを持っている
  • docker上で互換環境がすぐ構築できPC上でアプリの開発とテストができる

ディスクレスモードって?

極限までディスク書き込みを減らしつつ、パッケージの更新も可能にする仕組み。 運用のイメージは「docker commit」のような感じ。

  • 起動パーティションはリードオンリーで扱う
  • オーバーレイFSは起動パーティションと後述のアーカイブとtmpfsの内容を重ねて読めるようにしつつ
  • 書き込みの記録先はtmpfs(オンメモリFS)
  • そのオーバーレイFSを「/(ルート)」にマウントして起動する仕組み
  • 「lbu commit」コマンドでtmpfsの内容をアーカイブにして永続化する
  • 永続化しなかったままリブートするとtmpfsは空になってその間の操作はなかったことになる
  • commitは設定回数分巻き戻すことができる。
  • よほどのことがないと起動パーティションは壊れない(書き換えようとするプロセスが居ない)
  • 機器の電源断やCPUの誤動作程度ではほぼほぼ起動パーティションの破壊はおこりません

Alpineイメージ

https://alpinelinux.org/downloads/

  • armhf用のイメージがZero-Wで使える。
  • aarch64用は現状RaspberryPi3でのみ使える。

MicroSDカードの作り方

  1. パーティションでFAT+MBRなフォーマットを行う
  2. PCにマウントして上記のイメージを解凍したファイル群を書きこむ。

場合によって以下のカスタム調整を加えます。

Non-FreeなBroadcomファームウェアのインストール方法

RaspberryPiのWi-Fi機能はBroadcom製のチップなので それを利用する場合はそのファームウェアが必要です。

alpine-3.7以前

https://github.com/RPi-Distro/firmware-nonfree ここより以下のファイルを入手して ブートイメージの「/firmware/brcm」フォルダ配下に入れておく。

  • brcmfmac43430-sdio.bin
  • brcmfmac43430-sdio.txt

alpine-3.8以降

3.8からは上記の処理をやっちゃダメ。 (やってしまった場合、rootfsの/lib/firmware/bcrmにコピーされてしまうのでそこの削除も必要になる) 以下の手続きをsetup-interfaces、setup-apkrepos後に行う感じ。

  • なんとかオンライン環境にする(USB-NIC等)
  • apk add linux-firmware-brcm

setup-alpine

setup-alpineは以下のサブコマンドを順に呼ぶラッパーになってる。 👈 重要なところが正常に処理されないとメンテ不能なので要注意。

  • setup-keymap
  • setup-hostname
  • setup-interfaces 👈 重要
  • setup-dns
  • setup-timezone
  • setup-proxy
  • setup-apkrepos 👈 重要
  • setup-sshd 👈 重要
  • setup-ntp
  • setup-disk (追加ドライブなければスキップ)
  • setup-lbu 👈 重要
  • setup-apkcache

setup-interfaces

NICの設定(/etc/network/interfaces)を生成するスクリプト。 うまくいくと接続を試みる。

setup-apkrepos

パッケージマネージャのリポジトリ設定。 mirrorsリストが表示されるが基本1番でOK。 デフォルトはfでこれを指定するとfastestなミラーを探すが、 安定性を考慮してくれない上に時間がかかる。 うまくいくとカタログが更新される。

setup-sshd

openssh or dropbear のsshデーモンを選択すると、 うまくいくと自動起動するようにセットアップしてくれます。

setup-lbu

永続化の領域を設定する。 デフォルト値: mmcblk0p1 にて設定がおすすめ。 うまくいくとlbu commitにて変更を永続化できるようになる。 (逆にlbu commitしていない変更はすべて破棄される)

よく使うサービスのセットアップ

  • rc-update add wpa_supplicant boot 👈 重要
  • apk add avahi
  • rc-update add dbus
  • rc-update add avahi-daemon

wpa_supplicantサービスはNICとか使って最初にセットアップすると、 起動設定されない場合があります。 起動設定になってない場合、上記の操作で起動するようにしておくことが大切。 (boot指定なのはnetworkingよりも先に起動している必要があるため)

lbuの注意点

  • くれぐれも変更は「lbu commit」で永続化するのを忘れずに。
  • 「/home」配下は常にlbuの管理下に入ります。
  • 「/root」配下はlbu管理下ではないので適時「lbu add ファイルパス」で管理下に加える必要があります。

感想

3.8になってNonFreeなパッケージから切り出したファームをリポジトリで管理してくれるようになったのはより良い傾向なんですが、 若干セットアップフローに問題が残っています。 mirrorsの情報供給ホストのサーバー証明書の有効期限切れなどもあり、 素直にセットアップできないのが現状のようです。 まぁ、しばらくすれば修正はされるとは思います。

追記

SDカードFSの書き換え

自分自身でconfig.txt等の修正をしたい場合など。

  • mount -o remount,rw /dev/mmcblk0p1
  • /media/mmcblk0p1が読み書き可能になる

i2cバス有効化

  • config.txtに「dtparam=i2c_arm=on」を追記。
  • rootfsの/etc/modulesに「i2c-dev」を追記。

Wi-Fiが不安定

Wi-Fiモジュールがパワー節約設定になっているのが原因。

  • 「/etc/modprobe.d/8192cu.conf」に以下の内容を記述。
# disable power saving
options 8192cu rtw_power_mgnt=0 rtw_enusbss=1 rtw_ips_mode=1

alpine3.8.1リリース

TODO: セットアップフローに改善があれば説明を修正する