猫の手なら貸せる

いろいろ共有できたらいいなとおもってます

ラズパイ4でRAID1 NASを構築した

うちのRaspberryPi 4は、HDDを3枚使って2枚をソフトウェアRAID1のNAS、1枚を非RAIDNASとして現在絶賛稼働中です。

RAIDを採用してた時代もありました。今見るとパーティション切ってたりまあまあ危険な構成。 現在ではディスクではなくラズパイ自体を並列につないで負荷分散することで、ディスク3枚でミラーリングNASを稼働させています。

暇になったらクラスタリングの構築方法も書き起こそうと思っています。いまだにRAIDで検索してる人が多いのでモチベ的にも当分先でしょう。

以下はRAID1構成で稼働してた時に作成した備忘録です。

環境

アカウント

機器選定

Amazonだったりツクモだったりそのほかのショップだったり。

主要機器

バイス 役割 備考
RaspberryPi 4(4GB) サーバ Raspbian busterを使用
SDカード 内蔵ストレージ ラズパイ用
BUFFALO 外付けHDD(1TB) ストレージ RAID1-NAS用。3.5インチ、外部電源
IO-DATA 外付けHDD(2TB) ストレージ RAID1-NAS用。3.5インチ、外部電源
東芝 MQ04ABD200(2TB) ストレージ RAID-NAS用。2.5インチ、バスパワー

ケーブル類

バイス 役割 備考
UGREEN USB Type C ケーブル USBケーブル ラズパイ電源供給用。C先端がL字
エムエスプロダクト LP-ATCC01BK USBケーブル ラズパイとHDDの接続用、15cm。廃盤
付属ケーブル類 USBケーブル・ACアダプタ等 外付けHDD等の付属品

その他

バイス 役割 備考
高速冷却アルミ合金製保護ラズベリーパイ4ケース サーバケース ケース自体がヒートシンクになるタイプ。
エアリア 2.5インチ HDD SSD ケース HDDケース MQ04ABD200 収納用
ELUTENG USB FAN 8cm 冷却ファン ファン 夏場は必要かと思い、一応配置

構成図

機器紹介でRAID用のデバイスのサイズが一致していなかったり非RAIDだったりちょっとわかりにくいので図に描き起こしたものを掲載しておきます。

f:id:nkhnd:20200409124852p:plain

2TBのディスクはパーティションを切って1TB分だけRAID1に利用しています。

また、2.5インチのディスクについてはラズパイから外して利用することもあるため、RAIDには組み込んでいません。

RaspberryPiのセットアップ

初期設定

SDカードにRaspbian Buster Liteを書き込みます。以下からダウンロードします。

www.raspberrypi.org

面倒くさかったので書き込みにはbalenaEtcherを利用。

www.balena.io

Raspberry Pi Imagerを使う方法

(以下過去の文章)


ちなみに、公式でラズパイのイメージを書き込むソフトウェアが出てました。

Raspberry Pi Imagerというソフトで、WindowsMacUbuntuでbalenaEtcherのようなことができます。

f:id:nkhnd:20200417163242p:plain

今回はオンラインダウンロードではなく、あらかじめ持っていたRaspbian buster Liteのイメージを利用。ディスクユーティリティーで書き込み可能な4GBの仮想ディスクを作成し、書き込んでみます。

f:id:nkhnd:20200417163731p:plain

いい感じですね!完成した仮想イメージをマウントすると。。。

f:id:nkhnd:20200417164132p:plain

GPTで作ったのが自動的にマスターブートレコードに変更され、パーティションの切られたディスクが作成されました!

今回はイメージを落としてきたのでbalenaEtcherと変わりませんが、Raspberry Pi Imagerではそういったファイルを自動的にダウンロードしてきて書き込んでくれる機能があるみたいです。

Raspbianだけではなく、Raspberry Pi上で動くとされるバージョンのUbuntu等もインストールが可能。

