#author("2023-07-17T09:43:30+00:00","default:sysosa","sysosa") #author("2023-07-17T11:29:43+00:00;2023-07-17T09:43:30+00:00","default:sysosa","sysosa") PXE: Preboot eXexutionEnvironment 複数台のLinuxマシンを構築することになった 一台一台USB-bootで構築するのもいいが、ネットワーク経由でブートイメージをダウンロードして起動するPXE boot経由で構築させてみた. PXE bootには &color(magenta){dhcpサーバ}; と ブートに必要なbootloaderとブートイメージを提供する &color(orangered){tftp サーバ}; が必要で ここでは &color(magenta){dhcpサーバ}; として[[dnsmasq]]を使います. この dnsmasq には &color(orangered){tftp サーバ}; の機能も備わっているので. ***dnsmasq の導入 [#if159e76] #code(nonumber){{ [root@c ~]# cat /etc/redhat-release CentOS Linux release 8.5.2111 [root@c ~]# dnf install dnsmasq [root@c ~]# systemctl enable dnsmasq --now }} ***bootloaderの設置 [#z61b8d8d] ネットワークブートで起動すると直後にDHCPに問い合わせして自身のIP/GWらが定まる. そしてブート用のファイル(initrd.img, vmlinuz)をダウンロードするのだが、 その前にbootloaderがロードされます. &size(10){プローブみたいなもの}; まずはそのファイルらの準備です. 設置する場所は &color(green){''/var/lib/tftpboot''}; とします ここに bootloader を配置します biosで起動する(MBRを使う)マシンとUEFIで起動するマシンのそれぞれに向けてbootloaderを用意する必要があります. -biosブート向け パッケージ(syslinux)に含まれるファイルを使います. #code(nonumber){{ [root@c ~]# dnf install syslinux [root@c ~]# cp -a /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/ [root@c ~]# cp -a /usr/share/syslinux/ldlinux.c32 /var/lib/tftpboot/ [root@c ~]# cp -a /usr/share/syslinux/libcom32.c32 /var/lib/tftpboot/ [root@c ~]# cp -a /usr/share/syslinux/libutil.c32 /var/lib/tftpboot/ [root@c ~]# cp -a /usr/share/syslinux/vesamenu.c32 /var/lib/tftpboot/ }} -efiブート向け このマシンが既にEFIブートなマシンならその中のファイルを使いまわしてもいい. ここではネットから採取. #code(nonumber){{ [root@c ~]# curl -R https://ftp.riken.jp/Linux/rocky/8.8/BaseOS/x86_64/os/EFI/BOOT/BOOTX64.EFI -o /var/lib/tftpboot/BOOTX64.EFI [root@c ~]# curl -R https://ftp.riken.jp/Linux/rocky/8.8/BaseOS/x86_64/os/EFI/BOOT/grubx64.efi -o /var/lib/tftpboot/grubx64.efi }} ここではCentOS7、RockyLinux8, RockyLinux9らのPXEbootを目指すが、bootloaderは入れるOSを選ばないみたい. むしろ相手側のマシンが読めるかにかかるのかも. ***ブートイメージの準備 [#l9752ff4] 次にOS毎にフォルダを作って、そこにブートイメージを配置させます #code(nonumber){{ [root@c ~]# mkdir /var/lib/tftpboot/{centos7.9,rockylinux8.8,rockylinux9.2} (centos7.9) [root@c ~]# curl -R https://ftp.riken.jp/Linux/centos/7.9.2009/os/x86_64/images/pxeboot/initrd.img -o /var/lib/tftpboot/centos7.9/initrd.img [root@c ~]# curl -R https://ftp.riken.jp/Linux/centos/7.9.2009/os/x86_64/images/pxeboot/vmlinuz -o /var/lib/tftpboot/centos7.9/vmlinuz (rockylinux8.8) [root@c ~]# curl -R https://ftp.riken.jp/Linux/rocky/8.8/BaseOS/x86_64/os/images/pxeboot/initrd.img -o /var/lib/tftpboot/rockylinux8.8/initrd.img [root@c ~]# curl -R https://ftp.riken.jp/Linux/rocky/8.8/BaseOS/x86_64/os/images/pxeboot/vmlinuz -o /var/lib/tftpboot/rockylinux8.8/vmlinuz (rockylinux9.2) [root@c ~]# curl -R https://ftp.riken.jp/Linux/rocky/9.2/BaseOS/x86_64/os/images/pxeboot/initrd.img -o /var/lib/tftpboot/rockylinux9.2/initrd.img [root@c ~]# curl -R https://ftp.riken.jp/Linux/rocky/9.2/BaseOS/x86_64/os/images/pxeboot/vmlinuz -o /var/lib/tftpboot/rockylinux9.2/vmlinuz [root@c tftpboot]# ls -lrt total 3508 -rw-r--r-- 1 root root 42376 Aug 24 2022 pxelinux.0 -rw-r--r-- 1 root root 26788 Aug 24 2022 vesamenu.c32 -rw-r--r-- 1 root root 26272 Aug 24 2022 menu.c32 -rw-r--r-- 1 root root 22804 Aug 24 2022 libutil.c32 -rw-r--r-- 1 root root 180668 Aug 24 2022 libcom32.c32 -rw-r--r-- 1 root root 116128 Aug 24 2022 ldlinux.c32 -rw-r--r-- 1 root root 944024 Apr 29 01:45 BOOTX64.EFI -rw-r--r-- 1 root root 2214728 Apr 29 03:23 grubx64.efi drwxr-xr-x 2 root root 39 Jul 11 22:05 centos7.9 drwxr-xr-x 2 root root 39 Jul 11 22:10 rockylinux8.8 drwxr-xr-x 2 root root 39 Jul 11 22:11 rockylinux9.2 [root@c tftpboot]# }} ***設定ファイルの設置 [#v0c20e28] ネットワークブート後にメニュー画面が表示され、そこからインストールしたいOSを選ぶようにしてみます これもbootloader同様にbiosで起動するマシンとuefiで起動するマシン、それぞれに適用した設定ファイルを用意します -biosブート向け 参照するOSリポジトリはネットワーク先を使ってます. ここをローカルに設置したサイトを指定すると早いかも. #code(nonumber){{ [root@c ~]# mkdir /var/lib/tftpboot/pxelinux.cfg [root@c ~]# vi /var/lib/tftpboot/pxelinux.cfg/default default vesamenu.c32 prompt 0 timeout 600 display boot.msg menu title ########## PXE Boot Menu ########## label 1 menu label ^1) Install CentOS7.9 kernel centos7.9/vmlinuz append initrd=centos7.9/initrd.img ip=dhcp inst.repo=https://ftp.riken.jp/Linux/centos/7.9.2009/os/x86_64/ inst.stage2=https://ftp.riken.jp/Linux/centos/7.9.2009/os/x86_64/ label 2 menu label ^2) Install RockyLinux8.8 menu default kernel rockylinux8.8/vmlinuz append initrd=rockylinux8.8/initrd.img ip=dhcp inst.repo=https://ftp.riken.jp/Linux/rocky/8.8/BaseOS/x86_64/os/ inst.stage2=https://ftp.riken.jp/Linux/rocky/8.8/BaseOS/x86_64/os/ label 3 menu label ^3) Install RockyLinux9.2 kernel rockylinux9.2/vmlinuz append initrd=rockylinux9.2/initrd.img ip=dhcp inst.repo=https://ftp.riken.jp/Linux/rocky/9.2/BaseOS/x86_64/os/ inst.stage2=https://ftp.riken.jp/Linux/rocky/9.2/BaseOS/x86_64/os/ [root@c ~]# }} &color(red){*};この設定ファイル「&color(darkgreen){default};」は、全てのネットブート由来マシンに適用されます. 特定のマシンにのみ適用させるならMACアドレスの先頭に01を付けたファイルを(&color(darkmagenta){''01''-00-0c-29-09-73-55};)を用意するか、IPアドレスを16進数に変換したファイルを用意する(「192.168.0.101」なら「C0A80065」(大文字へ)) -efiブート向け 設定ファイルは「&color(darkmagenta){grub.cfg};」になります #code(nonumber){{ [root@c ~]# vi /var/lib/tftpboot/grub.cfg set timeout=60 default=0 menuentry '1) Install CentOS7.9' { echo 'Network status:' net_ls_cards net_ls_addr linuxefi /centos7.9/vmlinuz ip=dhcp inst.repo=https://ftp.riken.jp/Linux/centos/7.9.2009/os/x86_64/ initrdefi /centos7.9/initrd.img } menuentry '2) Install RockyLinux8.8' { echo 'Network status:' net_ls_cards net_ls_addr linuxefi /rockylinux8.8/vmlinuz ip=dhcp inst.repo=https://ftp.riken.jp/Linux/rocky/8.8/BaseOS/x86_64/os/ initrdefi /rockylinux8.8/initrd.img } menuentry '3) Install RockyLinux9.2' { echo 'Network status:' net_ls_cards net_ls_addr linuxefi /rockylinux9.2/vmlinuz ip=dhcp inst.repo=https://ftp.riken.jp/Linux/rocky/9.2/BaseOS/x86_64/os/ initrdefi /rockylinux9.2/initrd.img } [root@c ~]# }} &size(10){「default=0」は何も操作しなければ、このエントリーの初めのがロードされることを意味します}; &color(red){*};こちらも「&color(darkmagenta){grub.cfg};」は全てのefiブートで適用される設定ファイルになります. 特定のマシンに適用したければ先頭を「01」としてMACアドレスを付与したファイルを用意します. 「grub.cfg-&color(darkgreen){''01''-00-0c-29-09-73-55};」. DHCPで付与されたIPアドレスで定義したいのなら「grub.cfg-C0A80065」(大文字)とかにします. &size(10){この辺は「&color(darkgreen){default};」と同じかな}; ***dnsmasqの設定 [#k9c6a4fe] 「/etc/dnsmasq.conf」には下記を追記します. conf-dir経由で「/etc/dnsmasq.d/」が利用可能なら「/etc/dnsmasq.d/pxeboot.conf」として用意してもいいかも. #code(nonumber){{ [root@c ~]# vi /etc/dnsmasq.conf : : enable-tftp tftp-root=/var/lib/tftpboot dhcp-match=set:bios, option:client-arch, 0 #x86-32 dhcp-boot=tag:bios,/pxelinux.0,192.168.0.3 dhcp-match=set:efi-x86_64, option:client-arch, 7 #EFI x86-64 dhcp-boot=tag:efi-x86_64,/grubx64.efi,192.168.0.3 [root@c ~]# }} biosブートなマシンには「/var/lin/tftboot」を起点としての「/pxelinux.0」を渡して efiブートなマシンには同じく「/var/lin/tftboot」を起点とした「/grubx64.efi」を渡すようにしてます. ***OSイメージの設置(オプション) [#e74cd111] 前段でOSリポジトリ先を「https://ftp.riken.jp/Linux/rocky/9.2/BaseOS/x86_64/os/」と外部を参照してますが、 このリポジトリをローカルに設置してより迅速な作業が可能になります ここでは「/opt/os/」に各OSのisoを展開させてみます そしてこの「/opt/os」をhttpで公開させます. #code(nonumber){{ [root@c ~]# mount -o loop,ro -t iso9660 ~/Rocky-9.2-x86_64-dvd.iso /mnt [root@c ~]# mkdir -p /opt/os/r9.2 [root@c ~]# rsync -a /mnt/ /opt/os/r9.2/ [root@c ~]# umount /mnt [root@c ~]# ls -CF /opt/os/r9.2 AppStream/ BaseOS/ COMMUNITY-CHARTER Contributors EFI/ EULA images/ isolinux/ LICENSE media.repo RPM-GPG-KEY-Rocky-9 RPM-GPG-KEY-Rocky-9-Testing [root@c ~]# cd /var/www/html/ [root@c html]# ln -s [root@c html]# ln -s /opt/os . [root@c html]# systemctl restart httpd }} ブラウザで公開したリポジトリにアクセスしてみて確認します ***firewall [#d5515b26] 「dhcp」「dns」「tftp」のサービスを受け入れられるようにします #code(nonumber){{ [root@c ~]# firewall-cmd --add-service=dhcp --add-service=dns --add-service=tftp --add-service=http --zone=public --permanent [root@c ~]# firewall-cmd --list-all }} ***起動 [#u2662b77] 実際にマシンを起動してみます 左がbiosで起動. 右がefiで起動. &ref(2023y07m12d_101545833.jpg,nolink); &ref(2023y07m12d_101451743.jpg,nolink); OSとして何を入れるかを矢印キーで選択して押下するとOSインストール画面になります こんな画面です. &ref(2023y07m12d_103058692.jpg,nolink,80%); ***自動OSインストール [#l52875f2] ここまではdhsmasqを利用して起動させたのみ. いわばOSインストーラーが入ったUSBを差し込んで起動しただけと同じ. OSのインストールは起こりません. ここまではdnsmasqを利用して起動させたのみ. いわばOSインストーラーが入ったUSBを差し込んで起動しただけと同じ. OSのインストールは起こりません. っでそれをさせるのが [[kickstart]] です. ***インストール先が複数のnicを持ってたら [#i46ef45d] 上記は全てnicが一枚ならのお話。複数だと上手く動かないみたい。 回避方法だが、定義ファイル([pxelinux.cfg/default],[grub.cfg])に 「ip=eth0:dhcp」 もしくは 「net.ifnames=0 ip=eth0:dhcp」 を加える。 &color(red){*};「net.ifnames」はCentOS7でnic名をCentOS6同様のeth0とかにしてくれる そして、どのnicを使うかを定義します。 「rd.neednet=1 bootdev=eth0」 ***ubuntu向け [#j83d862f] どうせならとubuntuもテストしてみた. ubuntu-22.04.2-live-server-amd64 です. desktop向けではないです. ubuntuの自動インストールは [[autoinstall]]を使うがその前まではPXEbootが使える. なので #code(nonumber){{ [root@c ~]# mkdir /var/lib/tftpboot/ubuntu-22.04.2-live-server-amd64 [root@c ~]# mount -o loop,ro -t iso9660 /export/ubuntu-22.04.2-live-server-amd64.iso /mnt [root@c ~]# cp -a /mnt/casper/vmlinuz /var/lib/tftpboot/ubuntu-22.04.2-live-server-amd64 [root@c ~]# cp -a /mnt/casper/initrd /var/lib/tftpboot/ubuntu-22.04.2-live-server-amd64 [root@c ~]# umount /mnt [root@c ~]# ln -s /export/ubuntu-22.04.2-live-server-amd64.iso /opt/os/ [root@c ~]# ls -lh /var/lib/tftpboot/ubuntu-22.04.2-live-server-amd64 total 116M -r--r--r-- 1 root root 105M Feb 18 02:32 initrd -r--r--r-- 1 root root 12M Feb 18 02:32 vmlinuz [root@c ~]# }} そして /var/lib/tftpboot/grub.cfg に下記を追記します #code(nonumber){{ menuentry '4) Install ubuntu-22.04.2-live-server-amd64' { set gfxpayload=keep linuxefi /ubuntu-22.04.2-live-server-amd64/vmlinuz ip=dhcp url=http://192.168.0.3/os/ubuntu-22.04.2-live-server-amd64.iso initrdefi /ubuntu-22.04.2-live-server-amd64/initrd } }} っでマシンを起動すると &ref(2023y07m17d_005103665.png,nolink); な感じで選択肢が得られる. っでOSインストール画面までは来る. &ref(2023y07m17d_015406210.png,nolink); これ以降は手動で、あるいは[[autoinstall]]を使って自動インストールに仕立てる. desktop版を試すと #code(nonumber){{ [root@c ~]# ln -s /export/ubuntu-22.04.2-desktop-amd64.iso /opt/os/ [root@c ~]# mount -o loop,ro -t iso9660 /export/ubuntu-22.04.2-desktop-amd64.iso /mnt [root@c ~]# mkdir /var/lib/tftpboot/ubuntu-22.04.2-desktop-amd64 [root@c ~]# cp -a /mnt/casper/vmlinuz /var/lib/tftpboot/ubuntu-22.04.2-desktop-amd64/ [root@c ~]# cp -a /mnt/casper/initrd /var/lib/tftpboot/ubuntu-22.04.2-desktop-amd64/ [root@c ~]# umount /mnt }} として/var/lib/tftpboot/grub.cfg に下記を追記して起動すると #code(nonumber){{ menuentry '5) Install ubuntu-22.04.2-desktop-amd64' { set gfxpayload=keep linuxefi /ubuntu-22.04.2-desktop-amd64/vmlinuz ip=dhcp url=http://192.168.0.3/os/ubuntu-22.04.2-desktop-amd64.iso initrdefi /ubuntu-22.04.2-desktop-amd64/initrd } }} desktop版のトライアルが起動します &ref(2023y07m17d_020731053.png,nolink);