犬でも分かるPXEブート(4):TFTPサーバの構築

前回は、PXEブートに必要となるDHCPサーバの構築について解説しました。PXEブートを実現するために必要な次の構成要素は TFTPサーバ です。ここでは、TFTPサーバのインストール方法と、PXEブートに必要な設定を分かりやすく説明します。
PXEブートのフローの図でいうと、以下の赤線の範囲が対象です。

TFTPサーバの処理

PXEブートにおけるTFTPサーバの役割

一般的なTFTPサーバの役割は、
・TFTPサーバ
です(これだと身も蓋もない書き方だなー。もう少し具体的に言うと、TFTP(Trival File Transfer Protocol)というプロトコルでファイルを転送するサービスを提供すること、です)。
FTPとの違いは、TFTPはシンプルな作りであるために負荷が軽いことと、認証がないことだそうです。
なるほど、軽い故にPXEブートのおけるファイル転送で使用されているのですね。。具体的には、PXEブートのプロセスにおいて、以下の重要なファイルを転送するのに使用されます。
・システムを起動するためのブートローダ
・起動した後にメモリ上でOSを稼働させる際のカーネル
・起動した後にメモリ上でOSを稼働させる際のRAMイメージ
・起動メニューを定義した grub.cfgファイル

TFTPサーバのインストール

RedHatやRocky Linuxでは、以下のコマンドでTFTPサーバをインストールすることができます。

# dnf -y install tftp-server

TFTPサーバのテストのために、TFTPクライアントもあったほうが良いので同時にインストールしちゃいましょう。

# dnf -y install tftp

TFTPサーバをインストールしたら、/var/lib/tftpboot というディストリが作成されていることを確認して下さい。これが、TFTPサーバでファイルを配信する場合の topディストリとなります。

TFTPサーバの設定

設定と言えるほど、設定というものはないのですが、PXEブート環境を構築していくときに、デバッグが楽にできるほうが良いので、TFTPサーバのログを /var/log/messages に出力するように、TFTPの起動スクリプト /usr/lib/systemd/system/tftp.service において、ExecStart行を以下の通り修正します。

ExecStart=/usr/sbin/in.tftpd -s /var/lib/tftpboot -vv

要するに、「-vv」というオプションを付けるってことです。
起動スクリプトを修正したときは、必ず以下のコマンドを実行して、システムに修正を反映するようにします。

# systemctl daemon-reload

TFTPサーバの起動

/usr/lib/systemd/system/tftp.serviceを上記の通りに修正したら、TFTPサーバを以下の通り起動します。

# systemctl start tftp.service

システム起動時にTFTPサーバを自動起動するために、自動起動の設定もしておきましょう。

# systemctl enable tftp.service

PXEブートに必要なファイルの配備

TFTPサーバで配信するファイルのtopディストリは、/var/lib/tftpboot/ です。PXEブートで使用するファイルはこのディストリ配下に置くことにします。このときの注意点は、
「シンボリックリンクはダメよ…」
ということです。配信するファイルは実ファイルとして置いてください。この点がHTTPサーバと違うので不便なんだよなー。

PXEブートに必要なファイルはどこから持ってくるの?

ブートローダ、カーネル、RAMイメージは、OSディストリビューションのISOファイルの中に格納されています。ISOファイルをファイルシステムとしてマウントすれば、cpコマンドで取り出すことが可能です。
以下の例は、RedHat Enterprise Linux (RHEL) 8.8のISOファイル /tmp/rhel-8.8-x86_64-dvd.iso を /media/ にマウントするコマンドです。

# mount -t iso9660 -o loop /tmp/rhel-8.8-x86_64-dvd.iso /media

このようにすることで、/media/ 配下から ISOイメージの中に格納されているファイルにアクセスすることができます。以降、/media/ にISOイメージがマウントされている前提で解説を進めます。

ブートローダの配備

x86_64アーキテクチャのマシンのブートローダは、BOOTX64.EFI です。これは、OSディストリビューションのISOファイルの以下のパスに格納されています。

/media/EFI/BOOT/BOOTX64.EFI

このファイルを /var/lib/tftpboot/ 配下にコピーします。ついでに、以下のファイルも同ディストリにコピーして下さい。

/media/EFI/BOOT/grubx64.efi

ブートローダのファイル名(パス)は、/etc/dhcp/dhcpd.conf のfilename における定義と一致しなくてはならないことに注意して下さい。

カーネルの配備

メモリ上にOSを起動する際のカーネルは、OSディストリビューションのISOファイルの以下のパスに格納されています。