f:id:nkhnd:20200417164349p:plain

新規ユーザーはぜひ上を利用しましょう。


不具合の原因が分かるまでは、balenaEtcherを利用する方が良さそうです。

SDカードへOSをインストールしたら、まずSSHを有効にしましょう。キーボードもマウスも不要です。

焼き終わったSDカードのbootパーティションsshというファイルを配置します。

% cd /Volumes/boot
boot % touch ssh
boot % ls | grep ssh
ssh*

次にラズパイにWifi設定を入れます。
あらかじめWifi設定を入れておくことで、初回からLANケーブルやディスプレイをつかわずSSH接続が可能です。

jyn.jp

wpa_supplicant.confはこのサイトを利用すると簡単に作成できます。

mascii.github.io

作成したwpa_supplicant.confをbootにコピーしたら、SDカードをラズパイに差し込んで起動します。

起動後の初期設定

ひとまず接続できたら、IPアドレスの設定をします。初期設定であればraspberrypi.localで接続は可能ですが、固定してあると管理の際に役に立つ時があります。

~ $ sudo vi /etc/dhcpcd.conf
...(編集)...
~ $ cat /etc/dhcpcd.conf
...(省略)...
#wlanインターフェースの自動設定
interface wlan0
 ssid <wpa_supplicant.confで設定したSSID>
  static ip_address=192.168.0.2/24
  static routers=192.168.0.1

static routersルーターIPアドレスstatic ip_addressにラズパイのIPを指定します。

次にRaspbianの設定を行います。以下のコマンドを入力するとCUIコンフィグ設定画面が表示されます。

~ $ sudo raspi-config

初めに、初期状態だとホスト名がraspberrypi.localと長いので編集します。 2 Network OptionsN1 Hostnameを選択し、ホストネームを設定します。

次にロケーションの設定。4 Localisation OptionsからI1 Change Localeを選択し、ja_JP.UTF-8 UTF-8までスクロールします。結構下の方。

f:id:nkhnd:20200505131925p:plain

同様にタイムゾーンの設定。同様に4 Localisation OptionsからI2 Change Timezoneを選択しAsiaTokyoを選択。

Wifiのlocationも一応設定しました。4 Localisation OptionsからI4 Change Wi-fi Countryを選択、JP Japanを選択。

あとは、piユーザを使用する/消さずに残す場合は必ず1 Change User Password Change password for the 'pi' userでpiユーザのパスワードを変更しましょう。

以上の設定が完了したら、最初の画面で<Finish>を選択すると、再起動が行われ設定が反映されます。

再起動を促されなかった場合は、自分で再起動します。

~ $ sudo shutdown -r now

以後の接続はpi@(設定したホスト名).localで接続可能です。

ファームウェアアップデート

ファームウェアをアップデートします。RaspberryPiではaptまたはapt-getでアップデートが可能です。

~ $ sudo su -
~ # apt update -y && apt upgrade -y && apt autoremove -y

デベロッパー向けのアップデートもあり、いろいろなサイトで紹介されていますが、私は安定版を使うことにします。

Swapの無効化

SDカードの書き込み回数を消費してしまうので、Swapを無効化します。

sudo swapoff --all
sudo systemctl stop dphys-swapfile.service
sudo systemctl disable dphys-swapfile.service
sudo apt remove dphys-swapfile
sudo rm -f /var/swap

参考:
www.angelcurio.com
curecode.jp

mdadmによるRAID構築

mdadmはソフトウェアRAIDの構築が可能なパッケージです。
これを利用し、HDD2枚でRAID1を構築します。

以下のサイトをかなり参考にして作りました。

monakaice88.hatenablog.com

ディスクのフォーマット

RAIDに利用するディスクは専用のフォーマットを行います。
混合を避けるため、RAIDに利用するディスクだけをラズパイに接続します。

