ラベル RAID の投稿を表示しています。 すべての投稿を表示
ラベル RAID の投稿を表示しています。 すべての投稿を表示

2011-09-04

Ubuntu 11.04でeSATA外付けHDにソフトウェアRAID 5を構築する

今回入手したHP Z800に、今度はeSATA接続で大容量の外付けHDを接続し、ソフトウェアRAID 5で運用してNASその他として利用することを考える。用意したものは以下の通り。

まずeSATAボードPEX-PE30SをPCIeスロットにセットする。HD × 5は裸族のインテリジェントビルCRIB535EUFに詰め込むだけ。CRIB535EUFはRAID機能を内蔵しているが、今回はそれは使わないのでRAID無しモードに裏面のディップスイッチをセットする。

両者を接続して起動すると、以前RAID 1を構築した内蔵HDが/dev/sdf, /dev/sdgとなり、今回接続したHDが/dev/sdasdeと認識された。このようなことがあるために、/etc/fstabなどでは/dev/sdaなどと直接指定するのでなく、ファイルシステムのUUIDで指定しておくべきだ。

そしてRAID 5を構築するため以下のコマンドを実行する。

$ sudo mdadm --create /dev/md4 --level=5 -n 5 --metadata=0.9 /dev/sd[abcde]
$ cat /proc/mdstat

ここから長い長い再構築プロセスが始まる。mdstatの出力を見ると、spareがどうとかこうとか出力され、特にスペアディスクなどを指定していないのにと困惑するが、man mdadmによるといったんスペアがあることにしたほうが構築が速く済むということなので心配しないでいい。再構築には多分20時間くらいかかった。再構築が終了したら、構成を保存する。

$ sudo vi /etc/mdadm/mdadm.conf
{ 以前のARRAY行を削除する }
$ sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
$ sudo update-initramfs -u
$ sudo reboot

後はファイルシステムを構築しマウントして終わり。

$ sudo mkfs -t ext4 /dev/md4
$ sudo blkid /dev/md4
$ sudo vi /etc/fstab
$ sudo mount -a

後日談

ある夜、サーバ置き場になっている書庫からボーという音がしていたのでのぞいてみると、ソフトウェアRAID 5で運用している裸族のインテリジェントビルのアクセスランプが全部赤くなっていてアクセスが連続して起きていた。これは何事?と思って調べてみた。

$ cat /proc/mdstat
md4 : active raid5 sda[0] sdb[1] sde[4] sdd[3] sdc[2]
      7814057984 blocks level 5, 512k chunk, algorithm 2 [5/5] [UUUUU]
      [=========>...........]  check = 49.8% (974687636/1953514496) finish=658.9min speed=24756K/sec

なんとRAIDの再構築が進行中だった。もう壊れたのか?と思ってよく見てみると、壊れたことを示すFAILなどの文字が無い。あちこち検索したところ、/etc/cron.d/mdadmによる設定によって週に一回/usr/share/mdadm/checkarrayが実行されることが判明した。そしてよく目をこらしてmdstatの出力を見るとcheck =となっていて、再構築ではなくチェックが進行中なだけであった。でも週1で20数時間かけてチェックするのもどうかな...

(2011/10/2追記)/etc/cron.d/mdadmをよく見ると、[ $(date +\%d) -le 7 ]というチェックが入っていて、月一度の実行だった。

 

2011-08-26

RAIDやLVMが設定されたHDを初期化する方法

Linux によるソフトウェアRAIDやLVMは、HD上のパーティションにメタデータという形で設定を書き込む。これによってHDをマシン間で移動したときなどでも設定ファイル無しに復元できることになる。

ただ、このメタデータは明示的に消去しないとHDを再フォーマットしてもそのまま残り続けて、再度のRAIDやLVMの設定に問題を起こすことがある。例えばインストーラがRAIDやLVMパーティションを誤検知してしまい、訳のわからないことが起こることがある。

Ubuntu のインストーラを用いてこのようなHDをリセット(再初期化)する方法を紹介する。起動ディスクとしてはUbuntuデスクトップインストーラまたはサーバインストーラを用いる。

$ sudo apt-get update
$ sudo apt-get install mdadm