/media/images/pxeboot/vmlinuz

このファイルを /var/lib/tftpboot/pxeboot/rhel-8.8-x86_64/ 配下にコピーします(このディレクトリは予め作成しておきます)。ちなみに、このコピー先のパスは、後述のgrub.cfgファイルに定義します。

RAMイメージの配備

メモリ上にOSを起動する際のカーネルは、OSディストリビューションのISOファイルの以下のパスに格納されています。

/media/images/pxeboot/initrd.img

このファイルを /var/lib/tftpboot/pxeboot/rhel-8.8-x86_64/ 配下にコピーします(このディレクトリは予め作成しておきます)。ちなみに、このコピー先のパスは、後述のgrub.cfgファイルに定義します。

grub.cfgファイルの作成

grub.cfg ファイルは起動時のメニューと起動するカーネル及びRAMイメージを定義したファイルです。RedHatやRocky Linuxのカーネルには、オプションでインストールに使用するレポジトリやkickstartファイルを指定することもできます。

kickstartのためのgrub.cfgファイル

以下は、kickstartファイルを使ってOSを自動インストールするための grub.cfg ファイルの例です。

set timeout=10
default=0
menuentry 'RHEL 8.8 x86_64 (kickstart)' {
linuxefi /pxeboot/rhel-8.8-x86_64/vmlinuz ip=dhcp vga=normal inst.graphical inst.resolution=1024x768 inst.repo=http://192.168.2.203/repositories/rhel-8.8-x86_64/ inst.ks=http://192.168.2.203/repositories/kickstarts/rhel-8.8.cfg
initrdefi /pxeboot/rhel-8.8-x86_64/initrd.img
}

内容について解説します。

set timeout=10

ブート時において、メニューを表示する時間を設定します。この例では10秒を指定しています。

menuentry 'RHEL 8.8 x86_64 (kickstart)'

ブート時に表示するメニューのラベルです。PXEブートの処理が正しく進めば、ブート時にこのラベルが表示されます。デバッグをやりやすくするために、他と区別しやすいを記述しておくことをお勧めします。

inst.graphical

インストール処理をグラフィカルモードで進めます。kickstartによるOS自動インストールを行う場合でも、kickstartファイルの記述内容をデバッグするのには、グラフィカルモードのほうがエラー箇所の判別が容易です。

inst.resolution=1024x768

kickstartの自動インストールにおいて、コンソールに何も表示されない場合は、解像度に1024×768を指定してみて下さい。インストールするサーバやコンソールの表示方法にも依存するのかもしれませんが、RHEL 8.8でkickstartインストールを行うときに解像度を指定する必要がありました。

inst.repo=http://192.168.2.203/repositories/rhel-8.8-x86_64/

インストールするOSのレポジトリのURLを指定します。私の環境では、192.168.2.201のサーバでHTTPサーバを構築して、RHEL8.8用のレポジトリを運用しています。レポジトリの構築は、次章で解説することにします。

inst.ks=http://192.168.2.203/repositories/kickstarts/rhel-8.8.cfg

OSの自動インストールの仕様を定義したkickstartファイルのURLを指定します。kickstartファイルの作成方法は、次章で解説することにします。

手動でインストールする場合のgrub.cfgファイル

前述のgrub.cfgファイルで inst.ks を指定しなければ、DVDからOSをインストールする手順と同じように、RHELやRocky Linuxのインストーラを手作業で操作して、インストール作業を行うことができます。サーバにインストールメディア(DVDやUSBフラッシュメモリ)を付けたり外したりする必要がないので楽になります。

set timeout=10
default=0
menuentry 'RHEL 8.8 x86_64 (manual)' {
linuxefi /pxeboot/rhel-8.8-x86_64/vmlinuz ip=dhcp vga=normal inst.graphical inst.resolution=1024x768 inst.repo=http://192.168.2.203/repositories/rhel-8.8-x86_64/
initrdefi /pxeboot/rhel-8.8-x86_64/initrd.img
}

PXEブートするサーバ毎にgrub.cfgファイルを切り換えたい

PXEブートにおいて、PXE対応デバイスが検索するgrub.cfgファイルを検索するとき、ファイル名の優先順位は以下のようになっています。

