余ったSSDを有効活用しようと思っただけなのに、SeaweedFS基盤が生えてしまった話

it-tech

はじめに

自宅には、過去に廃棄したノートPCから取り外したSSDやHDDがいくつか残っていました。

どれも正常に動作するものの、引き出しの中で長年眠っている状態でした。

当初の目的は非常にシンプルです。

まだ使えるストレージを有効活用できないだろうか

というものでした。

まさか後にSeaweedFSによるストレージ基盤構築へ発展するとは、この時点ではまったく思っていませんでした。


ストレージを棚卸ししてみた

まずは手元のストレージを整理してみました。

すると意外なことに、

240GB SSD ×2
1TB HDD ×2

という具合に綺麗にペアになっていました。

そこで最初に思ったことは、

RAID1が組めるのでは?

ということでした。


RAID1構成を採用

今回使用したのはRATOC製のRAIDケースです。

RS-EC22-U31R

このケースに240GB SSDを2台搭載し、ケース側でハードウェアRAID1を構成しています。

構成は次のようになります。

240GB SSD
240GB SSD
     ↓
RS-EC22-U31R
     ↓
   RAID1
     ↓
  USB3.0
     ↓
Raspberry Pi 4B

Linux側でmdadmによるソフトウェアRAIDを構築しているわけではなく、RAIDケース側でミラーリングを行っています。

そのためRaspberry Piからは単一のストレージとして認識されます。

実際には以下のようにマウントされています。

findmnt /srv/seaweedfs
TARGET         SOURCE    FSTYPE OPTIONS
/srv/seaweedfs /dev/sda1 ext4   rw,relatime

実はUPSも眠っていた

ストレージを整理している最中に気付いたことがあります。

実は以前サーバー用途で使用していたUPSも自宅に残っていました。

使用しているのは、

Dell-APC Smart-UPS 1500VA

です。

そのため今回のプロジェクトでは、

SSD RAID1
    +
Smart-UPS 1500VA

という構成を最初から実現できました。

つまり、

  • ストレージ障害対策
  • 停電対策

の両方を考慮できる状態だったのです。

ここで、

単なる外付けストレージではなく、きちんと運用できる基盤を作ろう

という方向へ考えが変わりました。


なぜSeaweedFSを選んだのか

一般的であれば、

  • NASを購入する
  • Samba共有を作る
  • USBストレージとして使う

あたりが選択肢になると思います。

しかし今回の目的は、

  • 余剰資産を活用する
  • 将来の拡張性を確保する
  • 古いストレージを有効活用する

ことでした。

そこで候補として浮上したのがSeaweedFSです。


SeaweedFSのディレクトリ構成

保存先はSSD RAID1上の

/srv/seaweedfs

です。

構成は以下のようにしました。

/srv/seaweedfs
├─ master
├─ volume
└─ filerldb2

作成時には以下のコマンドを使用しました。

sudo mkdir -p /srv/seaweedfs/{master,volume,filerldb2}
sudo chown -R user:user /srv/seaweedfs

Masterの構築

まずはMasterです。

weed master \
  -mdir=/srv/seaweedfs/master \
  -port=9333 \
  -port.grpc=19333 \
  -ip=100.xxx.xxx.xxx \
  -ip.bind=100.xxx.xxx.xxx

正常に起動すると、

curl http://127.0.0.1:9333/cluster/status

以下のような応答が返ります。

{"IsLeader":true}

Volumeの構築

続いてVolumeを構築します。

weed volume \
  -dir=/srv/seaweedfs/volume \
  -max=0 \
  -mserver=100.xxx.xxx.xxx:9333 \
  -ip=100.xxx.xxx.xxx

VolumeがMasterへ登録されると、

curl http://127.0.0.1:9333/dir/status

で登録状況を確認できます。


Filerの構築

最後にFilerを構築します。

weed filer \
  -master=100.xxx.xxx.xxx:9333 \
  -ip=100.xxx.xxx.xxx \
  -ip.bind=100.xxx.xxx.xxx \
  -defaultStoreDir=/srv/seaweedfs/filerldb2

起動後は、

curl http://127.0.0.1:8888/

でHTTP 200が返れば正常です。


一番苦労したのはsystemd化だった

SeaweedFSの構築自体は比較的素直に進みました。

しかし実際に苦労したのは、再起動後も確実に復旧する仕組みの設計です。

手動起動では運用になりません。

そこでsystemd化を実施しました。


SeaweedFSの依存関係

SeaweedFSは単純に3つのプロセスを起動すれば終わりではありません。

各サービスに依存関係があります。

SSD RAID1
(/srv/seaweedfs)
        │
        ▼
SeaweedFS Master
(9333 / 19333)
        │
        │ Leader選出
        ▼
SeaweedFS Volume
(8080 / 18080)
        │
        │ Master登録
        ▼
SeaweedFS Filer
(8888 / 18888)

起動シーケンス

systemdでは以下の順番で起動するよう設計しています。

Raspberry Pi起動
    │
    ▼
SSD RAID1マウント
    │
    ▼
Master起動
    │
    ▼
Leader選出完了
    │
    ▼
Volume起動
    │
    ▼
Master登録
    │
    ▼
Filer起動
    │
    ▼
利用開始

Volumeの起動条件

VolumeはMasterがLeaderになったことを確認してから起動します。

curl http://127.0.0.1:9333/cluster/status

Leader選出が完了するまで待機する仕組みです。


Filerの起動条件

FilerはVolumeがMasterへ登録されたことを確認してから起動します。

curl http://127.0.0.1:9333/dir/status

Volume登録を確認した後に起動します。


再起動試験

systemd化後は実際にRaspberry Piを再起動して確認しました。

systemctl is-active \
  seaweedfs-master \
  seaweedfs-volume \
  seaweedfs-filer
active
active
active

さらにポートも確認しています。

sudo ss -lntp | grep -E \
  ':(9333|19333|8080|18080|8888|18888)\b'

すべて正常に待ち受けていることを確認できました。


気付けばストレージ基盤になっていた

最初の目的は、

余ったSSDを有効活用したい

ただそれだけでした。

しかし現在は、

  • OCI上のTeslaMate
  • 将来導入予定のZabbix
  • 構成ファイル
  • 技術資料
  • ブログ資産

などを保管するホームラボ共通ストレージとしての役割を担い始めています。


今後の計画

今回完成したのは序章です。

今後は、

1TB HDD ×2
    ↓
  RAID1化

Pi4B 2号機追加

SeaweedFSクラスタ化

TeslaMate長期保管

Zabbix連携

を予定しています。


まとめ

今回のプロジェクトは、

SeaweedFSを使ってみたかった

から始まったわけではありません。

むしろ、

余ったSSDやHDDを有効活用したい

という非常に単純な発想から始まりました。

ところが気付いてみると、

RAID1
Dell-APC Smart-UPS 1500VA
SeaweedFS
systemd自動復旧

を備えたホームラボ向けストレージ基盤になっていました。

まだ完成ではありません。

むしろ今回の構築は序章です。

次回は、余っている1TB HDD×2をRAID1化し、SSD層とHDD層を持つ二層構造ストレージへ発展させていきたいと思います。

最後に一言。

「余ったSSDを使おう」と思っただけだったのに、気付いたら小規模データセンターみたいな構成になっていました。😅

これが今回のプロジェクトを最も正確に表している気がします。

コメント

タイトルとURLをコピーしました