2019 年度 OSS リテラシ 3 : overlayfs の利用
はじめに
本作業を行う前に, (1) crontab でセンサーの計測コマンド (sensor.sh) が再起動時に自動実行されるようになっていることを確認, (2) ラズパイをセンサーとして各所に配置, しておくこと.
データがサーバに届いていることを確認した上で, ラズパイにリモートアクセスし, 以下の作業を行うとよい. なお, ラズパイの IP アドレスは DB の monitoring_hosts テーブルに保管されているのでそれを参照すること.
SD カードへの書き込みの抑制
センサーの本格稼働の前に SD カードへの書き込み抑制を行う.
これを行う理由は, ラズパイの SD カードは壊れやすいためである. 2016, 2017 年度の IoT 演習では, 10 秒おきにデータをファイル出力したところ, 稼働開始から数ヶ月で SD カードが壊れる事態が頻発した. また, ラズパイをセンサーとして運用していると電源ケーブルを抜き差しして ラズパイを再起動したくなることがあるが, SD カードの読み書き中に電源を切ると SD カードが壊れることがある.
SD カードへの書き込みを抑制するために overlayfs を用いる. overlayfs を用いることで, Readonly な下の層 (この場合は SD カード) と, Writable な上の層 (この場合はメモリー) を重ね合わせ 1 つのファイルシステムに見せることができる. データの書き出しは全てメモリ上に行われるので, 例え電源が抜き差ししても SD カードが壊れることはない.
実装の仕方は色々あるが, 今回は導入やメンテナンスが簡単な root-ro (Read-only Root-FS with overlayfs for Raspian) を用いる. 以下の作業は root-ro の README に基づいている.
swap 領域の無効化
まずは swap 領域を無効にする. swap はメモリ不足の時にディスクをメモリ代わりに使うものである. 今回はデータを全てメモリ上に置くので, swap を使う意味がない.
まずはメモリと swap の状態を確認する. swap が 100 MB あることがわかる.
# free total used free shared buffers cached Mem: 947732 745712 202020 49428 167380 332228 -/+ buffers/cache: 246104 701628 Swap: 102396 0 102396
swap 領域の無効化を行う.
# dphys-swapfile swapoff # dphys-swapfile uninstall # update-rc.d dphys-swapfile disable # systemctl disable dphys-swapfile dphys-swapfile.service is not a native service, redirecting to systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install disable dphys-swapfile
swap 領域が無効化されたことを確認する. 以下のように Swap の total が 0 になっていれば良い.
# free total used free shared buff/cache available Mem: 949580 113572 499352 16012 336656 765948 Swap: 0 0 0
root-ro の取得
root-ro は GitHub から入手する. それ以外は raspbian のパッケージを用いる (本演習では第 1 回目に, rsync, git, gawk, busybox, bindfs をインストール済み. もしインストールされていなければ apt-get コマンドを用いてこれらのパッケージをインストールすること).
$ sudo -s # cd # git clone https://github.com/josepsanzcamp/root-ro.git
root-ro の設定
GitHub から入手した root-ro のファイル群をシステム領域にコピーし, initramfs を作成し, 設定ファイル (/boot/config.txt) に修正を加える.
# rsync -va root-ro/etc/initramfs-tools/* /etc/initramfs-tools/ sending incremental file list modules hooks/ hooks/root-ro scripts/ scripts/init-bottom/ scripts/init-bottom/root-ro sent 10,494 bytes received 93 bytes 21,174.00 bytes/sec total size is 10,130 speedup is 0.96 # mkinitramfs -o /boot/initrd.gz # echo initramfs initrd.gz >> /boot/config.txt (起動時に必要な設定をファイル末尾に書き込む)
再起動
# reboot
再起動後の確認
overlayfs が有効になっていることを確認するために, df コマンドを実行する. 以下のようにファイルシステムとして "overlay" が存在すれば良い.
$ df ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置 udev 464112 0 464112 0% /dev tmpfs 94960 2840 92120 3% /run /dev/mmcblk0p2 14777128 5057392 8949384 37% /mnt/root-ro tmpfs 474788 27520 447268 6% /mnt/root-rw tmpfs 474788 0 474788 0% /mnt/boot-rw /dev/mmcblk0p1 42708 33582 9126 79% /mnt/boot-ro /mnt/boot-ro 42708 33582 9126 79% /mnt/boot-ro2 overlay 474788 27520 447268 6% / <--ココ overlay 474788 0 474788 0% /boot <--ココ tmpfs 474788 0 474788 0% /dev/shm tmpfs 5120 4 5116 1% /run/lock tmpfs 474788 0 474788 0% /sys/fs/cgroup tmpfs 94956 0 94956 0% /run/user/109 tmpfs 94956 0 94956 0% /run/user/1001
さらにホームディレクトリにファイルを作成し, 再びラズパイを再起動せよ.
$ touch test.txt $ ls -l test.txt -rw-r--r-- 1 hogehoge hogehoge 0 11月 20 17:23 test.txt # reboot
再起動した直後, ホームディレクトリに test.txt が存在しないことを確認せよ. このように新たなデータは全てメモリ上に保管されるので, 再起動するとそれらのデータは全て失われる.
$ ls -l test.txt ls -l test.txt ls: 'test.txt' にアクセスできません: そのようなファイルやディレクトリはありません
参考 (1): SD カードを再び書き込み可能にする方法
SD カードに書き込みする場合には, ルートのファイルシステムを rw (read write) でマウントし直して, 設定ファイル (/boot/config.txt) を元に戻す. 但し, 絶対パスが /mnt/boot-ro/config.txt になることに注意せよ.
$ sudo mount -o remount,rw /mnt/boot-ro $ sudo vi /mnt/boot-ro/config.txt 末尾の命令を以下のようにコメントアウトする # initramfs initrd.gz $ sudo reboot
参考 (2): 再び overlayfs を有効にする.
再び SD カードに書き込みできない状態に戻すには, 設定ファイル (/boot/config.txt) の末尾の命令を有効にして再起動する.
$ sudo vi /boot/config.txt initramfs initrd.gz (コメントアウトを外す) $ sudo reboot