絖綛 N@i.jp  昨日:00036668
 今日:00017106
 総計:00266538
keywords
管理者専用
  Post   Add link   Control Panel 































新しいトピック
最新:04/16 19:55


新しいコメント
最新:07/28 16:47






管理人へMAIL

プライバシーポリシー

USBメモリでRAID 5を構築・RAIDから起動(ブート)できるようにする

MicroSDカードをシステムディスクとして使用していると、いつ壊れるか分からず不安なので


 Raspberry Piを24時間運転のサーバとして使用したいと考えた場合、ネックになるのは、やはり MicroSDカードの寿命でしょう。自分は既にMicroSDカードの故障を2回経験しています。スワップやログ出力を止めたり、RAMディスク(tmpfs)を使用する等の延命策を講じていましたが、24時間運転させると1年から1年半ほどで壊れました。
 そこで、せっかくRaspberry Pi 3 (Raspbian Jessie) で USBメモリを使った RAID 5を構築したのですから、Raspbian のシステムをRAIDアレイに移し、MicroSDカードからブートするのではなく、RAIDからブートできるようにしてみたい(システムディスクのRAID化)と思います。

 とは言え、Raspberry Piのブートの仕組み上、"/boot"パーティションだけはMicroSDカード上のFAT32上になければなりません。それ以外の"/"(ルート)パーティションを RAIDに移します。

 "/boot"パーティションは、システムの起動時に読み出されるだけですから、MicroSDカードの寿命で壊れる可能性はかなり低くなると考えられます。容量も 80MB程度で足りますから、容量の少ない安価な MicroSDに変えてしまうこともできます。また、バックアップも短時間で済みます。
 逆にRAIDに移した"/"(ルート)パーティションについては、これまでの「MicroSDカード全体を Mac, Windows等の他PCを用いてバックアップする」という方法が使えなくなりますので、別のバックアップ方法を考える必要があります。バックアップ方法については、後日検討することにします。

 Raspbian をRAIDアレイからブートしようとした場合、重大な問題が1つあります。それは RAIDアレイの構築にmdadmというソフトウェアRAIDを用いているという事です。ソフトウェアRAIDですから、システム(カーネル)が起動した後でなければ使用(RAIDアレイの構成、マウント)することができませんが、そのシステムがRAID内にあるという状態になるわけです。(金庫を開ける鍵が金庫の中に入っているようなもんです。)
 幸いなことに、Linuxにはこのような問題を解決する(様々なデバイスからブートできるようにする)ための仕組みがあります。それが「initramfs」です。これはLinuxがブートする際に使用する「ミニルート」ファイルシステムで、RAM上に展開されて使用されます。この中にソフトウェアRAIDのデバイスドライバ(カーネルモジュール)を組み込んでおけば、ブート時からRAIDアレイが使用できるようになります。(詳しくは「initramfs」等で調べてください。)通常の Raspbian では initramfs は使用されていません。理由はおそらく、ブート時から MicroSDカードの"/"(ルート)パーティション("/dev/mmcblk0p2"デバイス)を直接マウント可能なようになっているからではないかと推測されます。
 よって、大まかな手順としては以下のようになります。

  1. initramfsを作成する
  2. initramfsを使ってブートできるようにする
  3. "/"(ルート)パーティションの内容をRAIDにコピーする
  4. "/"(ルート)にRAIDアレイデバイス("/dev/md0")をマウントする

1. バックアップを取る

 作業ミスがあるとRaspberry Piが起動しなくなる可能性があります。作業前に必ず MicroSDカードのバックアップを作成しておきましょう。

2. システムを最新化する。

 Raspbian を最新化しておきます。ファームウェアのアップデートも忘れずに実施します。

# apt-get update
# apt-get upgrade
# apt-get dist-upgrade
# rpi-update
# reboot

3. initramfsを作成する

 initramfsに組み込みたいカーネルモジュールを"/etc/initramfs-tools/modules"に記述します。

# cd /etc/initramfs-tools
# vi modules
# List of modules that you want to include in your initramfs.
# They will be loaded at boot time in the order below.
#
# Syntax:  module_name [args ...]
#
# You must run update-initramfs(8) to effect this change.
#
# Examples:
#
# raid1
# sd_mod

となっているところを以下の赤字のように編集します。RAIDアレイの構成がRAID 1であれば、raid1モジュールで良いですが、ワタシの場合はRAID 5なので、raid456モジュールを組み込ませます。

