1. 概要
巷ではoverlayfsなrootを利用した環境構築が流行っているものの、
NBD Rootを利用した構成がほとんど見つからないことからやってみました。
2. 構成
ハードウエア
- Raspberry Pi 3 Model B
- microSD 2GB
- 有線ネットワーク環境
-
ReadyNAS DUOv2
- そろそろNASを更改しなければ…
- 母艦(Mac)
ソフトウエア
Raspberry Pi
- HypriotOS aarch64
- ここのを使う。
NAS
- NBD Server
2. ディスク構成
- SDカード /boot
- FAT32
- NBD Root /
- 8GB
- btrfs
- lzo圧縮を使いたいのでbtrfsにした。
- NBD Swap
- 2GB
- 実際こんなにいらない。
- 2GB
- Zram
- 2.5GB
- memlimit 800MB
3. 実施作業
Macで作業
SD書き込みツールのダウンロード&必要なパッケージのインストール
$ brew install pv
$ brew install awscli
$ curl -O https://raw.githubusercontent.com/hypriot/flash/master/flash
$ chmod a+x ./flash
イメージの書き込み
ここを確認して最新のイメージを書き込む
[Releases · DieterReuter/image-builder-rpi64 · GitHub](https://
github.com/DieterReuter/image-builder-rpi64/releases/)
$ ./flash --hostname raspi -d /dev/disk2 https://github.com/DieterReuter/image-builder-rpi64/releases/download/v20180429-184538/hypriotos-rpi64-v20180429-184538.img.zip
不要ファイルの削除
$ rm flash
NAS作業
Rootの作成
NBDの設定ファイルを作成
[raspi-root]
exportname = /c/nbd/raspi-root.img
copyonwrite = false
空ファイルの作成
# truncate -s 8G /c/nbd/raspi-root.img
# chown nbd: /c/nbd/raspi-root.img
ここでフォーマットしてもよいが、btrfsを使うため、実機作業とする。
Swapスペースの作成
[swap]
exportname = /c/nbd/swap/%s.img
copyonwrite = false
virtstyle = ipliteral
prerun = /etc/nbd-server/create_sparse_swap.sh %s 2G
postrun = rm -f %s
# !/bin/sh
if [ ! -e $1 ]; then
logger -t nbd "create sparse file: $1"
truncate -s $2 $1
fi
# !/bin/sh
/etc/nbd-server/create_sparse.sh $1 $2
mkswap -f $1
ディレクトリ作成
# mkdir /c/nbd/swap
# chown nbd: /c/nbd/swap
再起動
NBDサーバの再起動
# /etc/init.d/nbd-server force-reload
実機作業
SSH接続
実機にSDカードを差し込みブートする
母艦よりSSHで接続
$ ssh pirate@raspi.local
$ sudo -s
パスワードは"hypriot"
NBD接続
# apt-get update
# apt-get upgrade
# apt-get install nbd-client
# modprobe nbd
# nbd-client -N raspi-root 192.168.102.21 /dev/nbd0 -p
3.15以前のnbd-serverに3.16または3.17のnbd-clientは接続できないので要注意
3.18ではオプション指定でできるようになるらしい。
NBDディスクのフォーマット
# apt-get install btrfs-progs
# mkfs.btrfs /dev/nbd0
# mount -o rw,noatime,discard,compress=lzo /dev/nbd0 /mnt
ディスクイメージからrootfsの作成
debootstrapでやってもいいが、面倒なのでディスクイメージをダウンロードして、
ローカルでマウントし、コピーすることにする。
# cd /mnt
# apt-get install unzip
# wget https://github.com/DieterReuter/image-builder-rpi64/releases/download/v20180429-184538/hypriotos-rpi64-v20180429-184538.img.zip
# unzip hypriotos-rpi64-v20180429-184538.img.zip
# rm hypriotos-rpi64-v20180429-184538.img.zip
# losetup -P --show -f ./hypriotos-rpi64-v20180429-184538.img
# mount /dev/loop0p2 /media
# tar cf - -C /media . | tar xfp -
# umount /media
# losetup -d /dev/loop0
# rm hypriotos-rpi64-v20180429-184538.img
chroot
# mount --bind /dev /mnt/dev
# mount -t tmpfs tmpfs /mnt/dev/shm
# mount -t tmpfs tmpfs /mnt/run
# mount -t proc proc /mnt/proc
# mount -t sysfs sysfs /mnt/sys
# mount -t devpts devpts /mnt/dev/pts
# mount --bind /boot /mnt/boot
# cp /etc/hostname /mnt/etc/
# cp /etc/hosts /mnt/etc/
# mkdir -p /mnt/run/systemd/resolve/
# cp /run/systemd/resolve/resolv.conf /mnt/run/systemd/resolve/
# chroot /mnt
パッケージのインストール
# apt-get update
# apt-get upgrade
# apt-get install nbd-client btrfs-progs initramfs-tools
nbd-clientはPinningしておくことにする。
Package: nbd-client
Pin: version 3.15.*
Pin-Priority: 1001
初期設定
タイムゾーン変更
# dpkg-reconfigure tzdata
Asia/Tokyoを選択
ユーザの作成
# adduser [ユーザ名]
パスワードなど答えてユーザを作成
sudoグループにいま作成したユーザを追加
# addgroup [ユーザ名] sudo
SSHキーの追加
# su [ユーザ名]
$ cd
$ mkdir .ssh
$ chmod 700 .ssh
$ vi .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys
$ exit
fstabの修正
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat ro,relatime,fmask=0022,dmask=0022 0 0
/dev/nbd0 / btrfs rw,relatime,discard,compress=lzo 0 0
cloud-initの削除
# apt-get purge cloud-init
# apt-get autoremove --purge
# systemctl mask hypriot-firstboot
initramfsの作成
# mkinitramfs -o /boot/initrd.img
# echo initramfs initrd.img >> /boot/config.txt
カーネル起動パラメータの修正
dwc_otg.lpm_enable=0 console=tty1 nbdroot=192.168.102.21,raspi-root,nbd0 root=/dev/nbd0 ip=dhcp rootfstype=btrfs cgroup_enable=cpuset cgroup_enable=memory swapaccount=1 elevator=deadline fsck.repair=yes rootwait console=ttyAMA0,115200 net.ifnames=0
再起動
# exit
# reboot
再起動したらもう一度sshで接続
ロケールの変更
# dpkg-reconfigure locales
ja_JP.UTF-8を選択
再起動時フリーズの対策
# vi /lib/systemd/system/ifup@.service
# vi /lib/systemd/system/systemd-networkd.service
# vi /lib/systemd/system/networking.service
[Unit]のBefore,Conflictsからshutdown.targetを消す
# systemctl daemon-reload
書くのは楽だけれどもものすごく嵌った
watchdogの変更
ここと同じ
Raspberry Pi 3/ Zero / Zero W等で watchdogを有効化する - Qiita
dtparam=watchdog=on
options bcm2835_wdt heartbeat=10 nowayout=0
RuntimeWatchdogSec=5
zramの有効化
パッケージがなくなった?ので自作
[Unit]
Description=Zram swap
[Service]
Type=oneshot
ExecStart=/usr/local/bin/systemd-zram-start
ExecStop=/usr/local/bin/systemd-zram-stop
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
# !/bin/sh
modprobe zram
echo 2560M > /sys/block/zram0/disksize
mkswap /dev/zram0
swapon /dev/zram0 -p 16383
echo 800M > /sys/block/zram0/mem_limit
# !/bin/sh
swapoff /dev/zram0
modprobe -r zram
# chmod a+x /usr/local/bin/systemd-zram-st*
# systemctl daemon-reload
# systemctl enable zram
NBD Swapの有効化
# echo "nbd1 192.168.102.21 swap persist,swap" >> /etc/nbdtab
NBD Rootによってnbdモジュールは有効化されていることから、
systemdに制御が移った時にはnbdデバイスが存在するため、
Before=dev-%i.deviceおよびRequiredBy=dev-%i.deviceは動かないので、
nbd@.serviceを編集する。
# vi /lib/systemd/system/nbd\@.service
[Unit] のBefore=dev-%i.device
をBefore=swap.target
に変更、
[Install] のRequiredBy=dev-%i.device
をWantedBy=sysinit.target
に変更
# systemctl daemon-reload
# systemctl enable nbd@nbd1
fstabの修正
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat ro,relatime,fmask=0022,dmask=0022 0 0
/dev/nbd0 / btrfs rw,relatime,discard,compress=lzo 0 0
/dev/nbd1 swap swap defaults 0 0
sshd.serviceの修正
/etc/init/ssh.confにはmkdir -p -m0755 /run/sshd
があるのに、
/lib/systemd/system/ssh.serviceには存在しないので、
ExecStartPre=/bin/mkdir -p -m0755 /run/sshd
を既存のExecStartPreの前に追加する。
4.最後に
NBD Rootはあまりないのか、ハマりポイントが多い。
うまくいかない場合は、ネットワークとディスクの起動順序を見直すと良いようだ。