7
7

More than 1 year has passed since last update.

LinuxでルートファイルシステムをRAID+bcache化する

Last updated at Posted at 2019-09-14

背景と概要

Linuxで高速大容量ストレージを安価に組みたい!

現状のストレージのコスト感

デバイスタイプ 価格帯
HDD 4TB 0.8〜2万
SSD(SATA) 4TB 6〜9万
SSD(NVMe) 2TB 2〜4万

という時代に、Linuxで4〜8TB程度のRAID1ストレージのマシンをこさえるというシチュエーションです。

SSDが安くなってきたとは言え、容量単価はまだHDDの5倍くらいの感覚です。4TBでSSDでRAID1を組もうと思ったら10万円コースですし、その容量だとNVMeはまだ出てこないのでSATAのSSDになってしまいます。

そこで、容量と速度のいいトコ取りをお値打ち価格で、を目指してファイルシステム全体を HDDのRAID1 + SSDキャッシュ の構成で組むことにしました。SSDキャッシュ化はbcacheを使います。
RAIDはいらないけどファイルシステム全体をbcacheで高速にしたい、というケースでも似たような手順になるかと思います。

実際に使用するマテリアル、その他

HDD 6TB x 2 + NVMe SSD 1TB (合計3.5万円)
Ubuntu 18.04 LTS をインストールメディアで入れます。(Ubuntu 20.04, 22.04 でも以下手順で確認済み)
UEFIブートします。

インストール手順

全体の流れ

インストーラはbcacheに対応していませんので、通常のパーティションに仮インストールをしたのち、ファイルシステムを構成してから本環境にデータを移動する流れになります。

最終形イメージ

デバイス マウントポイント
HDD /boot/efi
HDD /boot
bcache (backing=HDDのRAID1, cache=SSD) /

通常のデスクトップ用であればESPや/bootはSSDに置く方が起動が高速になって良いかもしれません。今回は立ち上げっぱなしのサーバ用途なので、起動の速さはどうでもよくってキャッシュ容量を最大化するためSSDを丸ごとキャッシュにしました。

パーティショニング

起動: live media
最初にUSBメモリ等のlive mediaを使って(インストールせずに)起動し、gdiskでパーティションを以下のように切っておきます。
(2019-09-18 修正: 障害時にHDD交換しやすいように、左右対象にしました。交換時には /etc/fstab を調整するなりして残すHDDだけで起動できるようにする手順になります)

sda, sdb: HDD (6TiB)
nvme0n1: NVMe SSD (1TiB)

として認識されています。

sda:
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048          499711   243.0 MiB   EF00  EFI System Partition
   2          499712         4196351   1.8 GiB     8300  Linux filesystem
   3         4196352     11721045134   5.5 TiB     8300  Linux filesystem

sdb:
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048          499711   243.0 MiB   EF00  EFI System Partition
   2          499712         4196351   1.8 GiB     8300  Linux filesystem
   3         4196352     11721045134   5.5 TiB     8300  Linux filesystem

nvme0n1:
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048      2000409230   953.9 GiB   8300  Linux filesystem

仮インストール

このうち、以下のパーティションを使用してUbuntuを仮インストールします。

デバイス ファイルシステム マウントポイント
/dev/sda1 EFI /boot/efi
/dev/sda2 ext4 /boot
/dev/nvme0n1p1 ext4 /

sda3とsdb3はのちほどRAIDを組むパーティションで、ここでは使いません。
またsdb1とsdb2は、sdb単体でもブートできるように後ほどsda1とsda2と等価になるようにします。

/ がSSDなので速いですね。すぐに終わります。

パッケージ更新と追加

再起動: 仮インストールしたシステム
インストールしたシステムを起動し、パッケージの更新およびRAIDとbcacheに必要なパッケージの追加をします。

sudo apt-get udpate
sudo apt-get install mdadm
sudo apt-get install bcache-tools

RAID + bcache でファイルシステム作成

RAID1を組み、それを使用してbcacheデバイスを作成します。ここではまずバッキングデバイス(HDD RAID)だけを登録し、あとでSSDが空いたらキャッシュデバイスとして追加します。

sudo mdadm --create /dev/md0 --level=raid1 --raid-device=2 /dev/sda3 /dev/sdb3
(※再起動するとIDが変わって /dev/md127 になったりするので注意)
sudo modprobe bcache
sudo /usr/sbin/make-bcache -B /dev/md0
sudo mkfs.ext4 /dev/bcache0

仮インストールしたルートファイルシステムをbcacheに移動

2021.02.08: 以下、ルートファイルシステムの移動のためlive mediaから起動しなおしてコピー操作していましたが、そのままの状態で次のコマンドでコピーできるので記述修正しました。GNU tarはextended attributeをサポートしないなどファイルシステムのコピーには問題がある可能性がありそうなので、bsdtarを使います。--one-file-system は別ファイルシステムがマウントされている先をアーカイブの対象にしないオプションで、この場合 /boot /sys /proc /dev などをコピーしないためのものです。

