2009年10月26日月曜日

MBRと"/boot"をバックアップして障害に備える、CentOSでiSCSI活用(前編)

CentOS5のインストーラは、iSCSIのデバイスを認識できるのでので、このような環境を作ってみた。
"/boot"をローカルに置き、ほかは全部iSCSI。
 






















用途 場所 dev?
/boot ローカルディスク /sdb1
SWAP ローカルディスク /sdb2
/ iSCSI /sda1

 

図でみるとこんな感じだ。
 

[caption id="attachment_1516" align="alignnone" width="348" caption="画像:Linux+iSCSI"]画像:Linux+iSCSI[/caption]
 


NICがiSCSI起動に対応していれば、しょっぱなからiSCSIいけたものを。。。
だがこれはこれで面白い環境なので気にいっている。
 


しかしこの環境、"/"はiSCSI経由、ZFSの上にいてるので大分堅牢になっている、データの消失は皆無といってよく、パフォーマンスも申し分ない。
ただ、ローカルディスクが1台なのだ。これがぶっ壊れたらさあどうすんのよと思ったので色々試してみた。
 
 


結論から言うと「/boot をdumpでダンプしておく」または「ddでMBRから/bootの領域までを全部書き出しておく。」というやり方で復旧が可能となる。
あ、あとはgrubのCDboot環境かな。
 

せっかくなのでそこに至る過程を述べておこう、まあ今回は結局のところgrubが何やってるかを調べたと同義かなあ。
 
 

通常起動で"/"をiSCSIでマウントするまでの過程


とりあえずこの環境がどのようなプロセスをたどって起動されるか、これがよくわからんようでは安心して眠れない。
ということで簡潔にブートプロセスを追ってみよう。
 


  1. PCが起動される
     

  2. ローカルHDDが認識され、MBR(第1セクタ)にあるgrubのステージ1が読み込まれる、MBRにはパーティションテーブルもある
     

  3. grubのstage1はstage1.5を読むためにある。次のセクタを読むようにstage1は終了し、第2セクタより始まるstage1.5を読む
     

  4. stage1.5が読み込まれる、これは"/boot"のファイルシステム(ext3)に合わせたものが入っている
     

  5. ext3を理解するstage1.5は、"/boot/grub"にあるgrubのstage2をちゃんとファイルシステム上のファイルとして認識、読み込み
     

  6. stage2に制御が移ったら、hdd上のinitrdを実行することが出来る
     

  7. initrdはiSCSIのドライバを利用できる、ここでiSCSIデバイスをマウントする
     

  8. マウントされたiSCSIデバイスからラベルが"/"のパーティションを見つける
     

  9. "switchroot"!、iSCSIのデバイスは見事"/"としてマウントされ、Linuxの起動シーケンスは続く
     


 

簡潔...どうにか簡潔か。
最初に見つけるのをまよったのはstage1.5の場所、MBRと/bootの間であるHDDの第2セクタから第63セクタは使われているんだなあ。
 

さて、この環境が起動するプロセスはよくわかっただろうか。
iSCSIの辺りは"initrd"を展開すると、initスクリプトに全部書いてあるので、見てみるといいだろう。
 
 



hddの基本構造が同じなら、ddだけでいい


さて、grubがしてくれることは判った。
 

ということで、最初に出した環境をローカルディスクの破壊から救うということは、grubのstage1から1.5 と、stage2,initrdとカーネルイメージが入った"/boot"をちゃんと復旧できるようにするということにほかならない。
 

それならそこまでそのままダンプしちゃえばいいんだ、HDDの構造が一緒のもの※に換装する場合に限るが。
※現行なら、1セクタが512バイトで、かつシリンダあたりのセクタ数が63のものになるだろう。大体そうだよね、vhdですらそうしている。


ちなみにmbrのバックアップについて、ddで512バイト書き出して、446バイト(stage1)を戻せ!と書いてある記事などあるが、ありゃあ不十分な嘘っぱちだ。
マジックナンバーがあるからな、512バイト中ケツの2バイトも戻してやらんことには話にならん。

 
 

それじゃあローカルのhddの情報を見てみる、復旧の検証用に作ったほうなので容量が変だけど。
 

# hdparm -g /dev/sdb1
 
/dev/sdb1:
geometry = 60801/255/63, sectors = 530082, start = 63
# hdparm -g /dev/sdb2
 
/dev/sdb2:
geometry = 60801/255/63, sectors = 8385930, start = 530145

 

このケースでは"/boot"にええと、512MBとったんだっけ?SWAPには256MBくらいとった。本番はもうちょっとSWAP多目。
 

この場合、/sdb の1から63セクタが1シリンダ目(=/bootより前の領域)なので、/bootは63から始まっていて、SWAPの/sdb2は530145セクタ目から始まっているというのが判る。
ってことで、530145セクタ までddで出しちゃえばいい、これで狙った範囲は丸ごと取得できる。SWAPはどうでもいい。
 

こんな感じ。
dd if=/dev/sdb of=./mbr_boot count=530145
bs=512はデフォルトなので省略。
あとは書き出した"mbr_boot"をどこかに保管しておけばいい。
ローカルのhddがぶっ壊れてしまった場合、とっておいたイメージを書き戻すだけでいい。
dd if=./mbr_boot of=/dev/sda
かな、復旧中はiSCSI多分関係ないからsdaだ、復旧には適当なCDブートのLinuxでも使おう。
 
 

これでこの環境は起動するようになる、簡単だ。
 
 

mbrと/bootだけ戻したら起動するんだが、SWAPがおかしくなったりする。インストール時に設定したのみだと特に。
こんな感じ
# swapon -a
swapon: cannot find ther device dor LABEL=SWAP-sda2

 

mkswapするだけで元通りだ、SWAPスペースにはddする価値はないのであえて放っておいた。
 

#mkswap -L SWAP-sda2 /dev/sdb2
Settiong up swapspace version 1, size = 271426 kb
LABEL=SWAP-sda2, no uuid
 
#swapon -a

これで元どおりの環境が復活する。
 
 



さて、冒頭で述べた"/boot"だけ バックアップしておくという手段は結構復旧に手間がかかるが、hddの構造に依存しないのでとっておくべき。
次の記事で/bootだけdumpしてる際の復活方法を書いておきたいが、まあ大体わかるよね?
 
 

後編に続く
 
 

おまけ:復旧につかうツール


CentOSのLiveCDとか結構いいと思う、初期状態でNFSが使えるのでファイルを持ってくるのに便利だし、dump&restoreとかもyumですぐ導入できる。
もちろんddは使える。
 

あとはgrubの起動CDは作っておいたほうがいいだろう
ブータブルなGrubは重宝すると思う、作り方は公式に。
>> grub公式のgrub bootableCD作成方法