LoginSignup
1
0

More than 5 years have passed since last update.

Raspberry Pi 3 Model B に 64bit NBD Root な環境を構築する

Last updated at Posted at 2018-05-20

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
    • 実際こんなにいらない。
  • 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

$ ./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の設定ファイルを作成

/etc/nbd-server/conf.d/raspi-root.conf
[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スペースの作成

/etc/nbd-server/conf.d/swap.conf
[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
/etc/nbd-server/create_sparse.sh
#!/bin/sh

if [ ! -e $1 ]; then
   logger -t nbd "create sparse file: $1"
   truncate -s $2 $1
fi
/etc/nbd-server/create_sparse_swap.sh
#!/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-server before commit 2ab3a2d fails to communicate with nbd-client after commit e6b56c1 · Issue #66 · NetworkBlockDevice/nbd · GitHub

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しておくことにする。

/etc/apt/preferences
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の修正

/etc/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

カーネル起動パラメータの修正

/boot/cmdline.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

/boot/config.txt
dtparam=watchdog=on
/etc/modprobe.d/bcm2835-wdt.conf
options bcm2835_wdt heartbeat=10 nowayout=0
/etc/systemd/system.conf
RuntimeWatchdogSec=5

zramの有効化

パッケージがなくなった?ので自作

/etc/systemd/system/zram.service
[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
/usr/local/bin/systemd-zram-start
#!/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
/usr/local/bin/systemd-zram-stop
#!/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.deviceBefore=swap.targetに変更、
[Install] のRequiredBy=dev-%i.deviceWantedBy=sysinit.targetに変更

# systemctl daemon-reload
# systemctl enable nbd@nbd1

fstabの修正

/etc/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はあまりないのか、ハマりポイントが多い。
うまくいかない場合は、ネットワークとディスクの起動順序を見直すと良いようだ。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0