sudo mount /dev/bcache0 /mnt
sudo apt-get install bsdtar  # (ubuntu-20.04 以降は sudo apt-get install libarchive-tools)
sudo bsdtar cvpf - --one-file-system / | sudo bsdtar xvpf - -C /mnt

fstabを修正してgrub更新、再起動

bcache0のUUIDを調べます。

ls -l /dev/disk/by-uuid
合計 0
lrwxrwxrwx 1 root root  10  9月 12 16:31 12732d48-4b0d-464f-938a-66fceca525f7 -> ../../sdb1
lrwxrwxrwx 1 root root  10  9月 12 16:31 1EE3-33F7 -> ../../sda1
lrwxrwxrwx 1 root root  11  9月 12 16:31 935f09e9-1aaf-4243-b433-974d83427b7d -> ../../md127
lrwxrwxrwx 1 root root  10  9月 17 11:09 b131c455-8bdb-4486-bf50-2f12140c9b37 -> ../../sda2
lrwxrwxrwx 1 root root  10  9月 17 11:09 a5a262cb-5016-44b6-9b62-bd139ed7784d -> ../../sdb2
lrwxrwxrwx 1 root root  13  9月 12 16:31 ab55455c-c7ea-4e36-9101-ac82e4571e33 -> ../../bcache0
lrwxrwxrwx 1 root root  15  9月 12 16:31 f7952b71-49b7-41a4-9e5c-54b33ab166b3 -> ../../nvme0n1p1

/mnt/etc/fstabの / のエントリを、bcache0に変更します。

# / was on /dev/nvme0n1p1 during installation
# UUID=f7952b71-49b7-41a4-9e5c-54b33ab166b3  /  ext4  errors=remount-ro  0  1
# / on /dev/bcache0
UUID=ab55455c-c7ea-4e36-9101-ac82e4571e33  /  ext4  errors=remount-ro  0  1

本番ファイルシステム構成を再現した状態でgrubを更新

sudo mount -B /dev /mnt/dev
sudo mount -B /proc /mnt/proc
sudo mount -B /sys /mnt/sys
sudo mount /dev/sda2 /mnt/boot
sudo mount /dev/sda1 /mnt/boot/efi
sudo chroot /mnt
grub-install --recheck /dev/sda
update-grub

今動いているSSDのシステムも検出してしまいますが、後でもう一度更新します。

再起動: 本システム
再起動すると bcache0 が / になってブートします。

df
 (必要なものだけ抜粋)
/dev/bcache0         5811055832   48770652 5469354184   1% /
/dev/sda2               1998672     120548    1756884   7% /boot
/dev/sda1                244988       6201     238787   3% /boot/efi

bcacheにキャッシュデバイスを追加

これでSSDを使わずにブートができたということになるので、仮インストールをしたSSDを潰してキャッシュにすることができます。

sudo wipefs -a /dev/nvme0n1p1
sudo make-bcache -C /dev/nvme0n1p1
UUID:           f7952b71-49b7-41a4-9e5c-54b33ab166b3
Set UUID:       333480d8-9c84-4cda-8c4c-82029e85eed6
 :

echo 333480d8-9c84-4cda-8c4c-82029e85eed6 | sudo tee /sys/block/bcache0/bcache/attach

bcacheの状態確認

ls /sys/block/bcache0/slaves
md127  nvme0n1p1
sudo bcache-super-show /dev/md127
sb.magic        ok
sb.first_sector     8 [match]
sb.csum         4DC6313D63E40B61 [match]
sb.version      1 [backing device]

dev.label       (empty)
dev.uuid        935f09e9-1aaf-4243-b433-974d83427b7d
dev.sectors_per_block   1
dev.sectors_per_bucket  1024
dev.data.first_sector   16
dev.data.cache_mode 0 [writethrough]
dev.data.cache_state    1 [clean]

cset.uuid       333480d8-9c84-4cda-8c4c-82029e85eed6

cset.uuidが先ほどセットしたUUIDになり、 cache_stateが [clean] になっています。(attachする前は [detached])

最後に両方のHDDにgrubをインストール

sdbの方は今やらなくてもよいのですが、一応両方のHDDにgrubをインストールしておきます。

sudo grub-install --recheck /dev/sda
sudo update-grub

# copy sda1, sda2 -> sdb1, sdb2
sudo mkfs.vfat -F32 /dev/sdb1
sudo mkfs.ext4 /dev/sdb2
sudo mount /dev/sdb2 /mnt
sudo mkdir /mnt/efi
sudo mount /dev/sdb1 /mnt/efi
sudo cp -a /boot/* /mnt
sudo umount /mnt/efi
sudo umount /mnt

sudo mount /dev/sdb2 /boot
sudo mount /dev/sdb1 /boot/efi
sudo grub-install --recheck /dev/sdb
sudo update-grub
sudo umount /boot/efi
sudo umount /boot

これで完成です。
6TB RAID1でSSDキャッシュの効いたルートファイルシステムが完成しました。


補足

一旦作ってしまったbcacheデバイスを止めたいときは以下のようにします。

echo 1 | sudo tee /sys/block/bcache0/bcache/stop
sudo wipefs -a /dev/md127
7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7