[an error occurred while processing this directive]

ソフトウェアRAIDの導入

この文書の更新履歴

2003/6/14
/etc/raidtabで、「chunk-size」を指定していないとmkraidが正常に実行できない、とdebian-users-jpメーリングリストで指摘された。当時のメモを見直すと、mkraid時には存在したchunk-sizeの記述を、RAID構築後に削除してしまっていたことが判明した。
削除した理由は起動時にカーネルの警告メッセージが出るためだが、無視すれば別段問題ないので「chunk-size」の指定を復活させた。

やりたいこと

耐障害性の要求

自分は、生まれも育ちもWindowsな人間なので、Linuxサーバを使い始めたあとでもしディスク障害なんておきようものなら、絶対に復旧できないと考えた。Windowsならデータのバックアップも再インストールにも慣れてるんだけど、ただでさえよくわかんないLinuxが死んだら困る(ぉ

そこで、Linuxでサーバ立てるならRAID構成にしようとかねてから考えていたわけである。

RAIDとは

RAIDとは、複数のディスクで論理的に1つのディスクを構成する技術で、複数のディスクを使うことによってディスクアクセスを高速化したり(たとえば2台のディスクに半分ずつデータを書き込めば、ディスクの性能による書き込み速度の限界は2倍高速になる)、ディスクの信頼性を上げたり(2台のディスクに同じデータを書き込めば、どちらかのディスク装置が故障してもデータが失われない)する技術である。

RAIDレベル

RAIDにはいくつかの種類があり、主なものとしては以下の4つがある。

今回は、メールサーバなどとして今後重要に働いてもらうLinuxマシンに使用するわけなので、RAID 1を構成する。

ハードウェアRAIDとソフトウェアRAID

RAIDを実現する処理をハードウェアで行うか、ソフトウェアで行うかによって2方式がある。ハードウェアRAIDは、OSやアプリケーションの変更を必要とせずにRAIDの恩恵が受けられ、CPUに負荷をかけないというような利点があるが、追加投資が必要になる。逆に、ソフトウェアRAIDには投資を行わないでRAIDを実現できる利点がある一方、設定が面倒であったり、RAID処理のためにCPUに負荷がかかったりする。特に、RAID5のパリティ計算などでは負荷が重くなるらしい。

タイトルにあるとおり、ここではソフトウェアRAIDを使用する。設定は一度行ってしまえばあとは置いておくだけだし、RAIDの構築作業(実際にHDD間の同期を取る作業)を、サーバーを稼動させながらバックグラウンドで行える点がハードウェアRAID(手が届く範囲のもの)にはない魅力だったからである。

作業の流れ

今稼動しているシステムを生かしたまま、RAIDを構築し、システムを移植する。方法として、RAID1の縮退モードというものを利用する。片方のドライブにはシステムが稼動していないといけないので、いきなり完全なRAIDを構築するのは不可能だからである。

最初の状態

そこで、まずシステムで使ってないほうのディスク(hdc)に、「RAID1なんだけど、片方のディスクが故障して切り離されてしまった」状態を仮想的に作る。

RAIDを縮退モードで構築
RAID上にシステムを移植

その後、そちらにシステムを移植して、「不完全なRAID」からシステムが起動する状態に持っていく。そのあとで、改めて今までシステムディスクだったほう(hda)をRAIDに加えて、完全なRAIDを完成させるのである。

完成

準備作業

必要なソフトのインストール

今回やりたいのは、RAID上で、しかもReiserFSというファイルシステムを使用することなので、それらをKernelでサポートしていないといけない。それは、前回のカーネル再構築のときに済ませてあるのでここでは割愛する。

Kernelのサポートがあっても、実際に使用するソフトが必要なので、それは別途インストールする必要があるが、RAIDツールもReiserFSツールもDebianパッケージになっているので別に苦労はない。aptでインストールする。

    root@host# apt-get install raidtools2 reiserfsprog

パーティションの分割

rootでcfdiskを実行して、次のようにパーティションを切った。

    マウントポイント(予定)  容量(MB)  デバイス名
    /boot                    256      hdc1
    /                        512      hdc2
    /usr                    8192      hdc5
    /home                   2048      hdc6
    /var                    1024      hdc7

さらに、すべてのパーティションのタイプを0xfdに設定しておく(重要)。画面上では種別が「Linux raid autodetect」と出るようになった。

RAIDアレイを準備

RAIDアレイの設定

/etc/raidtab を、こんな感じで作成。

    raiddev                 /dev/md1
    raid-level              1
    nr-raid-disks           2
    nr-spare-disks          0
    chunk-size              32
    persistent-superblock   1
    device                  /dev/hdc1
    raid-disk               0
    device                  /dev/hda1
    failed-disk             1
    
    raiddev                 /dev/md0
    raid-level              1
    nr-raid-disks           2
    nr-spare-disks          0
    chunk-size              32
    persistent-superblock   1
    device                  /dev/hdc2
    raid-disk               0
    device                  /dev/hda2
    failed-disk             1

    raiddev                 /dev/md2
    raid-level              1
    nr-raid-disks           2
    nr-spare-disks          0
    chunk-size              32
    persistent-superblock   1
    device                  /dev/hdc5
    raid-disk               0
    device                  /dev/hda5
    failed-disk             1
    
    raiddev                 /dev/md3
    raid-level              1
    nr-raid-disks           2
    nr-spare-disks          0
    chunk-size              32
    persistent-superblock   1
    device                  /dev/hdc6
    raid-disk               0
    device                  /dev/hda6
    failed-disk             1
    
    raiddev                 /dev/md4
    raid-level              1
    nr-raid-disks           2
    nr-spare-disks          0
    chunk-size              32
    persistent-superblock   1
    device                  /dev/hdc7
    raid-disk               0
    device                  /dev/hda7
    failed-disk             1

RAIDアレイを構築する

    raidアレイの構築
    root@host# mkraid /dev/md0
    root@host# mkraid /dev/md1
    root@host# mkraid /dev/md2
    root@host# mkraid /dev/md3
    root@host# mkraid /dev/md4
    
    そしてフォーマット
    root@host# mke2fs /dev/md1
    root@host# mkreiserfs /dev/md0
    root@host# mkreiserfs /dev/md2
    root@host# mkreiserfs /dev/md3
    root@host# mkreiserfs /dev/md4

今にして思えば別に必要はなかったが、とりあえず再起動してRAIDアレイがうまく動作するか調べた。どう調べたかというと、/proc/mdstat の中身を確認し、すべてのデバイスがactiveかどうか見ることである。

RAIDアレイ上にシステムを移す

いま /dev/hda* 上にあるファイルを、そっくり /dev/md* にコピーしたうえで、RAIDデバイス上のシステムが起動するようにブートローダ(ここでは、lilo)の設定を行う。

ファイルをコピーする

出来るだけ起動しているプロセスが少ないほうがいいと思い、シングルユーザーモードで作業をすることにした。もう一度再起動し、liloの画面のところで

    boot: linux single

と入力する。しばらくするとrootのパスワードを聞かれ、シングルユーザーモードで起動できる。

    コピー先のRAIDアレイをマウント
    root@host# mkdir /mnt/raid
    root@host# mount /dev/md0 /mnt/raid
    root@host# mkdir /mnt/raid/boot /mnt/raid/usr /mnt/raid/home /mnt/raid/var
    root@host# mount /dev/md1 /mnt/raid/boot
    root@host# mount /dev/md2 /mnt/raid/usr
    root@host# mount /dev/md3 /mnt/raid/home
    root@host# mount /dev/md4 /mnt/raid/var

    ざっくりファイルをコピーする
    root@host# cd /
    root@host# cp -a /bin /mnt/raid/
    root@host# cp -a /dev /mnt/raid/
    root@host# cp -a /sbin /mnt/raid/
    (その他、 /cdrom /floppy /mnt /proc 以外のディレクトリをすべてコピーする)

    マウントポイントを作成
    root@host# mkdir /mnt/raid/cdrom /mnt/raid/floppy /mnt/raid/mnt /mnt/raid/proc

起動したシステムがRAID領域をマウントするように /mnt/raid/etc/fstab を編集する。

    /dev/md0  /         reiserfs  defaults  0  0
    /dev/md1  /boot     ext2      defaults  1  1
    /dev/md2  /usr      reiserfs  defaults  0  0
    /dev/md3  /home     reiserfs  defaults  0  0
    /dev/md4  /var      reiserfs  defaults  0  0
    (後略)

ブートローダの設定

ミラーリンク構成では、どちらかのHDDが故障しても起動もうまくいかないと困る。そこで、1台目と2台目の両方のMBR(マスターブートレコード)に起動に関する情報を格納しておき、また、万一に備えて1台目のHDDによる起動メニューから2台目のHDDの起動メニューが呼び出せるようにしておく。

ということで、まず1台目のHDDのメニューから2台目のHDDが呼べるように、以下の設定を /etc/lilo.conf に追加した。

    other=/dev/hdc
            label=Secondary

lilo.confを変更したら、忘れずにMBRに情報を登録する。

    root@host# lilo -v

これで、1台目のHDDから表示されるメニューに、2台目のHDDを呼ぶ項目が追加されるはず。次に、2台目のHDDには、RAIDを認識してシステムを起動するための設定が必要である。fdiskでドライブの情報を調べて、

    root@host# fdisk -ul /dev/hdc
    Disk /dev/hdc: 16 heads, 63 sectors, 77557 cylinders

表示されたパラメータを使って /mnt/raid/etc/lilo.conf.hdc を作成する。

    lba32

    disk=/dev/md0
    bios=0x81
    sectors=63
    heads=16
    cylinders=77557

    partition=/dev/md1
    start=63

    boot=/dev/hdc

    install=/boot/boot-menu.b
    map=/boot/map

    prompt
    timeout=50
    vga=normal

    default=Linux

    image=/boot/vmlinuz
            label=Linux
            read-only
            root=/dev/md0

こちらも、忘れずにMBRに情報を登録する。

    root@host# lilo -v -C /mnt/raid/etc/lilo.conf.hdc

アンマウントし、RAIDアレイを止めて再起動してみる。

    root@host# umount /mnt/raid/boot
    root@host# umount /mnt/raid/usr
    root@host# umount /mnt/raid/home
    root@host# umount /mnt/raid/var
    root@host# umount /mnt/raid

    root@host# raidstop /dev/md0
    root@host# raidstop /dev/md1
    root@host# raidstop /dev/md2
    root@host# raidstop /dev/md3
    root@host# raidstop /dev/md4

    root@host# shutdown -r now

この時点での/dev/hdcの状態は以下のとおり。

    hdc1 Primary      Linux raid autodetect                         255.99
    hdc2 Primary      Linux raid autodetect                         511.97
    hdc5 Logical      Linux raid autodetect                        8192.00
    hdc6 Logical      Linux raid autodetect                        2047.87
    hdc7 Logical      Linux raid autodetect                        1023.94

再起動して、追加された「Secondary」から起動できるかどうかテスト。できなければ通常起動して問題を解決する必要がある。

ミラーリングする

無事にRAIDで起動したら、続きへ。まだこの時点ではRAIDの意味がないので、/dev/hdaのパーティションを切りなおしてちゃんとしたRAID1アレイにしよう。

ミラーリング先の準備

/dev/hda2にはスワップパーティションがあるので、まずスワップを解除する。

    root@host# swapoff -a -v

このあと、cfdiskを使ってパーティションを切りなおしたのだが、容量を入力するときにまったく同じ数値(たとえば、/dev/hda1なら"256")を入力しても厳密には同じ容量にならなかったので、ちょっとずつ大きめのサイズにして確保した。大きくしないと既存のRAIDアレイに参加させることは出来ない。

切った結果は以下のとおり。領域が一つ多いのはswap用にするため。以前はRAID領域にswapを置くと、「メモリが足りなくなる」→「swap確保命令が発動」→「RAID処理のためメモリ要求」→「さらにメモリ不足」という悪循環が起きて大変だった(というか、RAIDにswap置くのは不可だった)らしいが、最近のやつは改善されているらしいので気にせずRAID上swapなシステムにした。気になる人は、本当に大丈夫か調べたほうがいいと思う。

    hda1 Primary      Linux raid autodetect                         263.21
    hda2 Primary      Linux raid autodetect                         518.20
    hda5 Logical      Linux raid autodetect                        8200.61
    hda6 Logical      Linux raid autodetect                        2048.10
    hda7 Logical      Linux raid autodetect                        1028.16
    hda8 Logical      Linux raid autodetect                         863.66

ここで、ついでに /dev/hdc の残り容量を切りなおしてswap用の領域を作成しておきたいところだが、いま /dev/hdc のパーティションテーブルを操作してはいけない。RAIDに参加しているパーティションが含まれているディスクにそんなことをするとデータが破壊されてしまうのである。

ていうわけで後回し。

RAID構成ファイルの編集

次に、/etc/raidtab を編集。failed-disk のところを raid-disk に変更する。また、swap用の /dev/md5 の設定を追加する。以下は追加部分だけ。

    # swap
    raiddev                 /dev/md5
    raid-level              1
    nr-raid-disks           2

    nr-spare-disks          0
    persistent-superblock   1
    chunk-size              32

    device                  /dev/hda8
    raid-disk               0
    device                  /dev/hdc8
    failed-disk             1

swap領域については、まだ /dev/hdc8 を切っていないので、おなじみの failed-disk である。

ミラーリング開始

設定ファイルを保存したら、早速ディスクをRAIDアレイに追加する。再構築はすべてバックグラウンドで行われるし、再構築中にRAIDアレイに対して読み書きすることも可能。つまり、RAID再構築中でも普通に使えるし、待っていれば勝手に2重化が完了するということ。

    root@host# raidhotadd /dev/md0 /dev/hda2

    /proc/mdstat を見ると、再構築の様子が見える
    
    root@host# cat /proc/mdstat
    md0 : active raid1 hda2[2] hdc2[0]
          499904 blocks [2/1] [U_]
          [===>.................]  recovery = 15.9% (80192/499904) finish=0.6min speed=11456K/sec

    同じように、他のRAIDアレイも再構築する
    root@host# raidhotadd /dev/md1 /dev/hda1
    root@host# raidhotadd /dev/md2 /dev/hda5
    root@host# raidhotadd /dev/md3 /dev/hda6
    root@host# raidhotadd /dev/md4 /dev/hda7

    そして、swap用のRAIDアレイを作成
    root@host# mkraid /dev/md5

/etc/fstabを修正。swap領域を /dev/hda2 から /dev/md5 に変更する。

そして、スワップを有効にする。ところが…

    root@host# swapon -a -v
    swapon on /dev/md5
    swapon: /dev/md5: Invalid argument

と怒られたので調べると、スワップ領域も初期化が必要ならしいことがわかった。

    root@host# mkswap /dev/md5

として、再度 swapon を実行すると今度はうまくいった。

しばらく /proc/mdstat の様子を見る。さすがに8GB割り当てた /usr のアレイの再構築にはそこそこ時間がかかっていたようだが、ものの数十分でアレイの再構築がすべて終わった。

その後やった作業

もとのHDDからもRAIDが起動するようにする

すべての作業が完了したのを見計らって、/etc/lilo.conf.hda を作成。/etc/lilo.conf.hdc をコピーして、ディスクのパラメータ部分と、boot=/dev/hdc のところを boot=/dev/hda とを、それぞれ書き換えて、2台目のHDDメニューを呼び出す記述を書き加えればよい。

    root@host# lilo -v -C /etc/lilo.conf.hda

これで1台目のHDDからもRAIDで起動できるはず。ここでもう一回再起動して、うまく起動できるかどうか調べる。出来なければ2台目から起動して直す。

swap領域も完全なRAIDにする

もはやRAIDの大部分が完成してしまっているので、それぞれのHDDのパーティションを切りなおすことは出来ない。やった瞬間にデータが死ぬ。そこで、レスキューフロッピーから起動して作業をする。

/dev/hda8 よりもちょっと大きめに /dev/hdc8 を切る。

またHDDから起動して、/etc/raidtab を書き換え(swap用の /dev/md5 の failed-disk を raid-disk に書き換えた)、hotaddする。

    root@host# raidhotadd /dev/md5 /dev/hdc8

しばらく待てば完了。

おまけ

/dev/hda8 を切ったついでに、残りの領域に /dev/hdc9 を切っておいたので、それも使えるようにする。とりあえずは公開用の領域という位置づけという意味で /home/pub にわり当てることにした。

    root@host# mkreiserfs /dev/hdc9
    root@host# mkdir /home/pub
    root@host# mount /dev/hdc9 /home/pub

次回以降は自動的にマウントされるように、/etc/fstab を編集して

    /dev/hdc9 /home/pub reiserfs  defaults  0  0

という行を追加し、システムのディスク構成がようやく終わった。

再起動しても無事にRAIDを認識して起動するのを見るのは気分がいいものである。


Last Update: Tuesday, 03-May-2005 21:44:17 JST

Copyright© 1999-2003,Gensui