Raspberry Pi等、LinuxをmicroSDにインストールして使用する場合に電源断等でファイルシステムが壊れることはよくあります。
Raspberry Pi OSは raspi-confg
でファイルシステムのROM化が出来ますが、パッケージのアップデートが面倒だったりします。
もっと良い方法が無いかと探していたところ、Alpine Linuxのディスクレスモードが永続化も行いやすく使い勝手が良さそうでした。
Raspberry PiでAlpine Linuxを使う方法は検索するといくつか出てきますが、挙動を詳細に把握したかったこととx86_64でも使いたかったのでベアメタル環境へのインストールを試してみました。
前置き 🔗
色々と作業をしますが、最も単純な方法としてはUSBブートやPXEブートして setup-lbu
でapkovlの保存先を設定して lbu commit
すれば良い。
今回はUSBブートして更に別のストレージにインストールするという他のディストリビューションと似たことをします。
インストール 🔗
DHCPでIPを設定する 🔗
起動時にIPが割り当てられていないことがあったのでDHCPでIPを取得する。
dhclientは無く、udhcpcで設定します。
ip link set eth0 up
udhcpc -i eth0
静的IPを設定する 🔗
DHCPを使わない場合はiproute2で設定する。
ip link set eth0 up
ip addr add 192.168.11.20/24 dev eth0
ip route add default 192.168.11.1
echo 'nameserver 192.168.11.1' > /etc/resolv.conf
apkのリポジトリを設定する 🔗
setup-apkreposを使用します。
引数無しでミラーサーバーを選ぶか、引数にミラーサーバーのURLを渡してあげます。
setup-apkrepos
# or
# setup-apkrepos http://dl-cdn.alpinelinux.org/alpine/v3.18/main
インストール中に使うパッケージを追加 🔗
素のAlpine Linuxにはパーティショニングやフォーマットを行うツールが入っていないので追加します。
apk update
apk add parted mount dosfstools e2fsprogs
パーティションの作成 🔗
EFI System Partitionを約1GB、永続化パーティションを残りの領域に設定しています。
永続化パーティションもそんなにサイズは必要ないので100%
の部分はよしなに。
parted --script /dev/sda mklabel gpt
parted --script --align=optimal /dev/sda mkpart ESP fat32 1M 1G
parted --script --align=optimal /dev/sda mkpart primary ext4 1G 100%
parted --script /dev/sda set 1 boot on
パーティションをフォーマット 🔗
mkfs.vfat -F32 /dev/sda1
mkfs.ext4 /dev/sda2
ブートローダーとベースイメージのインストール 🔗
このコマンドを実行することで、/dev/sda1にカーネルとinitramfs、EFIブートローダー、最小限のapkがインストールされる。
setup-bootable https://dl-cdn.alpinelinux.org/alpine/v3.18/releases/x86_64/alpine-extended-3.18.2-x86_64.iso /dev/sda1
マウント 🔗
永続化用のパーティションをマウントします。
これを事前に行っていないと、setup-alpine
(setup-lbu
)で永続化先として出てきません。
mkdir /media/sda2
mount /dev/sda2 /media/sda2
初期セットアップの実行 🔗
setup-alpine
を実行する。
setup-alpine
やっていることは、Alpine setup scriptsを順番に実行しているだけなので、部分的に修正したい場合などは該当するコマンドを実行すると良い。
セットアップの永続化 🔗
lbu commit -d
詳細はAlpine local backupを参照。
ディスクレス運用なので、再起動すると設定がリセットされてしまう。
変更を保存する場合は都度lbu commit
を実行する。
再起動 🔗
reboot
まとめ 🔗
Alpine LinuxをDockerイメージを作る際に使うことはあってもベアメタル環境で使うことはあまり無いと思います。
ですが、シンプルでポータビリティなため意外と使えるシーンがありそうです。
これでルーター等を作る際にROM化が簡単に出来ますね。
ハマったところ 🔗
起動時にサービスが実行されない 🔗
apkをインストールしただけではデフォルトでは実行されないため、rc-update
で起動時に実行されるよう設定します。
apk add nftables
rc-update add nftables
すでにapkovl.tar.gzが存在するパーティションがある場合、インストール時にアンマウント出来ない 🔗
Alpine Linuxはマウント可能なパーティションからapkovl.tar.gzを探してきて利用するようで、再インストールの際などにapkovl.tar.gzを含むパーティションをアンマウント出来ずに困ることがあります。
その際はカーネルオプションを変更することでアンマウント可能になります。
ブートローダーが表示されたタイミングで、e
を押して編集モードに入ります。
カーネルオプションのmodulesから、sd-modとusb-storageを削除します。
linux /boot/vmlinuz-lts modules=loop,squashfs,sd-mod,usb-storage quiet
↓
linux /boot/vmlinuz-lts modules=loop,squashfs quiet
Ctrl-x
を押してブートします。
パーティションがマウントされapkovl.tar.gzがロードされた状態と同じになりますが、umount /dev/sda?
でアンマウント可能になっているはずです。