Raspberry Pi 4B を自宅サーバにする(CentOS Stream 8)

目次

はじめに

以前の記事 で、Raspberry Pi 4B を自宅サーバ化するために Ubuntu を採用したが、結局 IPv6 ネットワーク周りに関してどうしても解決できない問題が出たため継続利用を断念。本記事では、 Ubuntu でのインストール実績はなかったもの として、CentOS Stream 8 版として焼き直すことにする。

目標と主な構成

主な目標

  • 24時間常時稼働
    • Micro SD カードではなく SSD 運用とする
  • IPv6 対応+IPv6 アプリケーションの動作確認・テスト用
  • 自宅リモート接続用の OpenVPN サーバ (IPv4/IPv6)
  • 自宅用ファイルサーバ
  • Web フレームワーク構築学習用 (Python Django/Flask)

OS

CentOS Stream 8 を選択。

長年慣れた rpm 系ディストリビューションであり、社内でもずっと RHEL/CentOS 一択だった。RPM パッケージをリビルドする必要が出たとしても、大抵はなんとかなる。 ただ、CentOS 8 → CentOS Stream 8 移行問題については悩ましい。CentOS 8 (無印) は 2021年末にサポートが終わってしまうし、CentOS 7 ではライブラリが古すぎる。 Fedora/CentOS Stream/CentOS/RHELの関係性 (赤帽エンジニアブログ, 2020/7/27) を読む限り、「CentOS 以上、Fedora 未満」の熱さ加減らしいので、ここに期待する。

ケース

Argon ONE M.2 Case for Raspberry Pi 4 を選択。

M.2 SATA 型の SSD を内蔵可能、放熱性のよいアルミ筐体、可変コントロールFAN、配線をすべて背面にまとめられる等々がお気に入り。SSDユニットを接続するために特殊な USB-A ブリッジコネクターが付いている。

正面背面背面コネクタ
上面(GPIO端子)部品一式梱包箱

機器仕様・構成

項目構成
本体Raspberry Pi 4 Type B (RAM 4GB)
電源USB-C 端子 (5V/3A)
ケースArgon ONE M.2 Case
ストレージWestern Digital: WD BLUE M.2 500GB SSD (WDS500G2B0B)
出力インストール時のみ HDMI モニタに接続し、セットアップ後は外す
インターフェース作業時のみキーボード・マウスを接続し、セットアップ後は外す
OSCent OS Stream 8 (64bit)
ネットワーク内蔵Gigabit Ethernet

ケースへの SSD の組み込み

(ラズパイ自身の組み込みは省略。)

ケースの底蓋側が SSD ユニットになっているのでこれを外し、M.2 コネクタに SSD を差し込んでから、SSD自体をネジ1本で固定する。

再度底蓋を閉めたら、USB のブリッジコネクタを差し込む。完了まで何度か底蓋を外すことになるので、底蓋側のネジは最後まで締めずにおく。

OS インストール

インストール作業用OSの準備

ラズパイ標準構成以外のデバイスや OS を使おうと思ったら、とにかく標準 Raspberry Pi OS を起動して前準備をする。こちらはセットアップ済みの MicroSD カードの用意が前提。

  1. MicroSD カードから Raspberry Pi OS (デスクトップ版) を起動し、ログインする
  2. ターミナル内で、Raspberry Pi OS 自身を更新し、再起動する
sudo apt update
sudo apt upgrade
sudo reboot
  1. 再度 Raspberry Pi デスクトップにログインして下記を進める。

イメージファイルダウンロード

CentOS コミュニティの Pablo Greco さん がラズパイ用の CentOS イメージファイルを公開しているので、Raspberry Pi OS デスクトップ上でダウンロードしておく。

CentOS-Userland-8-stream-aarch64-RaspberryPI-Minimal-4-sda.raw.xz

SSD に CentOS イメージを入れる

Raspberry Pi OS デスクトップ版にログインし、ここから SSD に書き込む。

  1. Raspberry Pi OS の MicroSD をラズパイ本体に挿す。
  2. Argon ONE M.2 に SSD をセットし、USB ブリッジコネクタで接続。(まだ裏蓋ネジは締めないで仮置き)
  3. 電源を入れ、MicroSD から Raspberry Pi OS を起動し、デスクトップ (X Windows) にログインする。
  4. 公式の Raspberry Pi Imager をインストールする。
