モチベーション
十数台のハードウェアPCを手に入れることができ、クラスタを構築することになった。
インストールするライブラリを頻繁に変更する可能性があるため、一括の環境更新がしやすいようネットワークブートによる環境構築を行うことにした。
本記事の対象
この投稿では、Ubuntu 22.04 Serverを用いて、PXEサーバー構築 〜 クライアントPCでインストールウィザード表示 までを対象としています。
なお、Autoinstallによる構成自動化については、別記事にまとめることにします。
作業環境
- サーバーPC
- OS:Ubuntu 22.04
- NIC
- オンボード 1Gbps NIC (
Intel Corporation Ethernet Connection (17) I219-V (rev 11)) - PCIe 1Gbps NIC (
Intel Corporation 82574L Gigabit Network Connection)
- オンボード 1Gbps NIC (
- クライアントPC
- UEFI Bootに対応
- NIC
- オンボード 1Gbps NIC
- PCIe 10Gbps NIC
作業手順
- まず、サーバー側とクライアント側をLANケーブルで接続します。
- 後述する理由により、2口以上のポートがある場合、なるべく
オンボードのNICやドライバが安定しているNICを介して接続することを推奨します
- 後述する理由により、2口以上のポートがある場合、なるべく
- サーバー側のネットワーク設定を行います
- 先ほど接続したLANケーブルが刺さっているポート(PXE Bootを提供するポート)のインタフェース名を把握しておきます。
- 以下の例では
eno1という名前のインタフェース を使用しています。
- 以下の例では
- そのインタフェースに静的IPを割り振ります
- DHCPサーバーを途中で建てるのですが、その範囲外のIPを指定しましょう
- やり方いろいろ
- netplan
- GUIから設定(今回私はこちらでやりました)
- 先ほど接続したLANケーブルが刺さっているポート(PXE Bootを提供するポート)のインタフェース名を把握しておきます。
- 以下の例では、
192.168.0.2/24というIPを設定しています
- 以後基本は Netbooting the server installer on amd64 - Ubuntu公式フォーラム にのっとって行います
手順3について、一部、私の環境に合わせて変更しています。詳しくは以下の通りです:
20.04を22.04に読み替えている
上記記事はUbuntuの20.04をベースに解説していますが、22.04をベースにできるように変更しています。
20.04のコードネームは focal で 22.04のコードネームは jammy です。本投稿の下の方に今回使用した設定ファイルとディレクトリ構造についてまとめていますので、そちらも参考にしてください。
ファイルないよって怒られた
apt download shim-signed
dpkg-deb --fsys-tarfile shim-signed*deb | tar x ./usr/lib/shim/shimx64.efi.signed -O > /srv/tftp/bootx64.efi
↓
apt download shim-signed
dpkg-deb --fsys-tarfile shim-signed*deb | tar x ./usr/lib/shim/shimx64.efi.signed.latest -O > /srv/tftp/bootx64.efi
UEFI bootingを使用
- 今回、クライアントPCがUEFIに対応しているものであったため、
Set up the files for legacy bootではなく、Set up the files for UEFI bootingの方で行いました。 - 近年のOSブートプロセスは、セキュリティ強化のために署名つきのものを使用しないといけない、など制約が厳しくなっているようです。
- レガシーなブート方法(
BIOS legacy boot)を紹介しているサイトがかなり多い印象です。 - また、
UEFI bootとBIOS legacy bootの手順を混同しているもの、Autoinstall等の構成自動化と混ぜて解説しておりどこでつまづいたのか結局よくわからなくなるサイト等も多い印象です。
- レガシーなブート方法(
- OSインストールのフローにおいて、
PXE Bootと構成自動化は排他な概念です。まず前者ができるところまで持っていって初めて後者ができるので、本記事の内容が出来次第、Autoinstall等の構成自動化に持っていった方が、トラブルシューティングがしやすいですね。
vmlinux → vmlinuz
grub.cfgでタイポがあります。
menuentry 'Ubuntu 22.04' {
gfxmode $linux_gfx_mode
linux /vmlinuz ip=dhcp url=http://192.168.62.2/iso/jammy-live-server-amd64.iso --
initrd /initrd
}
つまづきポイント・デバッグ方法
とりあえず見直すなら
- 使用するクライアントPCがどのブート方式に対応しているか(
UEFI bootorBIOS legacy boot) - それぞれのブート方式に適した起動用ファイルを使用しているか
はチェックしておくべきでしょう。
なんかこういう画面が出た
grub2がPXE Bootを行う際に何らかのトラブルが発生し、処理を続行できなくなった場合に grub> というプロンプト画面が表示されるようです。私の実施した環境ではこの現象が発生しました。
解決法:
- クライアントPCとの接続を、10Gbps NICではなく、1Gbps NICを使って行う とこのプロンプト画面が表示されず、ウィザード画面まで進むことができました。
原因:
- おそらく 10Gbps NIC との相性の問題と思います
- Fetching Netboot Imageが表示されている間、本来はIPパケットを送受信して欲しいのに、PXE Serverの方でtcpdumpしてパケットを監視してみると、ARP RequestとARP Replyだけを送り合うだけの時間になっていた
- grubのプロンプトに
cat (tftp,192.168.62.2)/grub/grub.cfgって打つと、しばらく待ったのち、「could not resolve hardware address」的なエラーが返ってきた。これはすなわち、grubがIPアドレスをMACアドレスに変換することに失敗したということを意味しているはず。 - ARP ReplyとPXEに関する記事を探したら、こういうのが出てきた
- UEFI network boot hangs at grub for adapter 82599ES 10-Gigabit SFI/SFP+
- ARPリプライを無視してしまうのは、ネットワークドライバのバグではないか、とかいうやりとりをしていた
- なので、なるべく安定しているであろうドライバを使える環境に移った方が良いと判断し、1G NICに繋ぎ直したら、治った
手順については記載があるサイトが多いのですが、実機によるトラブル報告は少ないので役に立つといいです。
最終的な設定ファイル群
HTTPサーバー
$ tree /var/www/html/
/var/www/html/
├── index.html
└── iso
└── jammy-live-server-amd64.iso
TFTPサーバー
$ tree /srv/tftp/
/srv/tftp/
├── boot-amd64 -> /usr/share/cd-boot-images-amd64
├── bootx64.efi
├── grub
│ └── grub.cfg
├── grubx64.efi
├── initrd
├── unicode.pf2
└── vmlinuz
dnsmasq confファイル
$ cat /etc/dnsmasq.d/pxe.conf
interface=eno1,lo
bind-interfaces
dhcp-range=eno1,192.168.0.100,192.168.0.200
dhcp-boot=pxelinux.0
dhcp-match=set:efi-x86_64,option:client-arch,7
dhcp-boot=tag:efi-x86_64,bootx64.efi
enable-tftp
tftp-root=/srv/tftp
grub.cfg
set default="0"
set timeout=-1
if loadfont unicode ; then
set gfxmode=auto
set locale_dir=$prefix/locale
set lang=en_US
fi
terminal_output gfx_term
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
if background_color 44,0,30; then
clear
fi
function gfxmode {
set gfxpayload="${1}"
if [ "${1}" = "keep" ]; then
set vt_handoff=vt.handoff=7
else
set vt_handoff=
fi
}
set linux_gfx_mode=keep
export linux_gfx_mode
menuentry 'Ubuntu 22.04' {
gfxmode $linux_gfx_mode
linux /vmlinuz ip=dhcp url=http://192.168.0.2/iso/jammy-live-server-amd64.iso --
initrd /initrd
}
参照した記事
- Netbooting the server installer on amd64 - Ubuntu公式フォーラム
- 他のいろんなサイトを探し回った結果、最も参考になりました
- 設定ファイルやフロー、使用するファイル等は基本的にここに書かれているものが最も信頼性が高いです
- Ubuntu AutoinstallでOSインストール自動化 - GMOのブログ記事
- PXE Bootの仕組みがわかりやすく書かれていると思います
- 一部コードブロックでパスの記述に揺れがありますので注意して参照しましょう