- 前回
前回はとりあえずRaspberry Pi をGUIなしで起動できるところまで行いました。microSDカード・LANケーブル(wi-fi接続でない場合)・USB Type-Cケーブルを接続すれば、すぐに起動します。
そう、標準では電源ボタンなどがないので、Type-Cで電源を供給する前に、microSDカードやLANケーブルは接続しておくようにしましょう。
Raspberry Pi4B をサーバーに仕立てる
Raspberry Pi に SSHで接続してみる
さて、キーボードもなければディスプレイもないラズパイをどうやってサーバーに仕立てていくかというと、SSHというものを使って、リモートで接続します。
SSH はSecure SHell の略語で、暗号化されたShellの通信ですね(暗号化されていないtelnetというのもありますが……専用ポートに接続するルーターや組み込み機器以外ではほぼ使われません)。
あまり馴染みのない SSH ですが、Windows 11では、Windows Terminal で最初から使用できます。Windows 10では、環境によってインストールされているかが異なるため、下記サイト様を参考に、PowerShellに Open SSHを導入するのが確実です。
導入されているか分からない場合は、スタートメニューから Windows Terminal または、PowerShell を起動し、
上図のように、単に
ssh
と入力してEnterで改行します。usage: ssh …と出て来たらsshがインストールされています。逆に、見つからないよ……というようなメッセージが出て来たらインストールされていないので、Windows Storeなどからインストールしましょう。
試しに、ssiという存在しないコマンドを試してみたのが上図ですね。「あれでもない、これでもない」と沢山文句を言われています(笑)
さて、sshが無事にインストールされたことが確認できたら、今度はraspberrypi OSに接続してみます。GUIをインストールしていなければ、2, 3分もすれば起動していると思いますが、初回起動時は時間がかかり気味なので、電源を投入してから5分ほど待って、SSH の接続を試して見ます。
接続には、
ssh pi@raspberrypi.local
というコマンドを使います。上記は
#ssh [ユーザー名]@[ホスト名]
という形式になっていて、前回 OSのイメージ書き込み時に詳細設定で指定したホスト名・ユーザー名を使います。標準がraspberrypi.local, pi なのでそのままで大丈夫だと思いますが、変えた人はここも修正しましょう。
また、SSHで接続時に、
Are you sure you want to continue connecting (yes/no/[fingerprint])?
と質問されることがありますので「yes」と入力してEnterを押します。セキュリティに関する質問なので、業務で不審なタイミングでこの質問が出たら警戒しましょう。
また、
WARNING: POSSIBLE DNS SPOOFING DETECTED!
という、派手な警告文が表示されることがあります。これは、前回、同じホスト名で接続したサーバーとfingerprintが異なっている時にでます。システム管理者に連絡しろと出ますが、個人でやっていたら困ってしまいますね。
複数のRaspberry Piを同じホスト名でセットアップしたことがあったり、あるいは、OSの書き込み時にユーザー名・パスワードの設定を忘れていて書き込みをやり直したり(1敗)すると表示されます。ホスト名を変えてOS イメージを書き込み直してもいいのですが、さすがに面倒臭いので、
ssh-keygen -R raspberrypi.local
として、ssh に保存された fingerprint を削除しましょう。もう一度接続すれば、警告が表示されなくなります(もちろん、ホスト名は自分の環境に直します)。
これらの障害を乗り越えると、ようやくログインの認証としてパスワードの入力を求められます。
pi@raspberrypi.local's password:
と表示されたらパスワードの入力を行います。が、ssh に慣れていない人が気をつけないといけないのは、「文字を入力しても*とか●とか、伏せ字も表示されない」(エコーバックがない)ということです。ちょっと気持ち悪いですが、キーボードを叩いていればちゃんと入力されていますので、自信を持って入力し、Enterで確定しましょう。
pi@raspberrypi :~$
と、TerminalやPowerShellのプロンプトが変化すればログイン成功です。
Raspberry Pi OSのIPアドレスを固定する
Raspberry Pi OS は標準ではDHCP からIPアドレスを取得します。ルーターから自動で、家庭内の部屋番号を割り当ててもらうというようなイメージです。同じくローカル環境内からのアクセスであれば、raspberrypi.local というようなホスト名も使えるのでこのままでも特に困りません(sshで接続できましたよね?)。
ただ、サーバーを外部に公開したりホスト名が使いにくいサービスを使ったりする場合などに、IPアドレスが可変だとさすがに不便です。いくらフリーアドレスのオフィスでも、自動販売機が毎日場所移動していたら困りますよね? そんなイメージです。
IP アドレスの固定には、設定ファイルを書き換えます。
sudo nano /etc/dhcpcd.conf
※ / の間に半角のスペースが入っていますが、本来はここにスペースは入りません(Wordpressのセキュリティ上、Linuxの設定ファイルを示すパスがエラーになるようです……)
として、エディタを起動します。sudoコマンドは、特権ユーザー(管理ユーザー)として続くコマンドを実行する。nano というのは、エディタでファイルを開くという意味です。実際に編集されるのは、/etc / dhcpcd.conf というファイルになります。
なお、太字にして強調していますが、dhcpcd.conf です。dhcpd.confファイルではありません……。
ファイル名を間違えずに記述した場合、エディタでテキストファイルが開くので(間違えていると空っぽのファイルが開きます)、末尾まで移動します。マウスは使えませんが、カーソルキーやPageDownキーは使えますので、Windows のメモ帳と同じように使えます。
末尾まで移動したら、
interface eth0
static ip_address=192.168.1.181/24
static routers=192.168.1.1
static domain_name_servers=8.8.8.8
などのように設定します。
ip_address=…/24 のところが、固定したいIPアドレスとなります。楽介は、ラズパイ→なんかパイ→いっぱい→181ということで、192.168.1.181としました。/24 はサブネットマスクと言いますが、ここでは/24を必ずつけないといけないと考えてください。
routers=が、ルーターのIPアドレスです。お使いのルーターのIPアドレスを入れます。.で区切られた上3桁(通常)を指定するIPアドレスとあわせる必要があります。
そうはいっても、ルーターのIPアドレスなんて分からないよ! という場合には、Windows ターミナルで、
ipconfig
コマンドを実行します(Raspberry PiやMacでは、ifconfigになります)。
すると、
上図のように「デフォルト ゲートウェイ」というものが表示されます(通常、末尾が1です)。これで楽介の自宅のネットワーク環境が、ルーターは192.168.1.1、IPアドレスは192.168.1.2~192.168.1.254が使えることが分かります。たまに、192.168.11.とか、192.168.0.とかいう環境もあるので(もちろん、職場などの大規模ネットワークの場合はそれ以外の場合もありますが、そのときは管理者に聞いてください)、自信がなければ一度ipconfigを実行します。
最後の、domain_name_serverについては、8.8.8.8でいいと思います。これは、Googleが提供しているDNSサーバーでプロバイダが提供しているDNSより高速でセキュリティ上優れていることがほとんどです。
dhcpcd.conf を編集し終えたら、
Ctrl+O, Enter で上書き保存し、Ctrl+Xで終了します(ちょっとショートカットがWindowsと異なります)。
ただ、このままではIPアドレスは変わりません。
Raspberry Pi OSを一度終了してみよう
IPアドレスの設定変更を適用するには、一度ネットワークを切断・再接続するといいのですが、SSH上でやると、切断されたきり接続できなくなってしまいます。ということで、練習も兼ねて一度Rasperry Piを終了してみましょう。WindowsやMacと同様に、Raspberry Pi OSも、いきなり電源を抜いて終了してはいけません。
終了には、
sudo shutdown -h now
コマンドを使います。コマンドを実行すると、即座にsshが切断されます。ただ、OS上ではシャットダウンプロセスが継続していると考えられます。Type-C ケーブルを引っこ抜くのは、数分待ってからにしましょう。
そうです、標準のRaspberry Piでは、OSが終了しても、電源は切れません(電子スイッチもないので当たり前ですね?)。物理スイッチの追加などは、先人たちが多く資料を残しているので、必要な方はそちらを参照してください。楽介は、今のところ起動しっぱなしの予定なので、特に必要性を感じていません。
ともあれ、Type-Cを抜いたら、もう一度ケーブルを挿して電源を投入します。数分待ってから、sshで Raspberry Piに接続します(やり方を忘れてしまったら、このページの上に戻って下さいね)。
接続できたら、
ifconfig
として、ネットワーク設定を確認します。Windows 上とは、1文字違うので気をつけましょう。楽介はしょっちゅうこんがらがります。
inetが先ほど設定した内容になっていれば成功です。これで、Raspberry Pi OSが起動する度に、このIPアドレスを利用します。
注意点として、IPアドレスは、同じネットワーク内で重複してはいけません。複数台のRaspberry Pi に固定IPアドレスを割り当てる場合などは、同じ値を割り当てないようにしましょう。また、ルーターのDHCP(自動割り当て)と重複してしまうこともあるので、150番以降の大きめの値を設定する、といった工夫もするといいでしょう(ちゃんとする場合は、大体ルーターに、自動で割り当てられるIPアドレスの範囲を設定する機能があるので、そちらを使って下さい。楽介は面倒なので適当にあててしまっています)。
RAIDを設定してOSをRAIDから起動する
Raspberry Pi OS は microSDカードにOSをインストールして起動します。それは手軽でいいのですが、microSDカードは仕組み上、書き込み回数に上限があります。SSDにもありますが、安価なmicroSDカードの方が書き込み回数の上限は少ないだろうと想定されます(特に安い・付属品)。
教育用・練習用やIoT機器であれば、データはクラウドに保存して、本体には大事なデータは保存しない。壊れたら再インストールというのが、お手軽な運用だと思います。
最初は、swap(仮想メモリ)の書き込みを止めるか、RAID に書き込むようにしようと考えていたのですが、 / をHDD RAIDに移す方法があるみたいなのでやってみることにします。
SWAP無効の場合
RAIDにOSを移して起動するのは、手順が長く、失敗すると起動しなくなったり、SSHでログインできなくなったりするので、データさえ無事ならいいという場合には、SWAP無効の方が楽だと思います(いずれにせよ、microSDに/bootが残るため)。
参考
ほぼ上記、Qiita の記事そのままの手順ですが、1度どこか間違えたらしく、起動するもののSSHでログインができない……という不思議な状態になったので、変更点・1度目と2度目との違いも含めて書いて行きます。
また、Qiitaの記事はエンジニア向けなので、初学者にはちょっと辛い(昔Linuxをいじったことがある楽介もよく分かっていない)ので、初心者向けに簡単なコマンドの解説なども付記します。
初期設定
楽介の場合、1度目は初期設定はスキップしました。Raspberry Pi Imager で初期設定を行っている場合、基本的には不要だと思います。
ただ、SSH接続ができなかったため、2度目は念のため実行しています。
sudo passwd root
root という特権ユーザー(Windowsでいう管理ユーザー)のパスワードを設定します。コマンド後に新しいパスワードを尋ねられるので、入力します。
Raspberry Pi OS は Debian Linux 系統であるため、標準では root にログインできません。デフォルトユーザーから sudo で権限を取得し、パスワードを設定してログインできるようにしていると思います。特別必要ではないと思いますが、たまに復旧のために使うことがあるので、念のためにこれも実施しました。
sudo raspi-config
擬似GUI(マウスは使えないものの、キーボードでメニューを選択できる)を起動して、システムの初期設定をします。基本的には、Raspberry Pi Imager のGUIで設定済みの内容ですが、SSHに関する部分が含まれているので、2回目は実施しました(大丈夫なはずなんですが……勉強にもなるので)。
- 1 System Options → S3 Password → pi ユーザーのパスワードを再設定。念のため、Imager で設定済みのパスワードを再設定
- 3 Interface Options → I2 SSH → Enable(有効) SSHのログインを有効に。また、参考にした記事とローマ字がずれているのでそこだけ注意
- 5 Localization Options → L2 Timezone → Asia/Tokyo(時間の設定)
- 5 Localization Options → L3 Keyboard → JP(日本語キーボード利用の場合)
- 8 Update(ツールをアップデート)
完了したら Finish を選択して終わります。
パッケージ・OSの更新
sudo apt-get update && sudo apt-get upgrade
何か尋ねられたら、全てYes.
apt-get というのは、Debian 系Linux のパッケージ(アプリケーションのセットみたいなもの)管理ソフトを使って、実際にパッケージを操作するコマンドです。update オプションで、apt-get でインストールできるパッケージのリストの更新、upgrade でバージョンアップなどを実行します。ソフトの更新確認と、実際の更新をまとめて実行するコマンドだと思って下さい。
sudo apt-get dist-upgrade
こちらはOSを最新版にアップグレードできます。Windows Update のようなコマンドですね。メンテナンスとして、定期的に実行したいです。
HDD の確認
sudo fdisk -l
fdisk コマンドは、物理的なディスクやパーティション(物理ディスク上の保存領域)を管理するツールです。
注意点としてfdisk では、2TBを越えるディスクを(パーティションを分割しても)扱うことができません(1敗)。楽介は4TBのHDDを揃えてしまいましたが、2TBがまるまる無駄になっています。ディスクの形式がMBR になってしまうので、これはどうしようもないです。
GPT形式にすれば4TBまで使えますが、GPT 形式でHDDから起動ができるか分からなかったので、一回fdiskを用いたMBR形式で構築しています。後日、GPTフォーマットに直して起動するか実験したいと思います。
実行すると、
上図のような出力が得られます。スクリーンショットを撮っておくか、コピー&ペーストしておくと便利です(コマンドプロンプトでは選択してEnter, Windows Terminal では通常通り、Ctrl+Cでコピー)。
Raspberry Pi で、Raspberry Pi Imager を使って OS イメージを使った場合は、
- /dev/mmcblk0 → microSDカード自体
- /dev/mmcblk0p1 → /boot パーティション
- /dev/mmcblk0p2 → / パーティション(OS本体)
- /dev/sd* → USB ドライブ(a, b, c…と増加)
となっていると思います。Windows だと、パーティションごとにCドライブ、Dドライブ…と割り当てられるのでちょっと分かりづらいと思いますが、Raspberry Pi の場合、 /dev/ パスの中に、ハードウェア(device のdev ですね)が整理されて、それを使って管理するといった感じになります。
楽介の環境では、悲しく3.64 TiBと使い切れない容量が出ていますね。使用したのはWDのHDDです。NAS用途なので、RED の方がいいのかもしれませんが、予算をケチりました。後、GPT形式で起動できるかが分からないので、面倒な人は2TBを買った方がいいかもしれません。
今回、筆者の環境では、
- /dev/sda
- /dev/sdb
という物理ディスクがつながっていて、どちらにもパーティションが作成されていないことが分かります。
パーティションの作成
sudo fdisk /dev/sda
sudo fdisk /dev/sdb
2つのディスクそれぞれに実行します。実行すると、専用のコマンドモード(プロンプト)に切り替わります。
Command (m for help):
- n でパーティションを作成
- Partition Type そのまま Enter
- Partition Number そのまま Enter
- First Sector そのまま Enter
- Last Sector そのまま Enter
または、容量を指定したい場合は、 +500G などのように、 「+数字単位」の形式で入力します。 - w でディスクに反映
ただし、容量単位での指定を行った場合、下図のように何故か容量がずれてしまうことがあります。
こちらは面倒臭いのでそのままRAID構築まで実行してしまった例ですが、2回目に100GBで指定した場合は両方ともちょうど100GBとなったため、やりなおせばちゃんとできるかもしれません(30GBくらい誤差だよ誤差)。
RAID を構築
RAID の構築には、mdadm というソフトウェアを導入します。
sudo apt-get install mdadm
mdadm はRAID 管理用のLinux プログラムで、
といった使い方をします。
今回は、RAID1(ミラーリング・同じデータを2つのHDDに書き込む)を /dev/md0 として、先ほど作ったパーティション /dev/sda1, /dev/sdb1 をセットにして構築します。RAIDの名前は別に/dev/raid でも/dev/raid0 でも通るとは思いますが、慣例的に md+番号 とするみたいなので、従っておきます(こういうのは個性を発揮しないのが後々、やり直しの時に苦労しない)。
sudo mdadm --create --verbose /dev/md0 --level=1 --raid-device=2 /dev/sda1 /dev/sdb1
確認のメッセージには y で回答します。
構築後に同期の進捗が確認できます。
sudo mdadm --detail /dev/md0
楽介は同期の完了を待たずに以降の手順に進んでしまいましたが、1度目500GBのRAID、2度目100GBのRAIDだったので、同期を待った方が安全なのかもしれません(いずれにせよ、この時点では空のはず)。
RAID ボリュームの登録
この辺りから、楽介の理解がいよいよ怪しくなってきます。構築された RAID 自体は有効になったものの、デバイス /dev/md0 については永続性がない、ということ見たいです。メモリにはあるものの、HDDには書き込まれていない状態ということでしょうか。再起動すると、デバイス名が変わってしまう、らしいです(USBドライブを刺し直すとしょっちゅうドライブレターが変わる昔のWindowsみたいなもの?)。
これを固定するために、
sudo mdadm --detail --scan
で表示された結果をコピーし、
sudo nano /etc/mdadm/mdadm.conf
の末尾にペーストします。Windows Terminal であれば、SSH経由でのコピペもきちんと動作するので楽です。もしコピペが動かなければ、手間ですが手で入力しなおします。
入力できたら、Ctrl+O, Enterで保存、Ctrl+X で nano を終了します。
RAID のフォーマット
このままだと、RAID は未フォーマットのパーティションと同様なのでフォーマットします。
sudo mkfs.ext4 /dev/md0
Linux用の ext4 でフォーマットします。WindowsでもアクセスできるようにNTFS……とか考えがちですが、ソフトウェアRAIDなので大人しくext4にします。
RAID にSDカードの / (OS領域)をコピー
sudo fdisk -l で確認したように、raspberry pi OS をmicroSDカードに書き込んだ場合、通常は /dev/mmcblk0p2 が / がマウントされたデバイスになります。
sudo dd if=/dev/mmcblk0p2 of=/dev/md0 bs=32M conv=noerror,sync status=progress
として、全データをコピーします。
使用されているdd コマンドは、ファイルを「ブロック単位」で読み出して変換して出力するコマンドです。入出力に(ファイルやディレクトリではなく)デバイスを指定できるので、パーティションのコピーやバックアップにも使用されるとのことです。壊れかけのHDDから無理矢理データを引っ張り出すのにも使うとかなんとか。
- if が入力(in)
- of が出力(out)
なので、これを間違えるとただのファイルのコピーと違い、データが全て消えてしまうので注意が必要とのことです。
コピーには結構時間がかかるので(データがほぼ空でも、ディスク領域分の時間がかかる)、のんびり待ちます。
終わったら、
sudo e2fsck -f -y /dev/md0
として、エラーチェックと修復をかけます。ブロック単位でコピーするため、フォーマットが違うとかで必ずエラーが出るようなので、 -y オプションを指定して、全てにyesと回答します(ひとつひとつ確認してもいいですが、楽介の理解外だったので -y スイッチをつけます)。
また、パーティションごとコピーしたため、パーティションサイズがmicroSDカードと同じサイズ(約31GB)になってしまっているので、
sudo resize2fs -p /dev/md0
として、本来のサイズ(fdiskで作成したサイズ)まで戻します。こういうのをWindowsのGUIでやろうとすると大変なのですが、Linux系はコマンド1発で終わることが多くて気持ちがいいですね……。
RAIDから起動するために、initramfs イメージの作成
ソフトウェアRAIDを構築している mdadm プログラムが、OS起動前の最初期に読み込まれる /boot(ここはmicroSDカードのまま) の外にあるため、RAIDボリュームにOSをコピーしても起動できない、という理屈らしいです。
そのため、mdadmを起動できる initramfsを構築します。
sudo nano /etc/initramfs-tools/modules
としたら、最後の3行に以下を追加します。
raid1
md_mod
ext4
Ctrl+O, Enter, Ctrl+Xで保存、終了したら、
sudo update-initramfs -c -k `uname -r`
とします。これで、raid1やext4を組み込んだinitramfsが作られる、らしいです。また、シングルクォート’ ではなくバッククォート` なのでコマンド入力時は注意します。日本語キーボードの場合は、 Shift+@で入力ですね。
楽介の環境では上記のような警告がでていますが、他の環境でも出るらしいので、無視します。ここでは、
update-initramfs: Generating
の後に、ファイルのパスが表示されるのでコピーするか、スクリーンショットを撮っておきます。
ルートファイルシステムをマウントするため必要なカーネルモジュールやスクリプトが保存された、「ミニルート」のようなもの。mdadmに限らず、起動に必要なドライバを全てブート時に読み込もうとすると容量が大きくなるため、別に分割してあるらしい。
fdiskで扱えない 2TB以上のディスク形式、GPT形式を使うときに書き込む必要はないのかな?
ブートイメージの設定
ls /boot/*.img
として、カーネルのイメージを検索します。楽介の環境(というか今のRaspberry Pi OS)だと、kernel8.img というファイル名が検索されるので、ファイル名をメモっておきます。
参考にしている記事だとこれをやっていないのですが、他を探すと結構やっているみたいなので、念のために実行しています(1回目はやらずに失敗、2回目はやって成功したとだけ、参考までに)。
必要な情報を控えたら、
sudo nano /boot/config.txt
として、 /boot/config.txt ファイルを開きます。末尾、[All]の下に
kernel=kernel8.img
initramfs initrd.img-5.15.61-v8+ followkernel
と追記し、保存、終了します。それぞれ、読み込むカーネルとinitramfsを保存しているのだと思います。
cmdline.txt の設定
起動時に、RAIDを / とするように設定を行います。
sudo nano /boot/cmdline.txt
開いたファイルで、
console=serial0, … と始まる行を
console=serial0,115200 console=tty1 root=/dev/md0 rootfstype=ext4 elevator=deadline fsck.repair=yes rootdelay=15 rootwait
と修正します。参考にさせていただいた記事との違いは、elevator=deadline を追加していること。rootdelayを15に増やしていることです(2回目から)。また、
root=の後に、標準だとPARTUUID=…というのがスペースで区切られずについています。これは、デバイスのPARTUUIDを指定した方が通常の起動は安定するから、のようですが、/dev/md0は別のところで固定指定しているのでPARTUUID から次のスペースまでは削除して置き換えてしまいましょう(1回目はスペースで区切って残してしまった、後からWindowsで編集したものの、SSH接続はできず。1回目失敗のかなり怪しいポイントです)。
fstab の更新
こちらは、OS起動時に RAIDが / にマウントされるように設定する……のだと思います(今までの /boot 内のファイルの編集は、ブートプロセスの内容)。
そのため、この時点では /etc/… はSDカードを参照してしまうので、作成したRAID ボリュームを1回、別の場所にマウントします。Windowsの起動ディスクをUSBドライブにして、別PCに刺す……といったイメージでしょうか。
sudo mkdir /mnt/md0
sudo mount /dev/md0 /mnt/md0
とします。mkdir でディレクトリを作成し、mountコマンドで、そのディレクトリに /dev/md0 RAIDボリュームをマウントしています。このマウントがWindowsユーザーには馴染みづらいのですが、ジャンクションと似たようなイメージで動作します(実態は大分違うみたいですが)
参考:
マウントできたら、
sudo nano /mnt/md0/etc/fstab
として、fstab ファイルを開きます。
最初の proc…で始まる行には触れず、PARTUUID=…で始まる2行を#でコメントアウトします。
そして、
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/md0 / ext4 defaults,noatime 0 1
の2行を足します。
一行目のPARTUUIDと、/dev/mmclk0p1 については手を入れなくてもいいような気がしますが(どちらもmicroSDカードの/bootを意味している)、素人判断で変えることもないな……と思ってそのままです。
再起動と動作確認
sudo shutdown -h now
で一度シャットダウンし、外付けHDDの動作が停止してから再度電源を入れます。
SSHでログインできれば成功です(1敗)
終わりに
ほぼ参考記事そのままなのですが、それでも何故か失敗。他で上手く行っている人との違うところを適用して再挑戦でなんとか上手くいきました。
理解できていない作業なので、自分の理解を深めつつ、楽介のように全然詳しくないけれどもいじるやる気がある人がなじめるように、各種コマンドについて解説を入れながらまとめてみました(個人で再構築用も含んでいます)。
次は、HDDの空き容量が余りにももったいないため、HDDをGPT形式にしてRAIDから起動できるようにしてみたいと思います。調べるとMBRからGPTに変換できるってなってますが、データ全部消えるって警告でるので、1からやり直しだと思います。
楽介でした。