sudo apt install rpi-imager
  1. Raspberry Pi Imager を起動
    1. CHOOSE STORAGE で USB 経由の SSD デバイスを指定 (MicroSD を指定すると起動中の OS が壊れるので注意!)
    2. CHOOSE OSUse custom を指定
    3. 先ほどダウンロードしておいた xxx.raw.xz ファイルを指定する。自動展開されるため事前に xz 圧縮を展開しておく必要はない。
    4. WRITE をクリックして終わるまで待つ

CentOS kernel 起動ファイルを編集

Raspi OS のターミナルから実行

sudo su -
mkdir -p /mnt/sda1
mount /dev/sda1 /mnt/sda1

PARTUUID を確認

blkid | grep "sda"

結果から PARTUUID を拾っておく。例:

/dev/sda1: PARTUUID="68bafdb3-01"
/dev/sda2: PARTUUID="68bafdb3-02"
/dev/sda3: PARTUUID="68bafdb3-03"

kernel 起動引数の設定

vi /mnt/sda1/cmdline.txt

変更部分:

root=/dev/mmcblk0p3
root=PARTUUID=68bafdb3-03
※ダブルクォートを入れると認識されないので注意

fstab の編集

マウントデバイス名を PARTUUID=xxxx 形式に書き換える。

vi /mnt/sda3/etc/fstab

例)

PARTUUID=68bafdb3-01  /boot vfat   defaults,noatime 0 0
PARTUUID=68bafdb3-02  swap  swap   defaults,noatime 0 0
PARTUUID=68bafdb3-03  /     ext4   defaults,noatime 0 0

※PARTUUID の指定はダブルクォートを外すこと

ラズパイ起動オプションの編集

ファイル新規作成

vi /mnt/sda1/config.txt

  • SD カードスロット検索の無効化
  • BlueTooth無効化 (省電力)
  • Wi-Fi 無効化 (省電力)
  • 起動時 Splash 画面OFF
  • その他 Argon One M.2 Case 用の設定
    dtparam=sd_poll_once
    dtoverlay=disable-bt
    dtoverlay=disable-wifi
    disable_splash=1
    dtparam=i2c_arm=on
    enable_uart=1

デバイス起動順序の変更

ラズパイのデフォルトブートデバイスは microSD カードになっているので、USB に変更する。ラズパイには BIOS メニューが存在しないので、OS から変更する。

Raspberry Pi OS のターミナルを起動し raspi-config を実行:

sudo raspi-config

raspi-config 20210212 版の場合、下記の順でメニューを選択。メニュー名やコメントはバージョンによって違うことがある。

  1. Advanced Options Configure advanced settings
  2. Boot Order Choose network or USB device boot
  3. USB Boot Boot from USB if available, otherwise boot from SD Card

USB から起動

  1. 作業に使った Raspberry Pi OS をシャットダウンする。
  2. USBブリッジコネクタを含め全てコネクタを外し、(ネジの締めていない) 裏蓋を空ける
  3. MicroSD カードを抜く
  4. 再度裏蓋を閉め、USBブリッジコネクタを挿す。
  5. キーボード、モニタ、自宅ネットワークのLANケーブルを挿し、電源を入れる。
  6. SSD から CentOS が起動することを確認

CentOS 起動後の調整

コンソールから初回ログインする。 ユーザー: root、パスワードは centos。

パーティションを拡張し再起動する。

rootfs-expand
reboot

起動後、DHCP でネットワークアクセスができるはずなので、下記の順で作業する。

#OS アップデート
dnf -y update

#物理キーボードを日本語に変更
localectl set-keymap jp106

#システムロケール変更
#JP だと HDMI コンソールが文字化けするので en_US にしておく
localectl set-locale LANG=en_US.utf8

#タイムゾーン変更
timedatectl set-timezone Asia/Tokyo

#ホスト名変更 (お好みで)
hostnamectl set-hostname raspiyamk1

#root パスワード変更 (2回入力)
passwd

#再起動
reboot

起動時エラー対応

起動時にコンソールまたは /var/log/messages に下記のエラーが出る場合:

FAT-fs (sda1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.

FAT32 用のツールをインストール

dnf install dosfstools

下記の手順を実行

# fsck.fat -V /dev/sda1
fsck.fat 4.1 (2017-01-24)
0x25: Dirty bit is set. Fs was not properly unmounted and some data may be corrupt.
1) Remove dirty bit
2) No action
? 1
Starting check/repair pass.
Starting verification pass.
Perform changes ? (y/n) y
/dev/sda1: 238 files, 6907/36587 clusters

Wi-Fi の設定を完全 OFF

利用しないインターフェースを認識させないようにする。

nmcli radio wifi off

CentOS Stream 8 への切り替え

最初から Stream のはずなのになぜかなっていない。

現在のリリースを確認

