[VMware] Nested ESXi 8.0 U3 で PXE ブートの検証

今回は、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のインストーラがクライアント
  で起動されます。

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

・enable-tftp + tftp-root=/var/lib/tftpboot で TFTP サーバー として
 動作させる。
・dhcp-boot=bootx64.efi で UEFI クライアントは TFTP のルートで
 bootx64.efi を探す。

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

PXE ローダー(bootx64.efi) が boot.cfg を TFTP ルート直下から探すっぽく、
サブディレクトリに boot.cfg がある状態にすると “file /var/lib/tftpboot/boot.cfg
not found” で失敗したため、今回はとりあえず全部 TFTP ルート直下に全てをコピー
してます。(動作検証ということもあり)

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/

今回、/var/lib/tftpboot/ 直下に全て置いてるため boot.cfg はデフォルトのままとし、編集は特に必要ありません。

ファイアウォール設定

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 を介してダウンロードされます。

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 等を使用するのが良さそうです。

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