今回は、Nested ESXi を使って UEFI PXE ブート を検証しました。
PXE サーバーは AlmaLinux 9.5 上で dnsmasq を使い、TFTP だけで ESXi 8.0U3 の
インストーラを配布する構成です。
今回、ESXi 標準の bootx64.efi のみを使用して PXE ブートを行い、追加のブートローダー
(iPXE 等)を導入しないシンプルな方法で行います。
iPXE を組み合わせた高度な PXE ブートや kickstart を利用した自動インストールについては、
以下で記事にしています。
環境
<PXE ブートに使用する ESXi>
・ESXi 8.0 U3 (VMware-VMvisor-Installer-8.0U3-24022510.x86_64.iso)
・ブート方法: UEFI PXE ブート (bootx64.efi)
<PXE サーバー>
・PXE サーバー OS: AlmaLinux 9.5
・PXE サーバー IP アドレス: 192.168.1.70
・DHCP/TFTP: dnsmasq を使用
・DHCP で配布する IP 範囲: 192.168.1.230 ~ 192.168.1.250
・SELinux: 無効化
・ESXi 標準の bootx64.efi のみで PXE ブートを実行する
・ESXi インストールメディア(VMware-VMvisor-Installer-8.0U3-24022510.x86_64.iso): TFTP サーバーにすべて配置
<処理の流れ>
1. クライアントが IPアドレスを要求 (DHCP Discover)
-> クライアントが DHCP サーバーにブロードキャストで IP アドレスを要求します。
2. PXEサーバーが IP アドレスを提示 (DHCP Offer)
-> PXE サーバーがクライアントに IP アドレスとブートローダ(bootx64.efi)の情報
を提示します。
3. クライアントが IP アドレスを確定 (DHCP Request & ACK)
-> クライアントが受け取った IP アドレスを承認し、サーバーからブートローダの場所
を確定させます。
4. クライアントがブートローダをダウンロード
-> クライアントは TFTP サーバーから指定されたブートローダ(bootx64.efi)を
取得します。
5. ブートローダの起動
-> ダウンロードしたブートローダがクライアント上で起動されます。
6. カーネル・イメージのダウンロード
-> ブートローダが起動した後、カーネルやRAMイメージ(ESXi の場合、boot.cfg
で指定された各種ファイル)を TFTP 経由で順次取得します。
7. OS(またはインストーラ)の起動
-> 取得したカーネルやイメージをもとにOSまたはOSのインストーラがクライアント
で起動されます。
PXE サーバー (dnsmasq) のインストールと基本設定
dnsmasq(DHCP + TFTP) 及び SELinux の設定
1. SELinux の無効化 (検証向け)
# 一時的に無効化
setenforce 0
# 設定ファイルを編集し、再起動後も無効化
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
reboot
2. dnsmasq のインストール
dnf install -y dnsmasq
3. TFTP 用ディレクトリの作成
TFTP で配布するファイルを置くルートディレクトリを作成
mkdir -p /var/lib/tftpboot
4. /etc/dnsmasq.conf の編集
# DHCP レンジ指定 (12時間リース)
dhcp-range=192.168.1.230,192.168.1.250,255.255.255.0,12h
# DHCP/TFTP を ens33 だけで提供
interface=ens33
# DHCP オプション: ゲートウェイ
dhcp-option=3,192.168.1.254
# DHCP オプション: DNSサーバー
dhcp-option=6,192.168.1.24
# TFTP を有効化&ルートディレクトリ指定
enable-tftp
tftp-root=/var/lib/tftpboot
# UEFI PXE ブート用に、bootx64.efi をクライアントに渡す
dhcp-boot=bootx64.efi
# ログを詳細にしてデバッグしやすくする
log-dhcp
5. dnsmasq の起動
systemctl enable dnsmasq
systemctl start dnsmasq
# ステータス確認
systemctl status dnsmasq
ESXi 8.0 U3 ISO のコピーとファイル配置 (TFTP ルート直下)
1. ISO をマウントしてコピー
今回、AlmaLinux は仮想マシンに作成しているため、当該仮想マシンに ESXi の
インストーラー ISO を構成した上で、以下コマンドを実行しています。
# 一時マウント用ディレクトリを作成
mkdir /mnt/esxi80u3iso
# ISO をマウント
mount -o loop /dev/sr0 /mnt/esxi80u3iso/
# 中身をコピー
cp -r /mnt/esxi80u3iso/* /var/lib/tftpboot/
# マウント解除
umount /mnt/esxi80u3iso
2. bootx64.efi を TFTP ルート直下に移動
ISO の構造上、bootx64.efi は通常 efi/boot/bootx64.efi にあるため、そのままだと /var/lib/tftpboot/efi/boot/bootx64.efi の位置になります。
しかし dnsmasq.conf で dhcp-boot=bootx64.efi を設定したため、クライアントは
TFTP ルートで bootx64.efi を探すので、移動かコピー で /var/lib/tftpboot/ 直下へ
置きます。
mv /var/lib/tftpboot/efi/boot/bootx64.efi /var/lib/tftpboot/
ファイアウォール設定
firewall-cmd --permanent --add-service=dhcp
firewall-cmd --permanent --add-service=tftp
firewall-cmd --reload
動作検証
仮想マシンの作成
ポートグループは PXE サーバーを同じにします。

起動オプションにて、ファームウェアが EFI であることを確認する。

仮想マシンの起動
PXE から bootx64.efi が読み込まれ、その後 boot.cfg に従って各モジュール(b.b00 や coredump、crypto64.efi など)が TFTP を介してダウンロードされます。

(番外編) 各モジュールを http で取得できないのか?
bootx64.efi と boot.cfg 以外の各モジュールを http で取得しようと検証してみると
失敗し、パケットキャプチャでは以下のように出力されていました。
00:28:42.290502 IP (tos 0x0, ttl 64, id 38359, offset 0, flags [none], proto UDP (17), length 89)
192.168.1.244.1436 > 192.168.1.70.69: [udp sum ok] TFTP, length 61, RRQ "http://192.168.1.70/esxi8/b.b00" octet tsize 0 blksize 1468
00:28:47.331576 IP (tos 0x0, ttl 64, id 38360, offset 0, flags [none], proto UDP (17), length 70)
192.168.1.244.1437 > 192.168.1.70.69: [udp sum ok] TFTP, length 42, RRQ "crypto64.efi" octet tsize 0 blksize 1468
00:28:47.333705 IP (tos 0x0, ttl 64, id 38361, offset 0, flags [none], proto UDP (17), length 96)
192.168.1.244.1438 > 192.168.1.70.69: [udp sum ok] TFTP, length 68, RRQ "http://192.168.1.70/esxi8/crypto64.efi" octet tsize 0 blksize 1468
00:28:47.335200 IP (tos 0x0, ttl 64, id 38362, offset 0, flags [none], proto UDP (17), length 105)
192.168.1.244.1439 > 192.168.1.70.69: [udp sum ok] TFTP, length 77, RRQ "http://192.168.1.70/esxi8/efi/boot/crypto64.efi" octet tsize 0 blksize 1468
00:28:47.337728 IP (tos 0x0, ttl 64, id 38363, offset 0, flags [none], proto UDP (17), length 89)
192.168.1.244.1440 > 192.168.1.70.69: [udp sum ok] TFTP, length 61, RRQ "http://192.168.1.70/esxi8/b.b00" octet tsize 0 blksize 1468
クライアントが TFTP で「http://192.168.1.70/esxi8/b.b00」や「http://192.168.1.70/esxi8/crypto64.efi」といった“ファイル名”を要求している
ように見えます。
本来、boot.cfg で prefix=http://192.168.1.70/esxi8/ と書いたとすれば、
「HTTP プロトコルで b.b00 などを取得する」 という挙動を期待しますが、
実際には、ESXi の UEFI ローダー(bootx64.efi) が HTTP ダウンロード機能を持たず、
単純に「ファイル名として http://… を TFTP に問い合わせている」状態になっている
ように見えます。
その結果、キャプチャには FTP RRQ (Read Request) が並び、存在しないファイルと
してエラーになり「TFTP error」が出てしまっています。
各モジュールを http で取得したい場合には、iPXE 等を使用するのが良さそうです。