# List of modules that you want to include in your initramfs.
# They will be loaded at boot time in the order below.
#
# Syntax:  module_name [args ...]
#
# You must run update-initramfs(8) to effect this change.
#
# Examples:
#
raid456
md_mod
ext4

 initramfsを作成し、内容を確認します。initramfsは"/boot/initrd.img-X.X.X"と言った名前で作成されます。

# uname -r
4.4.21-v7+
# update-initramfs -c -k `uname -r`
update-initramfs: Generating /boot/initrd.img-4.4.21-v7+
# ls -l /boot/initrd.img-4.4.21-v7+
-rwxr-xr-x 1 root root 6324242  9月 18 15:20 /boot/initrd.img-4.4.21-v7+
# lsinitramfs /boot/initrd.img-4.4.21-v7+ | grep raid
lib/udev/rules.d/64-md-raid-assembly.rules
lib/udev/rules.d/63-md-raid-arrays.rules
lib/modules/4.4.21-v7+/kernel/drivers/md/raid10.ko
lib/modules/4.4.21-v7+/kernel/drivers/md/raid1.ko
lib/modules/4.4.21-v7+/kernel/drivers/md/raid0.ko
lib/modules/4.4.21-v7+/kernel/drivers/md/raid456.ko  ←※入ってますね
lib/modules/4.4.21-v7+/kernel/crypto/async_tx/async_raid6_recov.ko
lib/modules/4.4.21-v7+/kernel/lib/raid6
lib/modules/4.4.21-v7+/kernel/lib/raid6/raid6_pq.ko

4. initramfsでブートするように設定する

 initramfsを使ってブートするように設定を変更します。設定の変更には"/boot/config.txt"を編集します。

# cd /boot
# cp -p config.txt config.txt.org    ※バックアップを作成しておきます
# vi config.txt

以下の2行(赤字の部分)を追加します。

kernel=kernel7.img
initramfs initrd.img-4.4.21-v7+ followkernel

 "/boot"配下には"kernel.img""kernel7.img"の2つのカーネルイメージファイルがありますので、Raspberry Piの CPUに合わせてkernel=に指定します。Raspberry Pi A/A+/B/B+/Zero では CPUがARMv6ですので"kernel.img"を、Raspberry Pi 2/3 では"kernel7.img"を指定します。
 initramfs の第一パラメタには、先ほど作成した"initrd.img-X.X.X"(ここでは"initrd.img-4.4.21-v7+")を指定します。

 編集できたら保存し、再起動できるか?確認します。

# reboot

 無事に再起動できたら、先ずは第一段階クリアです。再起動できなかった場合は、カーネルイメージファイル名や initramfsファイル名を間違えていないか確認してください。

# uname -a
Linux RaspberryPi3 4.4.21-v7+ #911 SMP Thu Sep 15 14:22:38 BST 2016 armv7l GNU/Linux

5. "/"配下のファイルをRAID配下にコピーする

 "/"(ルート)配下にあるファイルを全てRAID配下にコピーします。ワタシの場合、RAIDアレイは"/media"にマウントされていますから、以下のようにコピーします。

# cp -afx / /media

 cpコマンドの-xオプションを指定することで、"/"のファイルシステム内のファイルだけをコピーするようにしています。(そうしないと"/media"配下のファイルもコピーしようとしてしまうだろう)コピーにはちょっと時間がかかりますので、気長にお待ちください・・・

6. "/boot/cmdline.txt"を編集

 カーネルへ渡すパラメタファイル"/boot/cmdline.txt"を編集します。

# cd /boot
# cp -p cmdline.txt cmdline.txt.org    ※バックアップを作成しておきます
# vi cmdline.txt
dwc_otg.lpm_enable=0 console=serial0,115200
    console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4
    elevator=deadline fsck.repair=yes rootwait

注)行が長いので折り返していますが、実際には1行です。
これを以下のように修正(赤字の部分)します。

dwc_otg.lpm_enable=0 console=serial0,115200
    console=tty1 root=/dev/md0 rootfstype=ext4
    elevator=deadline fsck.repair=yes rootdelay=10 rootwait

 root=パラメタには"/"配下のファイルをコピーした先のRAIDデバイス名を指定します。ワタシの場合は"/dev/md0"になります。(*1)
 また、USBメモリが認識されるまで少し時間がかかるので、rootdelay=10パラメタを指定することで10秒間遅延させるようにしています。(*2)

