ラズパイ4でRAID1 NASを構築した
うちのRaspberryPi 4は、HDDを3枚使って2枚をソフトウェアRAID1のNAS、1枚を非RAIDのNASとして現在絶賛稼働中です。
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だったりちょっとわかりにくいので図に描き起こしたものを掲載しておきます。
2TBのディスクはパーティションを切って1TB分だけRAID1に利用しています。
また、2.5インチのディスクについてはラズパイから外して利用することもあるため、RAIDには組み込んでいません。
RaspberryPiのセットアップ
初期設定
SDカードにRaspbian Buster Liteを書き込みます。以下からダウンロードします。
面倒くさかったので書き込みにはbalenaEtcherを利用。
Raspberry Pi Imagerを使う方法
(以下過去の文章)
ちなみに、公式でラズパイのイメージを書き込むソフトウェアが出てました。
Raspberry Pi Imagerというソフトで、Windows、Mac、UbuntuでbalenaEtcherのようなことができます。
今回はオンラインダウンロードではなく、あらかじめ持っていたRaspbian buster Liteのイメージを利用。ディスクユーティリティーで書き込み可能な4GBの仮想ディスクを作成し、書き込んでみます。
いい感じですね!完成した仮想イメージをマウントすると。。。
GPTで作ったのが自動的にマスターブートレコードに変更され、パーティションの切られたディスクが作成されました!
今回はイメージを落としてきたのでbalenaEtcherと変わりませんが、Raspberry Pi Imagerではそういったファイルを自動的にダウンロードしてきて書き込んでくれる機能があるみたいです。
Raspbianだけではなく、Raspberry Pi上で動くとされるバージョンのUbuntu等もインストールが可能。
新規ユーザーはぜひ上を利用しましょう。
不具合の原因が分かるまでは、balenaEtcherを利用する方が良さそうです。
SDカードへOSをインストールしたら、まずSSHを有効にしましょう。キーボードもマウスも不要です。
焼き終わったSDカードのbootパーティションにssh
というファイルを配置します。
% cd /Volumes/boot boot % touch ssh boot % ls | grep ssh ssh*
次にラズパイにWifi設定を入れます。
あらかじめWifi設定を入れておくことで、初回からLANケーブルやディスプレイをつかわずSSH接続が可能です。
wpa_supplicant.confはこのサイトを利用すると簡単に作成できます。
作成した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 Options
→N1 Hostname
を選択し、ホストネームを設定します。
次にロケーションの設定。4 Localisation Options
からI1 Change Locale
を選択し、ja_JP.UTF-8 UTF-8
までスクロールします。結構下の方。
同様にタイムゾーンの設定。同様に4 Localisation Options
からI2 Change Timezone
を選択しAsia
→Tokyo
を選択。
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を構築します。
以下のサイトをかなり参考にして作りました。
ディスクのフォーマット
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
~ # 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にしないとWindowsとMacで使えない」なんてことはありません。結局のところ、直接ファイルシステムでファイルを操作するのではなく、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で表示された内容と同じかどうかを確認)
※Windowsでssh-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ドライブを表示できるようになり、便利です。
ただし、これを利用してマウントするだけだとLinuxとmacの文字コードが異なる問題で、日本語のファイル名などが一部表示されないため、あらかじめ変換用ライブラリをインストールしておきます。
変換用ライブラリはHomebrewによって提供されているので、Homebrewをインストールします。
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サーバがマウントされ、アクセスできるようになりました。
アンマウントは通常のディスクと同様、マウントされたアイコンをゴミ箱に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」をクリックし、情報を入力します。
設定項目 | 内容 |
---|---|
Drive Name | マウントされた時に設定される名称です。 |
Drive Letter | ドライブ文字を指定します。 画像の場合P:¥でアクセスできるようになっています |
Remote Host | raspberrypi.local等、ホストのアドレスを記述します |
Authentication Type | Public Keyを指定すると鍵認証に切り替わります |
Username | piなど、ログインに利用するユーザを指定します。 |
Private Key | 前の手順でメモ帳で保存した秘密鍵を指定します。 |
以上を設定したら「Test SSH Connection」を押し、Successメッセージが出たら設定完了です。OKボタンを押して設定を保存します。
画面左上のStartボタンを押すと、自動的にマウントされ、使用可能になります。
また、画面左上のStopボタンでアンマウントする事ができます。
iOSクライアント(FE File Explorer)の設定
iOSクライアントをデバイスにインストールした状態で、デバイスをUSBで接続し、iOSのファイル共有を利用して転送します。
Macで秘密鍵を作った場合は、移動しやすいように秘密鍵をデスクトップにでも移動しましょう。ターミナルを開きます。
~ $ cp ~/.ssh/id_rsa ~/Desktop
出現したid_rsaをWindowsならiTunes、MacならFinderからiOSデバイスにアクセスし、ファイル共有でデータを転送します。
FE File Explorerの左カラムから+ボタンをタップし新しい接続→SFTPを選択。
サーバーの文字コードはUTF-8を選択します。
Unicode(UTF-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みたいな事ができたらいいなと思い、ここまでやってきたという事です。
セキュリティ知識がもっとついてきたら頑張ってみようと思います。