~ $ sudo su 
(スーパーユーザに変更)
~ # fdisk -l
(接続されているディスクが表示される)
~ # gdisk /dev/sd# 
GPT fdisk (gdisk) version 1.0.3

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): 

gdiskを利用し、2枚のディスクそれぞれにLinux LAIDパーティションを作成します。

(すみません。ここログが残っていないので頑張ってください。具体的には/dev/sd*1にfd00形式のパーティションを作成します。)

フォーマット手順は「?」キーで対話を進めながら行います。「p」で現在のパーティションを確認、「d」でディスクのパーティションを削除、「n」で新規パーティションを作成します。

実はmdadmでは「Linux RAID形式」ではなくてもRAIDディスクを作成することができます(Linux file system形式2つとか可能です)

ただし、mdadmのRAIDに加えた時点で単一での使用ができなくなる(part diskレコードを挿入される)ため、Linux RAID形式以外を選択するメリットがありません。

むしろ、Linux RAID形式であれば次の手順でmdadm.confの情報なしでRAIDとして動作するようになるので、LinuxRAID形式を選択しましょう。

ちなみにうちのシステムでは一度ディスクの差し替えを行なっているので、古い方(/dev/sdb)はいまだにMBRレコード形式です。

fdiskで作成した場合、gptレコードではなくmbrレコードになるので、2TB以上が扱えなくなる他、表示が「Linux RAID」ではなく「Linux raid autodetect」と表示されます。

ただし、gptレコードのディスクが混在しても正常に動作しています。RAID1の場合は2TB以上扱うことは通常パーティションではできなくなります。

~ # fdisk -l | grep "Linux "
/dev/sdb1        2048 1953525167 1953523120 931.5G fd Linux raid autodetect
/dev/sdc1        2048 1953505279 1953503232 931.5G Linux filesystem
/dev/sdc2  1953505280 3907029134 1953523855 931.5G Linux RAID

RAIDディスクの作成

mdadmをインストールします。

~ # apt install mdadm

インストール完了後、mdadmコマンドでRAIDのディスクを構築します。先ほどLinux RAIDで設定したディスクを--raid-devices=2以降に指定します。

ここでは/dev/md0として作成しています。

~ # mdadm --create /dev/md0 --level=raid1 --raid-devices=2 /dev/sdb1 /dev/sdc2

RAIDの構築が始まります。かなり時間がかかるので半日くらい放置します。

cat /proc/mdstatで進捗を確認する事ができます。以下のような表示になったら構築が完了です。

~ $ cat /proc/mdstat 
Personalities : [raid1] 
md0 : active raid1 sdc2[2] sdb1[1]
      976629440 blocks super 1.2 [2/2] [UU]
      bitmap: 0/8 pages [0KB], 65536KB chunk

unused devices: <none>

976629440 blocks super 1.2 [2/2] [UU][UU]が有効なディスクを示します。ディスクが利用不可能な時は[U_][_U]という表示になります。

完了後、ラズパイの起動と同時に設定されるよう、mdadm.confに必要な情報を追記します。

前手順でRAIDを構成するディスクを全てfd00(Linux RAID)に設定した場合、mdadm.confへの情報追記は不要です。

Linux RAID形式のディスクであれば、一度アレイを作成すればディスク側にアレイ情報が記録されるらしく、mdadmの入っているコンピュータであれば、実際にアレイを作成していないマシン上でもアレイを利用することが可能でした。)

mdadm.confが設定されていなくてもアレイができている状態

※本記事執筆時よりも環境が新しく、構成が変更されているので参考程度に。
いずれのディスク(/dev/sda、/dev/sdb)もgpt形式でフォーマットされている他、RAID0構成になっています。