7. fstabを編集

 "/"にRAIDデバイスをマウントさせるように"/etc/fstab"ファイルを編集します。ただし、元の"/etc/fstab"ではなく、RAIDにコピーした方の"/etc/fstab"(ここでは"/media/etc/fstab")を編集します。

# cd /media/etc
# cp -p fstab fstab.org    ※バックアップを作成しておきます
# vi fstab

 現在、既にRAIDを"/media"にマウントして使用していますので、fstabファイルは以下のようになっています。

proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults          0       2
/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
#
# tmp files put on RAM disk
tmpfs           /tmp            tmpfs   defaults,size=128m,noatime,mode=1777    0       0
tmpfs           /var/tmp        tmpfs   defaults,size=16m,noatime,mode=1777     0       0
#
# Log files write on RAM disk
tmpfs           /var/log        tmpfs   defaults,size=32m,noatime,mode=0755     0       0
UUID=f8b8beba-56e0-4f91-a717-8f2bc7459453  /media  ext4  defaults,noatime,nofail 0  2

 これを以下のように変更(赤字の部分)します。

proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults          0       2
#/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
UUID=f8b8beba-56e0-4f91-a717-8f2bc7459453  /  ext4  defaults,noatime,errors=remount-ro  0  1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
#
# tmp files put on RAM disk
tmpfs           /tmp            tmpfs   defaults,size=128m,noatime,mode=1777    0       0
tmpfs           /var/tmp        tmpfs   defaults,size=16m,noatime,mode=1777     0       0
#
# Log files write on RAM disk
tmpfs           /var/log        tmpfs   defaults,size=32m,noatime,mode=0755     0       0
#UUID=f8b8beba-56e0-4f91-a717-8f2bc7459453  /media  ext4  defaults,noatime,nofail 0  2

8. 再起動する

# reboot

 無事に再起動できれば(たぶん)成功!確認してみましょう。

# df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
udev              10M     0   10M    0% /dev
tmpfs            195M  4.8M  190M    3% /run
/dev/md0         174G   66G   99G   40% /              ←※"/"のデバイスが"/dev/md0"になった
tmpfs            487M     0  487M    0% /dev/shm
tmpfs            5.0M  4.0K  5.0M    1% /run/lock
tmpfs            487M     0  487M    0% /sys/fs/cgroup
tmpfs             32M  148K   32M    1% /var/log
tmpfs             16M     0   16M    0% /var/tmp
tmpfs            128M   50M   79M   39% /tmp
/dev/mmcblk0p1    60M   34M   27M   56% /boot
overlaid         128M   50M   79M   39% /tmp/asd-root/var/lib/monitorix
tmpfs             98M     0   98M    0% /run/user/109
tmpfs             98M     0   98M    0% /run/user/0

 再起動できない(ブートしない)場合は、一旦Raspberry Piの電源をオフにし、MicroSDカードを抜いて PC等にマウントします。"/boot"パーティションはFAT32ですから、普通に Macや Windowsからアクセスできますので、"/boot/cmdline.txt"ファイルをバックアップファイルに戻せば復旧するはずです。(それでも復旧しなかったら、一番最初に取った MicroSDカード全体のバックアップに書き戻すだね。^^;)

 無事に起動できれば作業は終了です。後は"/boot"パーティションを、もっと容量が少なくて安価な MicroSDカードに入れ替えてしまっても良いでしょう。今では 4GB, 8GB程度の MicroSDカードなら数百円程度で売っています。まぁ32GBでも千円程度ですけどね。


(*1)"/dev/md0"ではなく、fstab のように UUIDで指定することもできました。

dwc_otg.lpm_enable=0 console=serial0,115200
    console=tty1 root=UUID=f8b8beba-56e0-4f91-a717-8f2bc7459453 rootfstype=ext4
    elevator=deadline fsck.repair=yes rootdelay=10 rootwait

 (あまり無いとは思いますが)Raspberry Piに複数台のRAIDアレイを接続している場合は、UUIDで指定する必要があります。

(*2):以前は "/etc/init.d/mdadm-raid"スクリプトにsleepを入れることで、USBメモリが認識されるまで遅延させていましたが、これはもう不要になります。


< 過去の記事 [ 9月の 全てのカテゴリ リスト ] 新しい記事 >

2016 calendar
9月
123
45678910
11121314151617
18192021222324
252627282930


掲示板
最新:08/15 17:19


GsBlog was developed by GUSTAV, Copyright(C) 2003, Web Application Factory All Rights Reserved.