Ubuntuサーバインストーラを使う場合はmdadmが入っているので、レスキューモードを選んでシェルに抜けるだけでよい。

では消去を実行しよう。mdadm には--zero-superblockというオプションがあって、これがメタデータを消去してくれる。

$ for a in /dev/sd[ab]?*; do sudo mdadm --zero-superblock $a; done

LVMも設定している場合は、各パーティションの先頭あたりをきれいにすればよい(lvremoveなどを用いたもっとスマートな方法があるはずだが調べるのが面倒だった...)。

$ for a in /dev/sd[ab]?*; do sudo dd if=/dev/zero of=$a bs=1M count=1; done

この方法で重要なのは、パーティション情報を消去する前に行う必要があるということだ。メタデータの場所はパーティションに対して位置が決まっているからである。もしパーティションを初期化してしまった場合、パーティションの分割を覚えているなら同じ分割でパーティションを設定すれば問題ない。覚えていないならメタデータがありそうな場所(あるいはHD全体)を0で埋める方法をとる必要があるだろう。

メタデータの場所

メタデータがパーティションのどこにあるかを調べてみた。以下のようになっている。

  • RAIDでmetadata=0.9の場合: パーティションのお尻から128K〜64Kの範囲で、64Kアラインされている位置から4Kぶん。
  • RAIDでmetadata=1.xの場合、xによって位置が異なる: 1.0はお尻、1.1は頭、1.2は頭から4Kの場所に位置する(アラインについては不明)。
  • LVMのメタデータはパーティションの先頭にある(RAID上のLVMの場合はもちろんRAIDのメタデータの内側)。

References

RAIDのメタデータの位置について: [RAID superblock formats - Linux Raid Wiki]

LVMのメタデータの位置について: [LVM-on-RAID - The Linux Documentation Project]

Linux (Ubuntu 11.04)で2TB超のHDをソフトウェアRAID化する (4)

(承前)

sdaをRAIDに参加させる

無事に/dev/md0からブートできただろうか?この時点でsdaは最早使われていない。あとはこのsdaを片肺飛行しているRAIDに加えればおしまいだ。まずsdaのパーティションのraidフラグを立てる。

$ sudo parted /dev/sda
(parted) toggle 2 raid
(parted) toggle 3 raid
(parted) toggle 4 raid
(parted) quit

さていよいよRAIDにsdaを参加させる。

$ sudo mdadm --add /dev/md0 /dev/sda2
$ sudo mdadm --add /dev/md1 /dev/sda3
$ sudo mdadm --add /dev/md2 /dev/sda4

これにより、参加させたsdaの同期が始まる。同期の様子を見るには以下のようにする。

$ watch cat /proc/mdstat

同期が終わったら再起動でもしておく。

$ sudo reboot

この時点では、以前に作った/etc/grub.d/09_raidによるgrubエントリの生成は必要がなくなっている。update-grubによってちゃんと作られるからだ。/etc/grub.d/09_raidを用意した時点ではsdaがマウントされている状態でmd0のブート用のエントリを作ろうとしたのに対し、いまはmd0がマウントされている状態でmd0のブート用のエントリを作ろうとしているからである。ついでにupgradeも行おう。

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo rm /etc/grub.d/09_raid
$ sudo update-grub
$ sudo update-initramfs -u
$ sudo grub-install /dev/sda
$ sudo grub-install /dev/sdb
$ sudo reboot

以上でゴールが実現できた。

References

検索するといっぱい出てくるが、どれも試すとなかなか最後まで行かない。最も近いところまで行き、内容も参考になったのが以下のページ(英語): [How To Set Up Software RAID1 On A Running System (Incl. GRUB2 Configuration) (Ubuntu 10.04) | HowtoForge - Linux Howtos and Tutorials]

GPTと2048セクタへのアラインについては以下のページが参考になった: [LinuxMania: RAIDボリュームからのブートとパーティション]

