目次
概要
CentOS7で構築済みのRaspberry PiをNFSブートする。
OSがRaspbianの記事は散見されたが、CentOSは見つからなかったのでやってみた。
概要図
構成
※rpi2bpはストレージNW(172.16.1.0/24)用のIFを持っていないため、管理NW(172.16.0.0/24)用のIFを使用する。分けたほうが安全。いつか追加したい。前提
- Raspberry PiのOSはCentOS7とする。
- NFSサーバは構築済みとする。
- 手順の流れはこちらの記事をベースにする。
手順
1 - NFSサーバの準備
NFSサーバにデータ移行先の領域を作成する。
file01:~# mkdir -p /nfs/rpi2bp/root file01:~# ls -d /nfs/rpi2bp/root/ /nfs/rpi2bp/root/
2 - Raspberry Piの移行準備
Raspberry Piの移行元の領域を特定できる情報を確認しておく。具体例には、マウントポイント"/"にマウントされているパーティションのUUIDと、何番目のパーティションかを確認する。
[root@rpi2bp~]# cat /etc/fstab #Generated by RootFS Build Factory LABEL=1BBF2D52 /boot vfat noatime 0 0 #UUID=f28d9939-d00d-4e9e-aceb-1ac7b3e607ce swap swap noatime 0 0 UUID=8ceb6fa2-fa6e-4024-a5c6-71e3f063b21b / ext4 noatime 0 0 [root@rpi2bp~]#
[root@rpi2bp~]# blkid /dev/mmcblk0p1: SEC_TYPE="msdos" LABEL="1BBF2D52" UUID="7E9B-D0E2" TYPE="vfat" /dev/mmcblk0p2: UUID="f28d9939-d00d-4e9e-aceb-1ac7b3e607ce" TYPE="swap" /dev/mmcblk0p3: UUID="8ceb6fa2-fa6e-4024-a5c6-71e3f063b21b" TYPE="ext4" /dev/mmcblk0: PTTYPE="dos"
一応、"/"直下を目視しておく。移行前後の状態を比較するのが手堅いが、今回は割愛する。
[root@rpi2bp~]# ls -l /
(中略)
[root@rpi2bp~]#
Raspberry Piをシャットダウンする。
[root@rpi2bp~]# systemctl poweroff
3 - データ移行
Raspberry PiのmicroSDHCカードを取り外し、適当なLinuxの物理マシンにマウントする。そのへんに転がっていたmicroSDHCカード->USB Type-A変換アダプタを使用した。
※NFSサーバに直接マウントできるならその方がスマート。その際、手順は柔軟に読み替えること。
[root@linux ~]# tail /var/log/messages Jan 10 10:40:37 linux kernel: usbcore: registered new interface driver usb-storage Jan 10 10:40:37 linux kernel: usbcore: registered new interface driver uas Jan 10 10:40:38 linux kernel: scsi 4:0:0:0: Direct-Access Generic- SD/MMC 1.00 PQ: 0 ANSI: 0 CCS Jan 10 10:40:38 linux kernel: sd 4:0:0:0: Attached scsi generic sg4 type 0 Jan 10 10:40:39 linux kernel: sd 4:0:0:0: [sdc] 62333952 512-byte logical blocks: (31.9 GB/29.7 GiB) # microSDHCカードの容量で検討がつく Jan 10 10:40:39 linux kernel: sd 4:0:0:0: [sdc] Write Protect is off Jan 10 10:40:39 linux kernel: sd 4:0:0:0: [sdc] No Caching mode page found Jan 10 10:40:39 linux kernel: sd 4:0:0:0: [sdc] Assuming drive cache: write through Jan 10 10:40:39 linux kernel: sdc: sdc1 sdc2 sdc3 Jan 10 10:40:39 linux kernel: sd 4:0:0:0: [sdc] Attached SCSI removable disk [root@linux ~]#
デバイス名を確認する。
[root@linux ~]# fdisk -l (中略) ディスク /dev/sdc: 29.7 GiB, 31914983424 バイト, 62333952 セクタ 単位: セクタ (1 * 512 = 512 バイト) セクタサイズ (論理 / 物理): 512 バイト / 512 バイト I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト ディスクラベルのタイプ: dos ディスク識別子: 0xc1356df5 デバイス 起動 開始位置 終了位置 セクタ サイズ Id タイプ /dev/sdc1 2048 616447 614400 300M c W95 FAT32 (LBA) /dev/sdc2 616448 1665023 1048576 512M 82 Linux スワップ / Solaris /dev/sdc3 1665024 62332927 60667904 29G 83 Linux [root@linux ~]#
auto mountはされないらしい。LinuxサーバにUSBメモリを接続するのなんていつぶりだろう。
[root@linux ~]# df ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置 devtmpfs 26658024 0 26658024 0% /dev tmpfs 26677076 0 26677076 0% /dev/shm tmpfs 26677076 25976 26651100 1% /run tmpfs 26677076 0 26677076 0% /sys/fs/cgroup /dev/sda3 138083456 2978132 135105324 3% / /dev/sda1 1038336 256112 782224 25% /boot /dev/sdb 524032000 139640064 384391936 27% /var/lib/libvirt/images tmpfs 5335412 0 5335412 0% /run/user/0 [root@linux ~]#
UUIDを元に該当のパーティションを特定する。
[root@linux ~]# blkid /dev/sda1: UUID="152d7284-d558-4ae8-90f4-d5bc512df3ca" BLOCK_SIZE="512" TYPE="xfs" PARTUUID="823f64c0-01" /dev/sda2: UUID="9bc5f618-dc5e-4737-bf1c-a4132416d5e8" TYPE="swap" PARTUUID="823f64c0-02" /dev/sda3: UUID="bfc34690-3574-489b-a9c4-5eb365593778" BLOCK_SIZE="512" TYPE="xfs" PARTUUID="823f64c0-03" /dev/sdb: UUID="0b516580-3c70-424e-932f-c4878aaee15a" BLOCK_SIZE="512" TYPE="xfs" /dev/sdc1: SEC_TYPE="msdos" LABEL="1BBF2D52" UUID="7E9B-D0E2" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="c1356df5-01" /dev/sdc2: UUID="f28d9939-d00d-4e9e-aceb-1ac7b3e607ce" TYPE="swap" PARTUUID="c1356df5-02" /dev/sdc3: UUID="8ceb6fa2-fa6e-4024-a5c6-71e3f063b21b" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="c1356df5-03" [root@linux ~]#
該当のパーティションを任意のディレクトリにマウントする。ここでは/mediaとしている。
[root@linux ~]# mount /dev/sdc3 /media/ [root@linux ~]#
[root@linux ~]# df /media/ ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置 /dev/sdc3 29791292 7379480 21165432 26% /media [root@linux ~]#
中身をぱっと見して、マウントしたパーティションが間違っていないことを目視しておく。
[root@linux ~]# ls -l /media/ (中略) [root@linux ~]#
移行先のNFS領域を任意のディレクトリにマウントする。ここでは/mntとしている。
[root@linux ~]# mount file01:/nfs/rpi2bp/root /mnt/ [root@linux ~]#
[root@linux ~]# df /mnt ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置 file01:/nfs/rpi2bp/root 3876309120 3551585024 324724096 92% /mnt [root@linux ~]#
マウントしたNFS領域が間違っていないことを確認する。空ディレクトリなのできっと大丈夫。
[root@linux ~]# ls -l /mnt/ 合計 0 [root@linux ~]#
データをコピーする。
[root@linux ~]# cp -av /media/* /mnt/ '/media/4.1.11-v7+' -> '/mnt/4.1.11-v7+' (中略) '/media/var/www/html' -> '/mnt/var/www/html' [root@linux ~]#
# 7GBで6時間ほどかかった。どゆこと・・・
4 - fstabの変更
[root@linux ~]# vi /mnt/etc/fstab (詳細は編集後のcat結果を参照) [root@linux ~]#
[root@linux ~]# cat /mnt/etc/fstab #Generated by RootFS Build Factory LABEL=1BBF2D52 /boot vfat noatime 0 0 #UUID=f28d9939-d00d-4e9e-aceb-1ac7b3e607ce swap swap noatime 0 0 #UUID=8ceb6fa2-fa6e-4024-a5c6-71e3f063b21b / ext4 noatime 0 0 # この行をコメントアウトした [root@linux ~]#
5 - kernelのブートパラメータの変更
ここが核心。kernelのブートパラメータでrootパーティションを指定する箇所があるので、そこをNFSサーバに変更する。
該当ファイルが格納されている/bootパーティションがマウントされていないため、まずマウントする。マウント先は任意。
[root@linux ~]# mount /dev/sdc1 /media/boot/ [root@linux ~]#
[root@linux ~]# df /media/boot/ ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置 /dev/sdc1 307016 109600 197416 36% /media/boot [root@linux ~]#
設定ファイルをバックアップする。
[root@linux ~]# cp -p /media/boot/cmdline.txt{,_local} [root@linux ~]#
[root@linux ~]# ls -l /media/boot/cmdline.txt* -rwxr-xr-x 1 root root 120 12月 3 2015 /media/boot/cmdline.txt -rwxr-xr-x 1 root root 120 12月 3 2015 /media/boot/cmdline.txt_local [root@linux ~]#
編集する。
[root@linux ~]# cat /media/boot/cmdline.txt dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p3 rootfstype=ext4 elevator=deadline rootwait [root@linux ~]#
[root@linux ~]# vi /media/boot/cmdline.txt (詳細は編集後のcat結果を参照) [root@linux ~]#
[root@linux ~]# cat /boot/cmdline.txt dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/nfs nfsroot=172.16.0.5:/nfs/rpi2bp/root,tcp,vers=3 rw ip=172.16.0.10:::255.255.255.0::eth0:none elevator=deadline rootwait [root@linux ~]#
参考サイトの内容から以下を変えている。環境の違いが理由。
- console=tty1は残しておいた。モニタ直結して起動ログを見たかったため。
- NFSバージョンを指定した。指定しなかったら起動に失敗したため。当環境のNFSサーバ(NAS)が古いのが原因だろう・・・
- 固定IPにした。当環境のDHCPサーバは常時起動ではないため。
編集後の設定ファイルもバックアップしておく。理由は最後に説明する。
[root@linux ~]# cp -p /media/boot/cmdline.txt{,_nfs} [root@linux ~]#
[root@linux ~]# ls -l /boot/cmdline.txt* -rwxr-xr-x 1 root root 120 12月 4 2015 /boot/cmdline.txt -rwxr-xr-x 1 root root 120 12月 4 2015 /boot/cmdline.txt_local -rwxr-xr-x 1 root root 204 1月 11 2021 /boot/cmdline.txt_nfs [root@linux ~]#
microSDHCカード、NFSサーバをアンマウントする。
[root@linux ~]# umount /media/boot [root@linux ~]# umount /media [root@linux ~]# umount /mnt [root@linux ~]# df | grep -e "/media" -e "/mnt" [root@linux ~]#
microSDHCカードを物理マシンから取り外す。ejectコマンドなんてまともに使った記憶がない・・・
[root@linux ~]# eject /dev/sdc [root@linux ~]#
[root@linux ~]# fdisk -l /dev/sdc fdisk: /dev/sdc を open できません: メディアが見つかりません [root@linux ~]#
[root@linux ~]# blkid /dev/sda1: UUID="152d7284-d558-4ae8-90f4-d5bc512df3ca" BLOCK_SIZE="512" TYPE="xfs" PARTUUID="823f64c0-01" /dev/sda2: UUID="9bc5f618-dc5e-4737-bf1c-a4132416d5e8" TYPE="swap" PARTUUID="823f64c0-02" /dev/sda3: UUID="bfc34690-3574-489b-a9c4-5eb365593778" BLOCK_SIZE="512" TYPE="xfs" PARTUUID="823f64c0-03" /dev/sdb: UUID="0b516580-3c70-424e-932f-c4878aaee15a" BLOCK_SIZE="512" TYPE="xfs" [root@linux ~]#
[root@linux ~]# tail /var/log/messages (中略) Jan 10 17:11:38 linux kernel: sdc: detected capacity change from 31914983424 to 0 [root@linux ~]#
6 - NFSブートの動作確認
microSDHCカードをRaspberry Piに戻し、電源を投入する。
(前略) [ 7.830480] smsc95xx 1-1.1:1.0 eth0: link up, 100Mbps, full-duplex, lpa 0xCDE1 [ 7.873400] IP-Config: Complete: [ 7.879916] device=eth0, hwaddr=b8:27:eb:c0:40:d2, ipaddr=172.16.0.10, mask=255.255.255.0, gw=172.16.0.254 [ 7.896940] host=172.16.0.10, domain=, nis-domain=(none) [ 7.906302] bootserver=255.255.255.255, rootserver=172.16.0.5, rootpath= [ 7.964783] VFS: Mounted root (nfs filesystem) on device 0:19. [ 7.975329] devtmpfs: mounted [ 7.989648] Freeing unused kernel memory: 1024K [ 8.033763] Run /sbin/init as init process # この後にエラーが出なければたぶん大丈夫 [ 8.581484] SELinux: Disabled at runtime. (後略)
無事OSが起動したらログインし、ルートパーティションのマウント元がNFSサーバであることを確認する。
[root@rpi2bp~]# df /
ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
172.16.0.5:/nfs/rpi2bp/root 3876309064 3558929352 317379712 92% /
[root@rpi2bp~]#
比較用に、作業前の状態。
[root@rpi2bp~]# df /
ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
/dev/root 29791292 7378128 21166784 26% /
[root@rpi2bp~]#
おまけ
以降、ブート先の切り替えが一瞬でできる。これが大きなメリット。
[root@rpi2bp~]# ls -l /boot/cmdline.txt* -rwxr-xr-x 1 root root 120 12月 4 2015 /boot/cmdline.txt -rwxr-xr-x 1 root root 120 12月 4 2015 /boot/cmdline.txt_local # ローカルブート用 -rwxr-xr-x 1 root root 204 1月 11 2021 /boot/cmdline.txt_nfs # NFSブート用 [root@rpi2bp~]#
ローカル(microSDHCカード)ブートに切り替える。
[root@rpi2bp~]# cp -p /boot/cmdline.txt_local /boot/cmdline.txt cp: `/boot/cmdline.txt' を上書きしますか? y [root@rpi2bp~]#
[root@rpi2bp~]# systemctl reboot
NFSブートに切り替える。
[root@rpi2bp~]# cp -p /boot/cmdline.txt_nfs /boot/cmdline.txt cp: `/boot/cmdline.txt' を上書きしますか? y [root@rpi2bp~]#
[root@rpi2bp~]# systemctl reboot
参考1
cmdline.txtでNFSプロトコルのバージョンを指定しなかった場合の起動失敗ログ。
(前略) [ 6.874775] smsc95xx 1-1.1:1.0 eth0: link up, 100Mbps, full-duplex, lpa 0xCDE1 [ 6.933338] IP-Config: Complete: [ 6.945020] device=eth0, hwaddr=b8:27:eb:c0:40:d2, ipaddr=172.16.0.10, mask=255.255.255.0, gw=172.16.0.254 [ 6.963939] host=172.16.0.10, domain=, nis-domain=(none) [ 6.978492] bootserver=255.255.255.255, rootserver=172.16.0.5, rootpath= [ 7.023662] VFS: Mounted root (nfs filesystem) on device 0:19. [ 7.039656] devtmpfs: mounted [ 7.059176] Freeing unused kernel memory: 1024K [ 7.103754] Run /sbin/init as init process [ 19.033459] nfs: server 172.16.0.5 not responding, still trying [ 19.033863] nfs: server 172.16.0.5 not responding, still trying [ 19.033879] nfs: server 172.16.0.5 not responding, still trying [ 20.153428] nfs: server 172.16.0.5 not responding, still trying [ 34.023903] random: crng init done # ここで止まる(ハングしているわけではなさそう)