Raspberry PI シリーズで分散環境構築(その5: クラスタノード向け Raspberry PI OS のカスタマイズ(1))

# 序(連載リスト)
1. [Raspberry PI シリーズで分散環境構築(その1:モデル別、ディスクレスクライアント化の可否まとめ)](https://qiita.com/p_cub/items/e81dd0f49b3f6fb024a5)
2. [Raspberry PI シリーズで分散環境構築(その2: PiServer の解析と代替システムの設計まで)](https://qiita.com/p_cub/items/69fa32a9a62890ca1d04)
3. [Raspberry PI シリーズで分散環境構築(その3: dnsmasq のインストールと設定)](https://qiita.com/p_cub/items/e7c889b0f92a868a6c20)
4. [Raspberry PI シリーズで分散環境構築(その4: NFSサーバの構築とクライアント用OSのインポート)](https://qiita.com/p_cub/items/dd682de7de28276129e6)
5. [Raspberry PI シリーズで分散環境構築(その5: クラスタノード向け Raspberry PI OS のカスタマイズ(1))](https://qiita.com/p_cub/items/ecf4c48b7ecb08d971b1)
6. [Raspberry PI シリーズで分散環境構築(その6: クラスタノード向け Raspberry PI OS のカスタマイズ(2))](https://qiita.com/p_cub/items/73dc833302c3f064dc39)
7. [Raspberry PI シリーズで分散環境構築(その7: 各ラズパイ向けの tftp ルート設定と起動試験)](https://qiita.com/p_cub/items/ecef742e86ab2991c1b0)
8. [Raspberry PI シリーズで分散環境構築(その8: Webクラスタ構築のケース(前半))](https://qiita.com/p_cub/items/10751e2daa2d3b74c5d5)
9. [Raspberry PI シリーズで分散環境構築(その9: Webクラスタ構築のケース(後半))](https://qiita.com/p_cub/items/c4c837a57e6487a076d4)

本稿は [第4回](https://qiita.com/p_cub/items/dd682de7de28276129e6) からの続きとなります。
調査してみた所、Raspberry PI OS(旧名 Raspbian) 以外のディストリビューションに関しては、U-boot 関連の設定を突き詰めないとPXEブートができない状態でしたので、Raspberry PI OS 以外のディストリビューションに関する情報はしばらくの間省略し、後日、別枠でまとめてみたいと思います。
また、クラスタノードとなるラズパイ向け OS のカスタマイズは

1. x86_64 マシン(NFSサーバ)上のテキストエディタで実行可能な範囲
2. x86_64 ホスト上のエミュレータ(qemu-static)/ラズパイ実機 どちらかで chroot して実行する必要がある範囲

に分類することが可能ですが、今回はテキストエディタで実行可能な範囲について記載することにします[^エミュレータ]。

[^エミュレータ]: ちなみに、やろうと思えば大部分の作業をテキストエディタで行うことも可能なんですが、その場合、膨大な数の設定ファイルをいじったり、シンボリックを張り直すことになります。そんなことをするよりも、エミュレータなどからコマンド一発、で処理したほうが賢明です。

## (参考) 筆者の環境
![RaspiCloudSystem.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267238/9d0ab7af-1f13-cf7b-3cc9-9b4e8c6cb4fd.png)




# 0. 前提条件定義

本稿では、PXEサーバとNFSサーバが分離している状態であるとして、以下の条件で説明していきます。

## 0.1. サブネット関連
PXE サーバがサブネット内で唯一の DHCP サーバとなる場合にのみ必要です。
 
| 項目名 | 値 |
|:----|:----|
|自組織サブネット|192.168.172.0/24|
|デフォルトゲートウェイ|192.168.172.254|
|WiFi環境| モデルにかかわらず、利用しない(wpa_supplicant 関連ファイルは編集しない)|

## 0.2. DNS サーバ関連
PXE サーバがサブネット内で唯一の DHCP サーバとなる場合の dnsmasq.conf, 及びラズパイ向け /etc/resolv.conf ファイル編集時に利用します。

| 項目名 | 値 |
|:----|:----|
|最も近いサーバホスト IP| 192.168.172.53|
|外部サーバ1 IP|8.8.8.8|
|外部サーバ2 IP|8.8.4.4|

## 0.3. NTP サーバ関連
ラズパイ向け /etc/systemd/timesyncd.conf ファイル編集時に利用します

| 項目名 | 値 |
|:----|:----|
|最も近いサーバホスト IP |192.168.172.123|
|外部サーバ DNS 名 |ntp.nict.jp|

## 0.4. クライアント(ラズパイノード)関連

| 項目名 | 値 |
|:----|:----|
|総ホスト数|2B/3B/3B+/4 各1台の計4台|
|DHCP によって割り当てられる IP| 192.168.172.32 〜 192.168.172.35|
|ホスト名|古いモデル順に raspi1 〜 raspi4|

## 0.5. PXE(dnsmasq: DHCP+tftp) サーバ関連
tftp 接続先として DHCP サーバで利用します

| 項目名 | 値 |
|:----|:----|
|ホスト IP|192.168.172.16|
|ホスト名|pxeserver|
|tftp ルート(ベース)|/srv/tftp|

## 0.6. NFS サーバ関連
/boot/cmdline.txt, 及び /etc/fstab 等の編集時に利用します

| 項目名 | 値 |
|:----|:----|
|ホスト IP|192.168.172.17|
|ホスト名|nfsserver|
|OS用ルート基準フォルダ|/exports/os4pi |
|2B用 Raspbian ルート|192.168.172.17:/exports/os4pi/raspbian/armhf|
|3B用 Raspbian ルート|192.168.172.17:/exports/os4pi/raspbian/armhf_64|
|3B+/4 用 Raspbian ルート|192.168.172.17:/exports/os4pi/raspbian/aarch64|
|ホーム用フォルダ|192.168.172.17:/exports/home4pi|

## 0.7. HTTP/FTP プロキシサーバ関連
自組織内に Squid 等で構築された Web プロキシサーバがある場合、環境変数を設定するために使用します。

| 項目名 | 値 |
|:----|:----|
|ホスト IP| 192.168.172.80 |
|プロキシポート|3128|
|接続用認証|無し|


# 1. /etc/hosts ファイルの設定

上記条件をまとめた、ラズパイノード向け /etc/hosts ファイルを NFS サーバの root アカウントで予め作成しておきましょう。ここで作成した /etc/hosts ファイルを全ディストリビューションにコピーして使いますから、NFS 共有ディレクトリの直下に作成しておくといいでしょう。

```shell-session
# cd /exports/os4pi
# vi etc_hosts
(省略: 内容は下記)
# for A in armhf armhf_64 aarch64; do mv raspbian/$A/etc/hosts raspbian/$A/etc/hosts.bak; cp -pf etc_hosts raspbian/$A/etc/hosts; done
```

```config
# /etc/hosts (ラズパイ向け)
127.0.0.1 localhost

# NFS マウントのときに必要になるので、
# NFS サーバのエントリは必須
192.168.172.17 nfsserver

# 各クラスタノードも必須
192.168.172.32 raspi1
192.168.172.33 raspi2
192.168.172.34 raspi3
192.168.172.35 raspi4

# ここから先はなくても良いエントリなので、
# 各自の必要性と趣味に応じて追加してください
192.168.172.16 pxeserver     
192.168.172.53 dnsserver     
192.168.172.80 proxyserver   
192.168.172.123 ntpserver    
192.168.172.254 gateway      
```

# 2. /etc/hostname ファイルの編集

/etc/hostname ファイルの中身に何か文字列が書き込まれていると、全ノード同じホスト名になってしまいますので、/etc/hostname ファイルの中身は空にします。/etc/hosts ファイルさえ設定されていれば、シェル等も DHCP で与えられた IP と /etc/hosts から自ホスト名を解決してくれるようになります。

```
# cd /exports/os4pi/raspbian
# for A in armhf armhf_64 aarch64; do mv $A/etc/hostname $A/etc/hostname.bak;　touch $A/etc/hostname; done
```

# 3. /etc/resolv.conf ファイルの編集

デフォルトの状態ですと、/run/resolv.conf へのシンボリックリンクとなっていますが、この状態ですと qemu-static 環境などで apt-get が実行できない状態になってしまいます。シンボリックリンクから実ファイルへと変更しておきます。このファイルも全ディストリビューション共通となりますから、予め共有ディレクトリに作成しておきます。

```shell-session
# cd /exports/os4pi
# vi etc_resolv.conf
(内容は下記)
# for A in armhf armhf_64 aarch64; do rm -f raspbian/$A/etc/resolv.conf; cp -pf etc_resolv.conf raspbian/$A/etc/resolv.conf; done
#
```

```config
# /etc/resolv.conf (ラズパイ向け)
# 自組織内/プロバイダ指定の DNS サーバがあるなら
nameserver 192.168.172.53
# 以下、外部DNSサーバ
nameserver 8.8.8.8
nameserver 8.8.4.4
```

# 4. /etc/systemd/timesyncd.conf ファイルの設定
最近の(systemd を利用する)ディストリビューションでは、ホストの時刻合わせに systemd が持つ timesyncd を利用する場合が多く、旧来の /etc/ntp.conf を使用しません[^NTP]。その代わりに /etc/systemd/timesyncd.conf の変更が必要となります。オリジナルの /etc/systemd/timesyncd.conf を1つ改変し、全アーキテクチャ向けに同じ内容を展開します。

```shell-session
# cd /exports/os4pi/raspbian
# cp -pf armhf/etc/systemd/timesyncd.conf ./
# vi ./timesyncd.conf
(内容は下記)
# for A in armhf armhf_64 aarch64; do mv $A/etc/systemd/timesyncd.conf $A/etc/sytemdd/timesyncd.conf.bak; cp -pf ./timesyncd.conf $A/etc/systemd/; done
```

```config
# /etc/systemd/timesyncd.conf (ラズパイ向け)
# -----
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See timesyncd.conf(5) for details.

[Time]
# 自組織内やプロバイダ指定の NTPサーバがある場合はそちらを優先しましょう
# ない場合は国内の NTP サーバ(ntp.nict.jp)にしましょう
NTP=192.168.172.123
# 自組織内/プロバイダ指定の NTP サーバがある場合であっても、FallbackNTP に国内 NTP サーバを指定するべき。
FallbackNTP=ntp.nict.jp
```

[^NTP]: ntpサーバにしたい場合は ntp.conf の変更が必要。 

# 5. /etc/fstab の設定(Raspberry Pi OS)
どんなディストリビューションであろうとも、microSD からインストールするために配布されている OS イメージの /etc/fstab はローカルディスクをマウントする設定になっていますから、ごっそり削除し、新たな /etc/fstab を構築します。
この内容は ディストリビューション毎に異なってきますから、各ディストリビューションのルートディレクトリに保存して、各アーキテクチャ毎に同内容を配布していきます。

```shell-session
# cd /exports/os4pi/raspbian
# vi etc_fstab
(省略,内容は下記)
# for A in armhf armhf_64 aarch64; do mv $A/etc/fstab $A/etc/fstab.bak; cp -pf ./etc_fstab $A/etc/fstab; done
```

```config
# /etc/fstab (Raspberry PI OS のラズパイ向け)
proc            /proc           proc    defaults            0       0
tmpfs           /dev/shm        tmpfs   defaults,nosuid,nodev,noexec 0       0
tmpfs           /tmp            tmpfs   defaults,nosuid,nodev,noexec 0       0
tmpfs           /var/tmp        tmpfs   defaults,nodev 0       0
tmpfs           /var/log        tmpfs   defaults,mode=755,size=100m  0       0
tmpfs           /var/spool/cron	tmpfs   defaults,mode=755            0       0
tmpfs           /var/lib/sudo   tmpfs   defaults,mode=711            0       0
tmpfs           /var/lib/dhcp   tmpfs   defaults,mode=755            0       0
tmpfs           /var/lib/systemd/rfkill   tmpfs defaults,mode=755    0       0
tmpfs           /var/lib/systemd/coredump tmpfs defaults,mode=755    0       0
tmpfs           /var/lib/systemd/timesync tmpfs defaults,mode=755    0       0
192.168.172.17:/exports/home4pi	/home	nfs	tcp,vers=3,rw,nolock,noatime,nofail	0	0
```

# 6. ロケール関連の設定
言語・タイムゾーン等の設定を予め行っておきます

## 6.1. /etc/locale.gen, /etc/locale.conf の編集
glibc の各種言語メッセージを生成させるための設定ファイルである locale.gen と、実際のシステム言語設定を同時に行います。

```shell-session
# cd /exports/os4pi/raspbian
# for A in armhf armhf_64 aarch64; do cd $A/etc; mv locale.gen locale.gen.bak; echo "ja_JP.UTF-8" >> locale.gen; echo "en_US.UTF-8" >> locale.gen; mv locale.conf locale.conf.bak; echo "LANG=ja_JP.UTF-8" >> locale.conf; cd ../../; done
```

## 6.2. /etc/localtime の編集
ローカルタイムを東京に設定します

```shell-session
# cd /exports/os4pi/raspbian
# for A in armhf armhf_64 aarch64; do cd $A/etc; ln -sf /usr/share/zoneinfo/Asia/Tokyo ./localtime; cd ../../; done
```

## 6.3. (オプション) /etc/environment にもロケール設定
ログインプロセスを経ない各種デーモンなどが参照する、環境変数設定用ファイルである /etc/environment にも
ロケール設定を追加しておくことをオススメします。

```shell-session
# cd /exports/os4pi/raspbian
# for A in armhf armhf_64 aarch64; do cd $A/etc; echo "TZ=Asia/Tokyo" >> environment; echo "LANG=ja_JP.UTF-8" >> environment; cd ../../; done
```

# 7. (オプション)プロキシ設定
組織内で Web プロキシサーバを利用する場合は、以下の設定をしておくと幸せになります。

```shell-session
# cd /exports/os4pi
# vi proxy.sh
(省略。内容は下記)
# for A in armhf armhf_64 aarch64; do cp ./proxy.sh raspbian/$A/etc/profile.d/; cat ./proxy.sh | grep -ve '^#' | sed -e 's/^export //g' >> raspbian/$A/etc/environment; done
```

```shell
# proxy.sh
# プロキシサーバ 192.168.172.80
# プロキシポート 3128
export http_proxy=http://192.168.172.80:3128
export ftp_proxy=http://192.168.172.80:3128
export no_proxy="127.* 192.168.172.*"
```

# 8. /boot/cmdline.txt ファイルの設定
ラズパイのブートローダーである bootcode.bin が、Linux カーネルパラメータを設定するために参照するファイルである、/boot/cmdline.txt を設定します。

インストールイメージからコピーした直後の状態ですと、

+ ルートファイルシステムとして指定されているローカルディスクの UUID がおかしいため、そのままではルートファイルシステムがマウントできない(初回ブート時に書き換えられる)
+ 変な init コマンドが含まれていて、microSD のファイルシステムサイズ拡張,fsck実行,デフォルトユーザーを追加,sshキーファイルの生成といった、ネットブートには不適切な処理が自動実行されてしまう

と全く使い物にならない状態ですから、手作業で作成する必要があります。
なお、全内容を1行に収め、改行コードを挿入してはいけません。

## 8.1. (参考) 変更前の状態

ちなみに、これがインストールイメージからコピーした直後の状態です。

```config
console=serial0,115200 console=tty1 root=PARTUUID=738a4d67-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet init=/usr/lib/raspi-config/init_resize.sh
```

## 8.2. 変更後の状態
上記の状態から、モデルに合わせ、以下の内容に書き換えます。
なお、GPIO に USBシリアルケーブルを接続してブートログを読む、という予定がない場合は、先頭の 'console=serial0,115200' 部分を削除して構いません。

### 2B用

```config
console=serial0,115200 console=tty1 rootwait elevator=deadline ip=dhcp root=/dev/nfs nfsroot=192.168.172.17:/exports/os4pi/raspbian/armhf
```

### 3B用

```config
console=serial0,115200 console=tty1 rootwait elevator=deadline ip=dhcp root=/dev/nfs nfsroot=192.168.172.17:/exports/os4pi/raspbian/armhf_64
```

### 3B+/4 用

```config
console=serial0,115200 console=tty1 rootwait elevator=deadline ip=dhcp root=/dev/nfs nfsroot=192.168.172.17:/exports/os4pi/raspbian/aarch64
```

今回のカスタマイズはここまでとなります。

# 次回予告
次回は、qemu-static またはラズパイ実機を利用して chroot 環境内でラズパイノードのOSをカスタマイズする部分を記載したいと思います。