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カードの作り方
場合によって以下のカスタム調整を加えます。
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後に行う感じ。
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していない変更はすべて破棄される)
よく使うサービスのセットアップ
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: セットアップフローに改善があれば説明を修正する