USB HDDをソフトウェアRAIDでミラーリングして家庭内ストレージを作った
MacBook Air をメインにしてから以降、本体のストレージ領域が小さいことから、音楽データや写真データなどは、 外付けの USB HDD に保存するようにしているのだが、1つの HDD にしか保存していなかったので、 こいつが死んだら困るなぁ、と思っていた。
しかし、なんとかしないと、と思いつつもそのままの状態ですでに3年近くたってしまっていた。(笑)
それでも最近夏の暑さのためか、周りで HDD の故障の話をよく聞くようになってきたし、そろそろやらねばさすがにヤバイと、 ようやく重い腰をあげた次第だ。
方法としては、とりあえず、RAID1でミラーリングし、HDD自体の耐障害性のみを高めるということにした。[1]
今までの環境
今までは Mac mini に USB HDD を接続して、それを共有することで NAS 代わりにしていた。 これはだいぶお手軽で、OS X はソフトウェアRAIDもとてもカジュアルに作ることができる[2]ので、 この環境のまま RAID 化するのが一番楽だったと思う。
ただ、うちでは Mac mini の他にも古い Thinkpad を OpenVPN サーバとして使用していて[3]、 常時起動しているマシンが2台あり、これをどちらか片方だけにしたいとずっと思っていたので、 これを機に Thinkpad に統一させることにする。
方法
最初は、 裸族のテラスハウス RAID のような商品でRAIDしてくれるなら楽でいいかな〜と思っていたのだけど、 「安物のRAIDコントローラ使うくらいならソフトウェアRAIDのほうがマシ」という 組長 と 若頭 の教えをうけて、 Thinkpad に入っている ubuntu でソフトウェアRAIDを組むことにした。
なので方法としては、
- ThinkpadにUSB HDDを2台以上つける
- それらをRAID1でミラーリングさせる
- その領域を netatalk で共有する
という流れになる。[4]
買ったもの
UbuntuでのソフトウェアRAID構築
mdadm
というコマンドでやるらしい。
- man 4 md
- man 8 mdadm
に詳しくのっていた。
mdadmのインストール
sudo apt-get install mdadm
USB HDD 接続
/dev/sdb
と /dev/sdc
として認識される。
fdisk で領域確保
Linux raid autodetect (id: fd) として領域確保する。 今回は sdb sdc それぞれの全領域を割り当て。
Device Boot Start End Blocks Id System
/dev/sdb1 2048 3907029167 1953513560 fd Linux raid autodetect
/dev/sdc1 2048 3907029167 1953513560 fd Linux raid autodetect
こんな感じで sdb1 と sdc1 ができていればOK。
mdadm でRAID作成
sudo mdadm --create /dev/md0 --level 1 --raid-devices=2 /dev/sdb1 /dev/sdc1
としてソフトウェアRAIDを作成。RAID1で、sdb1とsdc1を、 /dev/md0 という仮想デバイスに作成、という意味。
フォーマット
sudo mkfs -t ext4 /dev/md0
再起動しても /dev/md0 ができるようにする
sudo update-initramfs -u
普通はこれをやる時に、mdadm.conf に ARRAY /dev/md0 ...
という設定を書くみたいだが、
USB HDD だからか、これを書いているとなぜか起動時に認識されないので、ARRAY の設定は書かないように設定。[5]
マウント
sudo mkdir /mnt/raid
sudo mount -t ext4 /dev/md0 /mnt/raid
再起動時にも自動でマウントされるようにする
sudo blkid
して、 /dev/md0
の UUID を調べ、 /etc/fstab
に、
UUID=そのUUID /mnt/raid ext4 defaults 0 0
という行を書いておく。
ここまでで、再起動しても自動的にRAIDボリュームが認識されマウントされるようになる。
RAIDに問題があった時に通知させる
RAIDを組んでもHDDが壊れた場合などに気がつけないと意味がないので通知の設定もしておく。
mdadm.conf
に
PROGRAM /home/typester/bin/mdadm-notify.sh
とか書いておくと、RAIDのステータスが変わった時にそのプログラムを実行してくれる。 ステータスと対象デバイスは引数でそれぞれ取得できる。
僕は im.kayac.com で通知させる以下のようなスクリプトをおいた。
#!/bin/sh
event=$1
device=$2
curl -s -d "message=[mdadm] $event $device" http://im.kayac.com/api/post/ユーザー名 >/dev/null
通知のテストは、
sudo mdadm --monitor --test /dev/md0
で行なうことができる。
また、通知システムがちゃんと動いているか確認するために、 Ubuntu では cron.daily 時にも通知が来るようになっているみたい。
以上でRAID周りの設定は完了
SMARTの設定
あんまり信用してないけど、念のためSMARTでHDDの状態も監視するようにする。
が詳しい。
smartmontoolsインストール
sudo apt-get install smartmontools
有効になってなかったらSMARTを有効にする
sudo smartctl -s on /dev/sda
sudo smartctl -s on /dev/sdb
sudo smartctl -s on /dev/sdc
smartmonが自動起動されるようにする
/etc/default/smartmontools
の start_smartd=yes
のコメントアウトをはずしておけばOK。
SMARTでなにか検知した場合に通知させる
デフォルトでは smartd.conf には通知プログラムとして smartd-runner
というのが登録されている。
これは /etc/smartmontools/run.d にあるスクリプトを実行してくれるラッパーのようだ。
以下のようなスクリプトを /etc/smartmontools/run.d/60notify として置き、実行権限をつけておく。
#!/bin/sh
curl -s -d "message=[SMART] $SMARTD_DEVICE may have a problem" http://im.kayac.com/api/post/ユーザー名 >/dev/null
この通知のテストは、 smartd.conf の
DEVICESCAN -d removable -n standby -m root -M exec /usr/share/smartmontools/smartd-runner
という行の末尾に -M test
とつけて保存したあと、 sudo service smartmontools restart
すると行なうことができる。
netatalkでAFP共有
netatalk を使って Mac からこのRAIDボリュームにアクセスできるようにする。 Ubuntu 12.04 のパッケージは古かったので、ソースからビルドした。
インストール
まず、 libgcrypt-dev
をインストールする。これが入ってないと新しめのMacからは認証できなくて接続できない。
sudo apt-get install libgcrypt11-dev
あとは普通にインストール
./configure --with-zeroconf --with-init-style=debian
make
sudo paco -D make install
設定
試行錯誤した結果 afp.conf はこんな感じになった。
[Global]
; Global server settings
save password = no
mimic model = Xserve
;log level = default:debug
[Time Machine]
path = /mnt/raid/tm
time machine = yes
vol size limit = 1000000
[Shared]
path = /mnt/raid/storage/shared
あと追加で、
[Homes]
home name = Private
basedir regex = /home
path = afp-data
という設定もしてあって、これはユーザー毎の ~/afp-data を Private という名前で共有する、という設定だが、
- home name に $u を含める必要がある
- ~/afp-data は実際には /var/raid/storage/{username} への symlink なのだが、symlink だと動かない
というようなnetatalkの制限があったので、適当にソースコードを修正してそれらを回避している。
起動
sudo service netatalk start
使用方法
接続するとこのように3つのボリュームが見える。
Time Machine はそのままで、Time Machine バックアップ用、 Shared は家族間で共有するデータを入れる用(アカウントがある人はすべて同じデータにアクセスできる)、 Private はそれぞれのユーザ専用領域、という感じになっている。
まとめ
これでようやく、 Mac mini を常時起動しなくてもよくなった。 Mac mini でやるのと比べるとたぶんだいぶセットアップは面倒だと思うが、細かい通知の設定などはLinuxのほうがしやすいのではないか、と思った。
裸族のテラスハウスは思ったより作りもしっかりしているし、その辺の安物のHDDケースとは違ってずっと使っていても熱くならないので、 だいぶ好印象。
ただ、2TBのRAIDのresyncに10時間くらいかかったので、HDD2つだけだとちょっと不安なところである…。[6]
あと、ミラーリングとは別にバックアップしたいが、その方法はまだ未定。 これは自前でやりたくないのでどこかのサービスを使いたいのだけど、どれも決め手に欠ける。 bitcasa が Linux に対応したら最有力候補なんだけど、いつになることやら。