2017年10月22日

【備忘録】LinuxソフトウェアRAIDの構成変更

今まで自宅サーバは/bootパーティションがRAID 1、それ以外のパーティションをLVMにまとめてRAID 5のソフトウェアRAIDで運用していたのですが、ハードディスクを大きなものに交換したのをきっかけにRAID 5からRAID 1に移行することにしました。
RAID 5だとハードディスク2台同時故障(実際に一度経験がある)とかdata corruptionとかの心配がありますし、まあ2台同時故障への対応ならRAID 6にするという手もあるのですが面倒だし、容量の問題さえなければRAID 1のほうがシンプルでいいじゃん!と考えたわけです。
2台同時故障に対応するためにはRAID 1で3重化することになります。つまり提供する容量の3倍のハードディスクが必要になるわけです(3台構成のRAID 5だと1.5倍で済む)。ハードディスクの容量が小さかった昔はこれが大問題でしたが、今はハードディスクの容量はあり余っているのが普通なので問題にはなりません。
変更前と変更後の構成を示しておきます(容量はわかりやすいように実際の数字ではなく切りの良い数字にしてあります)。

変更前の構成:
sda = sda1(1GB) + sda2(50GB)
sdb = sdb1(1GB) + sdb2(50GB)
sdc = sdc1(1GB) + sdc2(50GB)
md0 = RAID1(sda1 + sdb1 + sdc1) -> /boot (1GB)
md1 = RAID5(sda2 + sdb2 + sdc2) -> LVM -> /, /usr, /home, ... (100GB)

変更後の構成:
sda = sda1(1GB) + sda2(100GB)
sdb = sdb1(1GB) + sdb2(100GB)
sdc = sdc1(1GB) + sdc2(100GB)
md0 = RAID1(sda1 + sdb1 + sdc1) -> /boot (1GB)
md1 = RAID1(sda2 + sdb2 + sdc2) -> LVM -> /, /usr, /home, ... (100GB)

構成変更の手順は次のようになります。
(1) どこかに100GBの作業領域を確保する(sda3とします)
(2) LVMをmd1からsda3に移す
(3) md1を停止、sdb2, sdc2のパーティションを100GBで切り直す
(4) sdb2 + sdc2でmd1(RAID1)を構築
(5) LVMをsda3からmd1に移す
(6) sda3を消し、sda2のパーティションを100GBで切り直す
(7) md1にsda2を追加

ところで、ハードディスクのパーティションを切り直した後はその変更がカーネルに認識されないことがあり、リブートが必要となります。kpartxを使うとリブートしなくても認識されるという説もあるのですが、私の場合は実際に試してみたのですがkpartxではダメで、リブートする必要がありました。
つまり上の手順の (3) と (4) の間、(6) と (7) の間でリブートすることになります。
(3) と (4) の間のリブートはうまく行ったのですが、(6) が終わってリブートしたら「rootファイルシステムが見つからない」と言ってinitramfsのシェルに落ちてしまい、ちょっと焦りました。

調べてみたところ、md1がスタートしていないようです。ソフトウェアRAIDの情報はinitramfs上に書き込まれるので、ソフトウェアRAIDを構成変更したらinitramfsを作り直さないといけなかったんですね…。
initramfsのシェル上で
mdadm --assemble /dev/md1 /dev/sdb2 /dev/sdc2
としてmd1は起動できたんですが、ここからLVM上の論理ボリュームをカーネルに認識させる方法がわかりません。lvsで見ると論理ボリュームは存在しているのですが、ブロックデバイスファイルが作成されていないため、シェルをexitしてもまた「rootファイルシステムが見つからない」と言われてしまうんですよね。

実はlvdisplayで見るとわかるんですが、論理ボリュームがinactiveになっていました。これをアクティブにするには
vgchange -a y
とします。この状態からinitramfsのシェルをexitすると、無事にファイルシステムがマウントされてブートが継続し、コマンドプロンプトが表示されました。ふう、一時はどうなることかと思ったぜ…。

上記手順で使用した具体的なコマンドなどは、実際に作業する人しか興味がないと思いますので、「続きを読む」の後に書いておきます。

作業に使用したコマンド:

(1) どこかに100GBの作業領域を確保する(sda3とします)
# fdisk /dev/sda
sda3として100GBのパーティションを切り、typeを8e (Linux LVM) に設定

(2) LVMをmd1からsda3に移す
# pvcreate /dev/sda3
# vgextend vg0 /dev/sda3
# pvmove -i 300 /dev/md1 /dev/sda3
# vgreduce vg0 /dev/md1
# pvremove /dev/md1
pvmoveの「-i 300」というオプションは、5分ごとに進捗状況を表示させるためのものです(1時間くらいかかるので)

(3) md1を停止、sdb2, sdc2のパーティションを100GBで切り直す
# mdadm --stop /dev/md1
# fdisk sdb
sdb2を削除して100GBで再作成、typeをfd (Linux raid autodetect) に設定
# fdisk sdc
sdc2を削除して100GBで再作成、typeをfd (Linux raid autodetect) に設定
ソフトウェアRAIDの構成が変わったのでinitramfsを更新
# update-initramfs -u
パーティションの変更をカーネルに認識させるためリブート
# reboot

(4) sdb2 + sdc2でmd1(RAID1)を構築
# mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sdb2 /dev/sdc2
RAIDの構成が終わるのを待つ(cat /proc/mdstatで進捗状況が確認できる)
initramfsを更新
# update-initramfs -u

(5) LVMをsda3からmd1に移す
# pvcreate /dev/md1
# vgextend vg0 /dev/md1
# pvmove -i 300 /dev/sda3 /dev/md1
# vgreduce vg0 /dev/sda3
# pvremove /dev/sda3

(6) sda3を消し、sda2のパーティションを100GBで切り直す
# fdisk sda
sda2, sda3を削除してsda2を100GBで再作成、typeをfd (Linux raid autodetect) に設定
パーティションの変更をカーネルに認識させるためリブート
# reboot

(7) md1にsda2を追加
# mdadm --add /dev/md1 /dev/sda2
# mdadm --grow --raid-devices=3 /dev/md1
RAIDの再構成が終わるのを待つ(cat /proc/mdstatで進捗状況が確認できる)
initramfsを更新
# update-initramfs -u
ここで念のためリブートし、md1が3台構成で上がってくることを確認して完了です。
posted by ぽそこし at 10:00| Comment(0) | 備忘録 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス: [必須入力]

ホームページアドレス:

コメント: [必須入力]

※ブログオーナーが承認したコメントのみ表示されます。