① grub.cfg-01-<Macアドレス>
② grub.cfg-<ipアドレスを16進数に変換した8桁の文字列>
③ grub.cfg-<ipアドレスを16進数に変換した先頭7桁の文字列>
④ grub.cfg-<ipアドレスを16進数に変換した先頭6桁の文字列>
⑤ grub.cfg-<ipアドレスを16進数に変換した先頭5桁の文字列>
⑥ grub.cfg-<ipアドレスを16進数に変換した先頭4桁の文字列>
⑦ grub.cfg-<ipアドレスを16進数に変換した先頭3桁の文字列>
⑧ grub.cfg-<ipアドレスを16進数に変換した先頭2桁の文字列>
⑨ grub.cfg-<ipアドレスを16進数に変換した先頭1桁の文字列>
⑩ grub.cfg

具体的な例で示しましょう。
PXEブートする対象サーバのMacアドレス(PXE対応NICのMacアドレス) が 00:e0:4c:38:6c:39 だとします。DHCPが割り当てたIPアドレスが 192.168.2.102 だとします。この場合、①に相当するファイルは、
grub.cfg-01-00-e0-4c-38-6c-39
となります(Macアドレスの左に01が付くことに注意して下さい、またMacアドレスの区切り文字は「-」となります)。
次に、「ipアドレスを16進数に変換した8桁の文字列」についてですが、192.168.2.102 のそれぞれのオクテットを16進数に変換すると、192→C0, 168→A8, 2→02, 102→66 となるので C0A80266 という8桁の文字列が出来上がります。従って、②の相当するファイルは、
grub.cfg-C0A80266
となります。③は grub.cfg-C0A8026 、⑨は grub.cfg-C となることが理解できるでしょうか。
具体的な例で示しましょう。
PXEブートする対象サーバのMacアドレス(PXE対応NICのMacアドレス) が 00:e0:4c:38:6c:39 だとします。DHCPが割り当てたIPアドレスが 192.168.2.102 だとします。この場合、①に相当するファイルは、
grub.cfg-01-00-e0-4c-38-6c-39
となります(Macアドレスの左に01が付くことに注意して下さい、またMacアドレスの区切り文字は「-」となります)。
次に、「ipアドレスを16進数に変換した8桁の文字列」についてですが、192.168.2.102 のそれぞれのオクテットを16進数に変換すると、192→C0, 168→A8, 2→02, 102→66 となるので C0A80266 という8桁の文字列が出来上がります。従って、②の相当するファイルは、
grub.cfg-C0A80266
となります。③は grub.cfg-C0A8026 、⑨は grub.cfg-C となることが理解できるでしょうか。

このファイル名を検索する順序は、/var/log/messagesに出力されるTFTPサーバのログから確認することができます。