# cat /etc/centos-release
CentOS Linux release 8.3.2011

Stream に切り替え:

dnf -y install centos-release-stream
dnf -y swap centos-{linux,stream}-repos
dnf -y distro-sync
# 終わったら再起動
reboot

再起動後、リリースを確認

# cat /etc/centos-release 
CentOS Stream release 8

その他ツールインストール

#bash 補完パッケージ
dnf install -y bash-completion

#VIM 拡張
dnf install -y vim-enhanced

#ネットワークツール
dnf install -y telnet nc wireshark-cli tcpdump

SELinux 無効化

vi /etc/selinux/config
下記の行を編集
SELINUX=disabled
再起動して反映
reboot

firewall 無効化

systemctl stop firewalld
systemctl disable firewalld

mDNS (Multicast DNS) 有効化

※2021/7/2 パッケージ nss-mdns のインストールと設定を追加

dnf install -y avahi nss-mdns
systemctl enable avahi-daemon
systemctl start avahi-daemon

名前解決順序を修正: /etc/nsswitch.conf

変更前
hosts:      files mdns4_minimal [NOTFOUND=return] dns myhostname
変更後
hosts:      files mdns_minimal [NOTFOUND=return] dns mdns myhostname

同じネットワーク内の Windows 10 の PowerShell から、“ホスト名.local” で名前解決ができるか確認する。例)

Resolve-DnsName raspiyamk1.local

固定IP設定

Network Manager の設定は nmcli にて行う

コネクション名の変更

日本語ロケールで構築したためか、コネクション名が「有線接続 1」になってしまっているため、コマンドラインで入力しやすい英語名に修正する。

#Connection名の確認
nmcli c

NAME        UUID                                  TYPE      DEVICE 
有線接続 1  a3f45bb3-2970-3e05-bd40-1b8a56a0fd80  ethernet  eth0 

#connection名変更
nmcli connection modify "有線接続 1" connection.id "wired1"
※コネクション名にはスペースを入れない方がコマンドが打ちやすい。例)
△ “Wired connection 1”
○ “wired1”

IPv4 アドレスの固定

確認方法

nmcli con show wired1 | grep ipv4
設定例
nmcli con modify wired1 ipv4.addresses 192.168.0.16/24
nmcli con modify wired1 ipv4.gateway 192.168.0.1
nmcli con modify wired1 ipv4.dns 192.168.0.1
nmcli con modify wired1 ipv4.method manual
nmcli con reload
nmcli con down wired1 & nmcli con up wired1

IPv6 アドレスの半固定

確認方法

nmcli con show wired1 | grep ipv6
設定例: PREFIX 上位 64bit は SLAAC による自動配布、下位 64bit は固定アドレス (::16) とする。Default Gateway, DNS は自動設定。SLAAC は IPv6 ルータ側の設定に従う。
nmcli con modify wired1 ipv6.method auto
nmcli con modify wired1 ipv6.ip6-privacy 0
nmcli con modify wired1 ipv6.addr-gen-mode eui64
nmcli con modify wired1 ipv6.token ::16
nmcli con reload
nmcli con down wired1 & nmcli con up wired1

お片付け

ここまでの設定で、他の端末から SSH ログインできるようになっているはずなので、忘れずに裏蓋をネジ止めしておく。(この記事を書き上げるために何度裏蓋を外し、MicroSD を付け外ししたことか‥‥)

あとは冷暗所に置いて LAN ケーブルと電源アダプタだけを接続し、いつでもリモートログインできる状態なことを確認する。

Raspi の状態表示コマンドの導入

vcgencmd が CentOS にはないので、ソースからビルドする

開発環境のインストール

dnf install cmake gcc gcc-c++ make git

ソース展開とコンパイル

mkdir ~/work
cd ~/work/
git clone https://github.com/raspberrypi/userland.git
cd userland
./buildme --aarch64

以上でインストールまで完了するので、下記フォルダを確認。

ls /opt/vc/bin

実行できるようにもろもろやる。

cat <<'__EOT__' > /etc/ld.so.conf.d/raspberrypi.conf
/opt/vc/lib
__EOT__
ldconfig
cat <<'__EOT__' >> ~/.bashrc
PATH="/opt/vc/bin:$PATH"
export PATH
__EOT__

root で再ログインし直すと、vcgencmd が使えるようになる。 例)

#温度
vcgencmd measure_temp

#CPU周波数を表示
vcgencmd measure_clock arm

#電圧を表示
vcgencmd measure_clock arm

#CPU(arm),GPUのメモリ使用量
vcgencmd get_mem arm

参考