その他、以下のページ群から情報をつなぎ合わせて問題が解決した: [Linuxでmdadmを使ったソフトウェアRAIDの構築・管理メモ - nabeの雑記帳], [RAID1 on etch | qos webmaster's blog], [Ubuntu を BeyondRAID 環境へ移行する (1/2) - nigakyのメモ帳]

2011-08-25

Linux (Ubuntu 11.04)で2TB超のHDをソフトウェアRAID化する (3)

(承前)

sdbにRAID 1を構成

ソフトウェアRAIDの構築はmdadmコマンドを用いて行う。ログインしてからターミナルを開いてmdadmをインストールする。

$ sudo apt-get update
$ sudo apt-get install mdadm

依存関係によりpostfixがインストールされて何か質問されるので適当に答えておく。

RAID 1というのは2つのHDのうち1つが壊れても大丈夫というものだ。では実際に壊れたときにはどうすればいいのか?新しいHDを挿した状態でmdadmを実行できればいいのだ。このmdadmの実行をDVDでのレスキュー起動で行ってもよいが、1個のHDが壊れた状態でも起動できるようにすればもっと楽である。デフォルトでは壊れた状態では起動できなくなっている(これは壊れて起動した状態でもう1個が壊れると悲惨な状況になるからである)のでこれを修正する。

$ sudo vi /etc/initramfs-tools/conf.d/mdadm
BOOT_DEGRADED=true
$ sudo reboot

再起動後、sdbをsdaと全く同じようにパーティション分けする。

$ sudo parted /dev/sdb
(parted) mktable gpt
(parted) mkpart _ 1mib 2mib
(parted) toggle 1 bios_grub
(parted) mkpart _ 2mib 1gib
(parted) mkpart _ 1gib 3gib
(parted) mkpart _ 32gib 48gib

RAIDにするためにはパーティションのraidフラグを立てる必要がある。

(parted) toggle 2 raid
(parted) toggle 3 raid
(parted) toggle 4 raid
(parted) quit

いよいよRAID 1の作成だ。

$ sudo mdadm --create /dev/md0 --level=1 -n 2 --metadata=0.9 missing /dev/sdb2
$ sudo mdadm --create /dev/md1 --level=1 -n 2 --metadata=0.9 missing /dev/sdb3
$ sudo mdadm --create /dev/md2 --level=1 -n 2 --metadata=0.9 missing /dev/sdb4

ここで--metadataによってメタデータのフォーマットを0.9にしている点に注意してほしい。--metadataを省略すると1.2になるのだが、これでは後々問題が起こる。先回りして言うと、1.2でもほぼ問題なく最終段階まで設定が成功するのだが、apt-get upgradeでカーネルのアップデートが起こるとそれが失敗してしまうと言う致命的な問題が起こる。これはカーネルアップデートの際に実行されるupdate-grubが1.2フォーマットのメタデータを読めないために生じる問題である。ここでメタデータのフォーマットとして0.9を指定しなければならないというのを発見するのにはかなり苦労した。世のページでのソフトウェアRAIDの説明では古いバージョンのmdadmが使われており、その場合メタデータのフォーマット0.9がデフォルトとなるのでうまくいっていたのだ。

ソフトウェアRAIDの状況を確認しておく。

$ cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md2 : active raid1 sdb4[1]
      16777152 blocks [2/1] [_U]
      
md1 : active raid1 sdb3[1]
      2097088 blocks [2/1] [_U]
      
md0 : active raid1 sdb2[1]
      1046464 blocks [2/1] [_U]
      
unused devices:

パーティションをフォーマットする。

$ sudo mkfs -t ext4 /dev/md0
$ sudo mkfs -t ext4 /dev/md2
$ sudo mkswap /dev/md1

ソフトウェアRAIDの設定を保存する。

$ sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
ARRAY /dev/md0 metadata=0.90 UUID=5f156622:2c294f4b:21de336c:78d7ee00
ARRAY /dev/md1 metadata=0.90 UUID=4e48e1ac:30d9556c:21de336c:78d7ee00
ARRAY /dev/md2 metadata=0.90 UUID=c9e99e19:4bd9a5d8:21de336c:78d7ee00

最近のLinuxでは、このまま再起動すると/dev/md0などの名前が変わってしまうので、初期ラムディスクの作り直しが必要である。

$ sudo update-initramfs -u
$ sudo reboot

再起動して/dev/md0などが存在することを確認する。

/dev/md0からブートできるように設定

fstabを編集して/dev/md?を用いてファイルシステムを組織するように設定する。blkidによって取得したUUIDを用いて/etc/fstabを書き換える。

$ sudo blkid /dev/md[012] | tee /tmp/uuid
/dev/md0: UUID="f45a96a8-8bcf-4a51-9cbe-76c2583ddd5d" TYPE="ext4"
/dev/md1: UUID="1e6eb27a-18d7-4735-9d78-f12c22be17eb" TYPE="swap"
/dev/md2: UUID="a0965d65-1de0-4876-8108-63ef9fe8e568" TYPE="ext4"
$ sudo vi /etc/fstab
UUID=a0965d65-1de0-4876-8108-63ef9fe8e568 /               ext4    noatime,user_xattr,errors=remount-ro  0  1
UUID=f45a96a8-8bcf-4a51-9cbe-76c2583ddd5d /boot           ext4    noatime,user_xattr  0   2
UUID=1e6eb27a-18d7-4735-9d78-f12c22be17eb none            swap    sw              0       0

次に/dev/md0からブートするようにgrubを設定する。

$ cd /etc/grub.d
$ sudo cp 40_custom 09_raid
$ sudo vi 09_raid
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
menuentry 'Ubuntu, with Linux 2.6.38-8-generic' --class ubuntu --class gnu-linux --class gnu --class os {
    recordfail
    insmod part_gpt
    insmod raid
    insmod mdraid09
    insmod ext2
    set root='(md0)'
    linux   /vmlinuz-2.6.38-8-generic root=UUID=a0965d65-1de0-4876-8108-63ef9fe8e568 ro   quiet splash vt.handoff=7
    initrd  /initrd.img-2.6.38-8-generic
}
$ sudo update-grub

09_raidファイルの内容は、/boot/grub/grub.cfgからコピーしてきたmenuentryをペーストして変更するとよいだろう。linux行のUUIDにはもちろん先ほどblkidで取得したrootパーティション/dev/md2のものを設定する。

ここの設定も正しいものを探り出すのに大変苦労した。まず、世のページではinsmod mdraidになっているものが多いが、メタデータのフォーマットによってmdraid1xmdraid09を使い分けなければならない。次に大苦労したのが(md0)という表現である。世のページでは(md/0)というのまで出てきて誤植かとも思ったのだが、実はメタデータが1.xのとき(md/0)で、0.9のとき(md0)を使うのだ!そんなことどこに書いてあるんだ!!

初期ラムディスクの再生成を忘れないように。

$ sudo update-initramfs -u

sdaからsdbへのコピー

rsyncの-xオプション(ファイルシステムの境界を越えない指定)を用いてコピーする。

$ sudo mkdir /mnt/md0 /mnt/md2
$ sudo mount /dev/md0 /mnt/md0
$ sudo mount /dev/md2 /mnt/md2
$ sudo rsync -ax / /mnt/md2
$ sudo rsync -ax /boot/ /mnt/md0

5行目の/boot/の終わりのスラッシュを忘れないように。

最後にgrubをインストールして再起動する。片方のHDが壊れてももう片方のHDで起動できるように両方のHDにgrubをインストールする必要がある。

$ sudo grub-install /dev/sda
$ sudo grub-install /dev/sdb
$ sudo reboot

あと一息。

(つづく)

Linux (Ubuntu 11.04)で2TB超のHDをソフトウェアRAID化する (2)

(承前)

パーティション分け

2TBを超えるHDでは従前のいわゆるDOSパーティションテーブルは利用できず、GUIDパーティションテーブル(GPT)を使わなくてはならない。今回のHDは2Tなので必ずしもGPTを使う必要はないが、新しく触れる技術なので使ってみたところはまり込んだ次第。

GPTによるパーティション分けはGNU partedというコマンドで行う。Ubuntu デスクトップインストーラで起動し、[Try Ubuntu] を選んでターミナルを開き、parted を実行すればよい。まずはパーティションテーブルの初期化だ(以下を実行するとHDの内容が全部読めなくなるので注意してほしい)。

$ sudo parted /dev/sda
(parted) mktable gpt

さて、説明は省くがGPTを起動ディスクに用いた場合、先頭にbiosgrub属性を持つ1Mのパーティションが必要である。また、Advanced Format Technology (Big Sector) 対応のため、パーティション境界を2048セクタにアラインした方がよいらしい。このためにはセクタ境界の指定にmibまたはgibを用いればいい。以下でbiosgrubパーティションを作成する。

(parted) mkpart _ 1mib 2mib
(parted) toggle 1 bios_grub

partedのhelpコマンドによるとmkpartコマンドの第一引数はprimaryとかextendedを指定しろと書いてあるのだが、これはおそらくDOSパーティション用で、GPTの場合第一引数は単なる名前になるようだ。この名前がどのように使われるかは私は知らない。この記事では名前は全部 _ で済ますことにする。

次にboot, swap, root用の各パーティションを作成する。

(parted) mkpart _ 2mib 1gib
(parted) mkpart _ 1gib 3gib
(parted) mkpart _ 32gib 48gib

DOSパーティションと違い、パーティションのタイプを指定する必要はない。また、3gib と 32gib の間の「穴」は、後々簡単に swap パーティションを拡大できるようにするための余地である。

(最後のパーティションをディスクいっぱいまで使いたい場合はmkpart _ 32gib -0gibとすればよい; ただし同期に長大な時間がかかる)

ここまでの作業でパーティションは以下のようになる。

(parted) unit mib
(parted) print free
Number  Start     End         Size         File system  Name  Flags
        0.02MiB   1.00MiB     0.98MiB      Free Space
 1      1.00MiB   2.00MiB     1.00MiB                   _     bios_grub
 2      2.00MiB   1024MiB     1022MiB                   _
 3      1024MiB   3072MiB     2048MiB                   _
        3072MiB   32768MiB    29696MiB     Free Space
 4      32768MiB  49152MiB    16384MiB                  _
        49152MiB  1907729MiB  11858577MiB  Free Space

確認してリブートする。

(parted) quit
$ sudo reboot

インストール

Ubuntuデスクトップインストーラで起動しインストールを開始する。[ディスク領域の割り当て] の場面では [それ以外] を選んで、手動で ext4 ファイルシステムや swap を設定し、マウントポイントも設定する。

(つづく)

Linux (Ubuntu 11.04)で2TB超のHDをソフトウェアRAID化する (1)

今回入手したHP Z800には500GBのHDが付いていてWindows 7 Professionalがインストールされているが、Windowsは必要ないのでLinux (Ubuntu)に入れ替える。最終的な目標は外付けの集合型HD箱にHDを5台詰め込んでRAID 5で運用することだが、本体に内蔵するシステム用HDもRAIDで運用したいと考えた。

LinuxでソフトウェアRAID (RAID 1)を構成する話なんてありふれていて、ちょろっと検索して調べれば簡単に済む話だと思っていたが、これが大違い。検索の結果、一番簡単なやり方はインストーラで最初からRAID構成にすること、ということだったので試してみたところ、

  • Ubuntu デスクトップインストーラではRAID構成はできない。
  • Ubuntu Alternative インストーラならできるらしいが、HP Z800のハードウェア(おそらくイーサネットチップ)がサポートされておらずインストーラがうまく動かない。
  • それ以前の話として、2TBを超えるHDのパーティション切りにインストーラが対応できていない。

などの理由で一筋縄ではいかないということが判明した。それからしばらくの間格闘した結果、うまく設定できる方法がわかったのでここに記述する。

材料

  • HP Z800(付いてきた500GBのHDは外す)
  • 2TB HD × 2(512バイト/セクタ)(sda, sdbと呼ぶ)
  • Ubuntu 11.04インストールDVD(デスクトップ版)

ゴールの設定と作業の概要

ゴール: boot, swap, rootの各ファイルシステム用のパーティションをRAID 1で運用する。

作業の概要は以下のようになる。

  1. sdaをパーティション分けする。
  2. sdaに Ubuntu 11.04 デスクトップ版をインストールする。
  3. sdbにRAID 1を構成する。このとき相方が無いsdb 1台のみの設定で構成する。
  4. sdbにsdaの内容をコピーし、相方の無いsdbのみのRAID 1で起動できるようにする。
  5. (この時点でsdaは全く使われていない状態になっている)sdaをsdbのみで運用されているRAID 1に参加させる。

(つづく)