Apr 29 14:59:13 rocky1 dhcpd[184850]: DHCPDISCOVER from 00:e0:4c:38:6c:39 via enp8s0
Apr 29 14:59:14 rocky1 dhcpd[184850]: DHCPOFFER on 192.168.2.102 to 00:e0:4c:38:6c:39 via enp8s0
Apr 29 14:59:17 rocky1 dhcpd[184850]: DHCPREQUEST for 192.168.2.102 (192.168.2.203) from 00:e0:4c:38:6c:39 via enp8s0
Apr 29 14:59:17 rocky1 dhcpd[184850]: DHCPACK on 192.168.2.102 to 00:e0:4c:38:6c:39 via enp8s0
Apr 29 14:59:17 rocky1 in.tftpd[184853]: RRQ from ::ffff:192.168.2.102 filename BOOTX64.EFI
Apr 29 14:59:17 rocky1 in.tftpd[184853]: tftp: client does not accept options
Apr 29 14:59:17 rocky1 in.tftpd[184854]: RRQ from ::ffff:192.168.2.102 filename BOOTX64.EFI
Apr 29 14:59:17 rocky1 in.tftpd[184854]: Client ::ffff:192.168.2.102 finished BOOTX64.EFI
Apr 29 14:59:17 rocky1 in.tftpd[184855]: RRQ from ::ffff:192.168.2.102 filename grubx64.efi
Apr 29 14:59:17 rocky1 in.tftpd[184855]: Client ::ffff:192.168.2.102 finished grubx64.efi
Apr 29 14:59:18 rocky1 in.tftpd[184856]: RRQ from ::ffff:192.168.2.102 filename /grub.cfg-01-00-e0-4c-38-6c-39
Apr 29 14:59:18 rocky1 in.tftpd[184856]: Client ::ffff:192.168.2.102 File not found /grub.cfg-01-00-e0-4c-38-6c-39
Apr 29 14:59:18 rocky1 in.tftpd[184856]: sending NAK (1, File not found) to ::ffff:192.168.2.102
Apr 29 14:59:18 rocky1 in.tftpd[184857]: RRQ from ::ffff:192.168.2.102 filename /grub.cfg-C0A80266
Apr 29 14:59:18 rocky1 in.tftpd[184857]: Client ::ffff:192.168.2.102 File not found /grub.cfg-C0A80266
Apr 29 14:59:18 rocky1 in.tftpd[184857]: sending NAK (1, File not found) to ::ffff:192.168.2.102
Apr 29 14:59:18 rocky1 in.tftpd[184858]: RRQ from ::ffff:192.168.2.102 filename /grub.cfg-C0A8026
Apr 29 14:59:18 rocky1 in.tftpd[184858]: Client ::ffff:192.168.2.102 File not found /grub.cfg-C0A8026
Apr 29 14:59:18 rocky1 in.tftpd[184858]: sending NAK (1, File not found) to ::ffff:192.168.2.102
Apr 29 14:59:18 rocky1 in.tftpd[184859]: RRQ from ::ffff:192.168.2.102 filename /grub.cfg-C0A802
Apr 29 14:59:18 rocky1 in.tftpd[184859]: Client ::ffff:192.168.2.102 File not found /grub.cfg-C0A802
Apr 29 14:59:18 rocky1 in.tftpd[184859]: sending NAK (1, File not found) to ::ffff:192.168.2.102
Apr 29 14:59:18 rocky1 in.tftpd[184860]: RRQ from ::ffff:192.168.2.102 filename /grub.cfg-C0A80
Apr 29 14:59:18 rocky1 in.tftpd[184860]: Client ::ffff:192.168.2.102 File not found /grub.cfg-C0A80
Apr 29 14:59:18 rocky1 in.tftpd[184860]: sending NAK (1, File not found) to ::ffff:192.168.2.102
Apr 29 14:59:18 rocky1 in.tftpd[184861]: RRQ from ::ffff:192.168.2.102 filename /grub.cfg-C0A8
Apr 29 14:59:18 rocky1 in.tftpd[184861]: Client ::ffff:192.168.2.102 File not found /grub.cfg-C0A8
Apr 29 14:59:18 rocky1 in.tftpd[184861]: sending NAK (1, File not found) to ::ffff:192.168.2.102
Apr 29 14:59:18 rocky1 in.tftpd[184862]: RRQ from ::ffff:192.168.2.102 filename /grub.cfg-C0A
Apr 29 14:59:18 rocky1 in.tftpd[184862]: Client ::ffff:192.168.2.102 File not found /grub.cfg-C0A
Apr 29 14:59:18 rocky1 in.tftpd[184862]: sending NAK (1, File not found) to ::ffff:192.168.2.102
Apr 29 14:59:18 rocky1 in.tftpd[184863]: RRQ from ::ffff:192.168.2.102 filename /grub.cfg-C0
Apr 29 14:59:18 rocky1 in.tftpd[184863]: Client ::ffff:192.168.2.102 File not found /grub.cfg-C0
Apr 29 14:59:18 rocky1 in.tftpd[184863]: sending NAK (1, File not found) to ::ffff:192.168.2.102
Apr 29 14:59:18 rocky1 in.tftpd[184864]: RRQ from ::ffff:192.168.2.102 filename /grub.cfg-C
Apr 29 14:59:18 rocky1 in.tftpd[184864]: Client ::ffff:192.168.2.102 File not found /grub.cfg-C
Apr 29 14:59:18 rocky1 in.tftpd[184864]: sending NAK (1, File not found) to ::ffff:192.168.2.102
Apr 29 14:59:18 rocky1 in.tftpd[184865]: RRQ from ::ffff:192.168.2.102 filename /grub.cfg
Apr 29 14:59:18 rocky1 in.tftpd[184865]: Client ::ffff:192.168.2.102 finished /grub.cfg

従って、この規則性を利用し、例えば grub.cfg-01-<Macアドレス> というファイルを作成しておけば、サーバに固有のgrub.cfgファイルを定義すること可能になります。このことは、サーバ毎にkickstartファイルを切り換えて使用したい場合等に有用です。

広告主へのリンク




このブログにおける関連リンク

犬でも分かるPXEブート(1):PXEブートとは
犬でも分かるPXEブート(2):起点は電源ON
犬でも分かるPXEブート(3):DHCPサーバの構築
犬でも分かるPXEブート(5):HTTPサーバとリポジトリーの構築
犬でも分かるPXEブート(6):kickstartによるOS自動インストール
犬でも分かるPXEブート(7):実際にやってみた

コメント

タイトルとURLをコピーしました