~ $ df
ファイルシス   1K-ブロック      使用     使用可 使用% マウント位置
/dev/root         30483740   2570952   26642568    9% /
devtmpfs           1867780         0    1867780    0% /dev
tmpfs              1999876         0    1999876    0% /dev/shm
tmpfs              1999876     25452    1974424    2% /run
tmpfs                 5120         4       5116    1% /run/lock
tmpfs              1999876         0    1999876    0% /sys/fs/cgroup
/dev/mmcblk0p1      258095     54373     203722   22% /boot
/dev/md0        1921551568 614648772 1209223488   34% /mnt/nfs
tmpfs               399972         0     399972    0% /run/user/1001
~ $ cat /etc/mdadm/mdadm.conf 
# mdadm.conf
#
# !NB! Run update-initramfs -u after updating this file.
# !NB! This will ensure that initramfs has an uptodate copy.
#
# Please refer to mdadm.conf(5) for information about this file.
#

# by default (built-in), scan all partitions (/proc/partitions) and all
# containers for MD superblocks. alternatively, specify devices to scan, using
# wildcards if desired.
#DEVICE partitions containers

# automatically tag new arrays as belonging to the local system
HOMEHOST <system>

# instruct the monitoring daemon where to send mail alerts
MAILADDR root

# definitions of existing MD arrays

# This configuration was auto-generated on Sun, 10 May 2020 14:11:20 +0900 by mkconf
~ $ sudo fdisk -l
...(中略)...

Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: 2135            
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: AC9312AC-5BA2-4056-94F0-5E940231774F

Device     Start        End    Sectors   Size Type
/dev/sda1   2048 1953525134 1953523087 931.5G Linux RAID


Disk /dev/md0: 1.8 TiB, 2000136699904 bytes, 3906516992 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 524288 bytes / 1048576 bytes


Disk /dev/sdb: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: External HDD    
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 2B3ABC87-27E6-4859-9DC3-5AC79FF15E17

Device     Start        End    Sectors   Size Type
/dev/sdb1   2048 1953525134 1953523087 931.5G Linux RAID

Linux RAIDでディスクを設定していない場合には、mdadm.confへの追記が必要になります。

~ # mdadm --detail --scan
ARRAY /dev/md0 metadata=1.2 name=raspberrypi:0 UUID=3d26c6d8:a52ebff1:f3df6011:6e97ae59

~ # mdadm --detail --scan >> /etc/mdadm/mdadm.conf

Linux RAIDを設定していないディスクを含む場合はこの設定を行わないとアレイが作成されないようです。

構築したRAID仮想ディスクをフォーマットします。RAIDディスクにはラズパイしかアクセスできないのでext4で大丈夫です。

~ # mkfs -t ext4 /dev/md0

exFATにしないとWindowsMacで使えない」なんてことはありません。結局のところ、直接ファイルシステムでファイルを操作するのではなく、SambaやSFTP(SSHプロトコルを仲介に利用するため、フォーマットがどのような形式であろうと利用することが可能です。

あとは/dev/md0を好きなマウントポイントにマウントすれば利用が可能です。

自動マウントの設定

/etc/fstabに追記します。素直に/dev/md0を指定しても良いのですが、私はできるだけUUIDを利用する方法でいつもマウントしています。

blkidコマンドを管理者権限で利用すると、全てのデバイスにおけるUUIDやPARTUUIDを調べることができます。
ここで表示されるプロパティを/etc/fstabに直接書き込みます。

~ # blkid
...(省略)...
/dev/md0: UUID="04d1d291-5598-4733-b4fe-cc61708f44ec" TYPE="ext4"
...(省略)...

~ # cat /etc/fstab
proc            /proc           proc    defaults          0       0
...(省略)...
### RAID Device
UUID=04d1d291-5598-4733-b4fe-cc61708f44ec   /mnt/nas    ext4    defaults,nofail 0   0

## ↑は次のように書くことも可能
# /dev/md0  /mnt/nas    ext4    defaults,nofail 0   0
...(省略)...

再起動し、指定したマウントポイントにマウントできているか確認します。mountpointコマンドがシンプルでわかりやすいです。

~ # reboot
...(再起動後)...
~ $ mountpoint /mnt/nas
/mnt/nas is a mountpoint

心配ならdfコマンドでも可です。

df -hで作成したアレイがマウントされているかを確認することもできます。私の環境では稼働中の表示なので使用%が高いですが、通常では初期値で0%が表示されます。

~ $ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/root         30G  1.8G   27G    7% /
...(省略)...
/dev/md0         916G  414G  457G   48% /mnt/nas
...(省略)...

SFTPで共有

Sambaを使う方法もありますが、今回は公開鍵認証を行いたかったのでSFTPを利用しました。

いろいろ面倒なので特別な理由がないのであればSambaの方が簡単なので、Sambaをお勧めします。

鍵の作成

クライアントPCを利用し鍵を作成します。

~ $ ssh-keygen -C ""
Generating public/private rsa key pair.
Enter file in which to save the key (/home/pi/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/pi/.ssh/id_rsa.
Your public key has been saved in /home/pi/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Kd8eibUkY+nNUqZyPjLROP+WDCssD/rae1u35tfzEYM
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|                 |
|                 |
|         o    .  |
|      .oS =  E o |
|      +=o& o    o|
|    ...+O+O. . . |
|   o..*=++=o. o .|
|  oo+=o=.*=.   o.|
+----[SHA256]-----+
~ $ ls ~/.ssh
id_rsa      id_rsa.pub  

作成されたid_rsa.pubをラズパイでログインするユーザの~/.ssh/authorized_keysファイルに追記します。

### クライアントPC上で
~ $ cat ~/.ssh/id_rsa.pub
(公開鍵情報が表示される)

#### 上で表示された内容をコピー、ラズパイでログイン
~ $ mkdir ~/.ssh
~ $ echo "ここに上の内容をペースト" >> ~/.ssh/authorized_keys
~ $ cat ~/.ssh/authorized_keys
(id_rsa.pubで表示された内容と同じかどうかを確認)

Windowsssh-keygenが使えない場合

鍵自体はラズパイ上で作成し、WindowsPC上で秘密鍵を作成します。

上の手順でssh-keygenを行ったあと、ラズパイ上で公開鍵をauthorized_keysに登録します。

~ $ ls ~/.ssh
id_rsa      id_rsa.pub  
~ $ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
~ $ cat ~/.ssh/authorized_keys
(id_rsa.pubで表示された内容と同じかどうかを確認)

ラズパイ上で秘密鍵を表示します。

~ $ cat  ~/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----

...(省略)...

-----END OPENSSH PRIVATE KEY-----

この内容をWindowsのメモ帳などに貼り付け、適当な場所に保存します。

これで鍵認証の準備が完了です。

macOSクライアントの設定

macOSでSFTPドライブをマウントするにはFUSE for macOSとsshfsを利用します。Finder上にSFTPドライブを表示できるようになり、便利です。

ただし、これを利用してマウントするだけだとLinuxmac文字コードが異なる問題で、日本語のファイル名などが一部表示されないため、あらかじめ変換用ライブラリをインストールしておきます。

変換用ライブラリはHomebrewによって提供されているので、Homebrewをインストールします。

brew.sh

xcodeコマンドラインツール等のインストールも必要になる場合があります。
Homebrew導入方法はここでは割愛します。

まず、libiconvをインストールします。

~ $ brew update
~ $ brew install libiconv

これでlibiconvの導入が完了です。

Stable ReleasesからFUSE for macOSとSSHFSをダウンロードし、インストールします。
osxfuse.github.io

インストールが完了すると、コマンドプロンプトから特定のポイントにマウントができるようになります。

piユーザのホームディレクトリをデスクトップ上のfuseディレクトリにマウントする際の例です。IdentityFileには秘密鍵(ここではid_rsa)を指定します。

~ $ sshfs pi@raspberrypi.local:/ ~/Desktop/fuse -o IdentityFile=/Users/<ユーザ名>/.ssh/id_rsa -o defer_permissions,modules=iconv,from_code=UTF-8,to_code=UTF-8-MAC

defer_permissionsによってファイル操作の際に使うuidとgidを認証に使用したユーザ(上記ではpiユーザ)に設定します。

modules=iconv,from_code=UTF-8,to_code=UTF-8-MACでは、Linux上でUTF-8で扱われている内容をUTF-8-MACに変換します。

これでやっとSFTPサーバがマウントされ、アクセスできるようになりました。

f:id:nkhnd:20200409142617p:plain

アンマウントは通常のディスクと同様、マウントされたアイコンをゴミ箱にD&Dしたり、ターミナルからdiskutil umount (マウントポイント)を入力することで解除する事ができます。

簡単に設定するためにシェルスクリプトAutomatorでアプリ化するといい感じです。

Windowsクライアントの設定

WindowsではSFTP Driveを利用するとMacとは比べ物にならない簡単さで設定できます。

https://www.nsoftware.com/sftp/drive/www.nsoftware.com

Free DownloadからSFTP Drive V2 Personal Editionを選択し、インストールします。

インストール後、Start SFTP Drive V2をクリックし起動。
Drivesタブ右側の「New」をクリックし、情報を入力します。

f:id:nkhnd:20200409143759p:plain

設定項目 内容
Drive Name マウントされた時に設定される名称です。
Drive Letter ドライブ文字を指定します。
画像の場合P:¥でアクセスできるようになっています
Remote Host raspberrypi.local等、ホストのアドレスを記述します
Authentication Type Public Keyを指定すると鍵認証に切り替わります
Username piなど、ログインに利用するユーザを指定します。
Private Key 前の手順でメモ帳で保存した秘密鍵を指定します。

以上を設定したら「Test SSH Connection」を押し、Successメッセージが出たら設定完了です。OKボタンを押して設定を保存します。

画面左上のStartボタンを押すと、自動的にマウントされ、使用可能になります。

f:id:nkhnd:20200409145420p:plain

また、画面左上のStopボタンでアンマウントする事ができます。

iOSクライアント(FE File Explorer)の設定

iOSクライアントをデバイスにインストールした状態で、デバイスをUSBで接続し、iOSのファイル共有を利用して転送します。

Mac秘密鍵を作った場合は、移動しやすいように秘密鍵をデスクトップにでも移動しましょう。ターミナルを開きます。

~ $ cp ~/.ssh/id_rsa ~/Desktop

出現したid_rsaWindowsならiTunesMacならFinderからiOSバイスにアクセスし、ファイル共有でデータを転送します。

FE File Explorerの左カラムから+ボタンをタップし新しい接続→SFTPを選択。

f:id:nkhnd:20200409150348j:plain

サーバーの文字コードUTF-8を選択します。
UnicodeUTF-8)でも問題ありません。

ログオンの種類をキーファイルに選択後、秘密鍵ファイルをタップし、転送したファイルを選択します。
iTunesやFinderによるファイル共有を使用した場合は、On My iPadファルダに転送されています。

保存をタップすると、左カラムに追加され、接続できるようになります。


SFTPは面倒くさいです。ここで設定したのは最低限で、筆者の環境ではここからユーザーごとにChrootを設定して安全性を高めたり、SSH制限をつけたりしています。

初めSambaで作成したものの出来心でSFTPに乗り換えましたが、普通に使う分にはSambaで良いと思います。

特にTimeMachineなんかは(ずっと前に)SambaのNASに対応していたので、SFTPとは別にこちらの接続はSambaを利用しています。

https://nkhnd.hatenablog.jp/entry/2020/04/08/021526nkhnd.hatenablog.jp

しかし今後ポートフォワードなんかでうまく外部に公開して自宅Dropboxみたいな事ができたらいいなと思い、ここまでやってきたという事です。

セキュリティ知識がもっとついてきたら頑張ってみようと思います。