Kickstartシリーズ
Kickstartとは、Linuxのインストールを自動化する機能です。
本シリーズではRHEL, Fedora, CentOS Streamをモデルに紹介します。
一連の記事でKickstartの構成を3パターン紹介します。
今回の記事では、3つ目の構成を紹介します。
- KickstartによるLinuxインストール自動化 (手動トリガー・HTTP連携)
- KickstartによるLinuxインストール自動化 (自動トリガー・ローカルディスク接続)
- KickstartによるLinuxインストール自動化 (自動トリガー・PXEブート連携) ← 今ココ
今回の記事については私が構成の内容を理解しきれておりません。
したがって、RHEL8のマニュアル通りの操作を抜粋して紹介するにとどめます。
詳しい原理や、使い勝手やセキュリティを踏まえた設計の吟味などはできませんが、ご了承ください。
今回の構成では、PXE BootやKickstartに必要なファイルをアップロードするサーバ (※) は、他にDHCPが動作していないネットワーク上で起動する必要があります。
(※) 本記事ではPXEサーバと呼びます
"他にDHCPが動作していないネットワーク" というのは、実はかなり大きな制約です。
VirtualBoxのようなローカル検証環境においてはDHCPを活用しているケースが多いと思うので、個人的にはローカル検証環境とPXE Bootはあまり相性が良くないと思います。
一方でPXE Boot用のネットワークが設計上分離されており、PXEサーバが常時起動しているようなインフラが整備されていればうまく活用できると思います。
- Kickstartシリーズ
- 構成概要
- 環境構築
- Kickstartの実行
- まとめ
- 関連記事
構成概要
PXE (Preboot eXecution Environment) とは、ネットワークブートの一方式です。
ピクシー (/ˈpɪksiː/
) と読まれることが多いようです1。
ネットワーク越しにブートローダーやOSイメージ等の情報を取得して起動を開始します。
ブートローダーのパラメータにLinuxインストーラやKickstartファイルのURLを指定することで、インストール作業の完全自動化まで可能となります。
環境構築は以下の手順で行います。
詳細は#環境構築にて説明します。
- DHCPサーバをインストールする
- DHCPサーバにTFTPサーバのIPアドレスなどを設定する
- TFTPサーバをインストールする
- ブートローダーの設定ファイルやバイナリファイルをTFTPサーバにアップロードする
- HTTP、FTP、またはNFSサーバを構築し、以下ファイルをアップロードする
Kickstartは以下の手順で開始します。
この構成では、イメージファイルの準備も不要です。
詳細は#Kickstartの実行にて説明します。
- インストール対象のマシンに空のディスクをセットする
- ネットワーク起動の優先順位を高くする
- マシンを起動する
環境構築
今回は、DHCPサーバ、TFTPサーバ、HTTPサーバを同じマシンに全て同居させた "PXEサーバ" を構築します。
今回の構成では、サーバは192.168.101.2/24
というIPアドレスを持ちます。
デフォルトゲートウェイは、192.168.101.1
であるとします。
手順はRHEL8 - Performing an advanced RHEL installationをベースとしています。
以降、各セクションに参照したセクションへのURLを記載します。
本記事の手順はCentOS Stream 9 (RHEL9相当) で動作を確認しました。
冒頭に記載しましたとおり、本記事では各設定内容の詳細までは吟味しません。
ただ、気になるポイントがあればSYSLINUX Wiki - PXELINUXが参考になると思います。
DHCPが動作していない仮想ネットワークを作成する
PXEサーバが動作するネットワークでは、他のDHCP機能が動作しないようにしてください。
VirtualBoxやlibvirtなどの仮想ネットワークを使っている場合は、組み込みのDHCP機能がデフォルトで有効になっているので注意してください。
(参考) DHCPサーバが動作しない仮想ネットワークを作る理由
同じネットワーク内にDHCPサーバを複数台構築すると、DHCPサーバの動作が競合してしまいます。
同じネットワークにDHCPサーバが複数台存在すると、以下のような動きになってしまいます。
(※) DHCPサーバに冗長化機能があり、Active-Standby構成で動作しているようなケースは例外です
- クライアントがブロードキャストでDHCPDISCOVERを出す
- 複数台のDHCPサーバがDHCPDISCOVERを受け取り、DHCPOFFERを返す
- クライアントは複数のDHCPサーバからDHCPOFFERを受け取るが、最初に届いたDHCPOFFERで後続の処理を進める
つまり、DHCPOFFERを先に届けたもの勝ちという動きになり、意図しないDHCPサーバがクライアントにIPアドレスを渡してしまいます。
今回の構成では、確実にPXEサーバが起動しているDHCPサーバからIPアドレスを受け取る必要があります。
PXEサーバ上で動作するDHCPサーバは、後続処理のためにTFTPサーバのIPやファイルパスを伝える特殊な役割を持つためです。
したがって、VirtualBoxやKVM (libvirt) が起動している仮想ネットワークのDHCP機能と、PXEサーバのDHCP機能が競合しないように構成を組む必要があります。
(参考) KVMの場合の手順
KVM環境において、DHCP機能を無効化したネットワークを作る手順を紹介します。
操作方法はKVMの基本操作集 - #仮想ネットワークの作成が参考になります。
Cockpitの場合は以下のようなパラメータを指定します。
仮想ネットワーク作成後、ネットワーク起動し、自動起動も有効化しておきましょう。
コマンドで実行する場合は、やや煩雑な手順になります。
今回は少々手抜きですが、上記Cockpitで作成したXML形式の定義情報を貼っておきます。
ただし、MACアドレス、UUID情報、ブリッジ名は自動生成に任せたいので削除しておきました。
<network> <name>nodhcp</name> <forward mode='nat'> <nat> <port start='1024' end='65535'/> </nat> </forward> <domain name='nodhcp' localOnly='yes'/> <dns> <host ip='192.168.101.1'> <hostname>gateway</hostname> </host> </dns> <ip address='192.168.101.1' netmask='255.255.255.0' localPtr='yes'> </ip> </network>
以下のコマンドにより、作成したtmp.xml
を読み込んで新しい仮想ネットワークを作成します。
virsh net-define tmp.xml
ネットワークを起動し、自動起動を有効化します。
virsh net-start nodhcp virsh net-autostart nodhcp
VMのネットワーク設定
KVMの構成におけるネットワーク設定を参考までに残しておきます。
以下の構成です。
sudo nmcli connection add ifname enp1s0 con-name enp1s0 type ethernet ipv4.method manual ipv4.addresses 192.168.101.2/24 ipv4.gateway 192.168.101.1 ipv4.dns 192.168.101.1 autoconnect yes sudo nmcli connection up enp1s0
Linuxイメージファイルのマウント
今回のPXEサーバの構築にはLinuxインストール用のイメージファイルを使用します。
Linuxインストール用のISOファイルを接続した上でサーバを起動します。
Cockpitから仮想マシンに対してISOファイルを追加する際、BusをSCSIではなくSATAを指定しないとLinux上で/dev/cdrom
が生成しませんでした。
サーバ起動後、以下のコマンドでISOファイルをマウントします2。
sudo mkdir /media/cdrom sudo mount -t iso9660 -o ro,loop /dev/cdrom /media/cdrom
DHCPサーバの構築
参考元: 14. Preparing to install from the network using PXE
(14.2と14.3にそれぞれBIOSとUEFI向けの設定方法が説明されていますが、DHCPの設定に関してはどちらも共通です)
DHCPサーバのインストール
以下のコマンドでDHCPサーバをインストールします。
sudo dnf install dhcp-server
DHCPサーバの設定
続いてDHCPサーバの設定を書き換えます。
sudo vi /etc/dhcp/dhcpd.conf
dhcpd.conf
の中身を以下のように編集します。
IPアドレスの値は環境によって調整してください。
option space pxelinux; option pxelinux.magic code 208 = string; option pxelinux.configfile code 209 = text; option pxelinux.pathprefix code 210 = text; option pxelinux.reboottime code 211 = unsigned integer 32; option architecture-type code 93 = unsigned integer 16; subnet 192.168.101.0 netmask 255.255.255.0 { option routers 192.168.101.1; range 192.168.101.101 192.168.101.254; class "pxeclients" { match if substring (option vendor-class-identifier, 0, 9) = "PXEClient"; next-server 192.168.101.2; if option architecture-type = 00:07 { filename "BOOTX64.efi"; } else { filename "pxelinux/pxelinux.0"; } } }
中身について補足します。
option
宣言によってDHCPヘッダでやり取りする追加情報を指定するcode 208
などの数値は、RFC5071やRFC4578などの規程に基づく- 参考: syslinux.org - PXELINUX
subnet
,option
,range
は、実際のネットワーク構成に合わせて値を変更するsubnet
: DHCPで管理するネットワークアドレスoption routers
: デフォルトゲートウェイのIPアドレスrange
: DHCPで配布するIPアドレスの範囲 (最小値と最大値を指定)- 参考: man dhcp-options
next-server
にはブートローダーの読み込み先のIPアドレスを指定するfilename
によって、次に読み込むTFTPサーバ (next-server
) 上のブートローダーのファイルパスを指定している
DHCPサーバの起動
DHCPサーバを起動します。
# sudo systemctl enable dhcpd.service; sudo systemctl start dhcpd.service と同じ sudo systemctl enable dhcpd.service --now
TFTPサーバの構築
参考元: 14. Preparing to install from the network using PXE
TFTPサーバのインストール
以下のコマンドでTFTPサーバをインストールします。
sudo dnf install tftp-server
firewalldによるTFTP通信許可
firewalldが有効な場合は、以下のコマンドでTFTP通信を許可しておきます。
重要なコマンドは「変更」と「設定反映」です。
# 事前確認。serviceにtftpがないこと sudo firewall-cmd --list-all # 変更 sudo firewall-cmd --add-service tftp --permanent # 差分比較 diff -u <(sudo firewall-cmd --list-all) <(sudo firewall-cmd --list-all --permanent) # -public (active) # +public # target: default # icmp-block-inversion: no # - interfaces: enp1s0 # + interfaces: # sources: # - services: cockpit dhcpv6-client ssh # + services: cockpit dhcpv6-client ssh tftp # ports: # protocols: # forward: yes # 設定反映 sudo firewall-cmd --reload # 事後確認。serviceにtftpがあること sudo firewall-cmd --list-all
BIOS利用クライアント向けのブートローダー格納
参考元: 14.2. Configuring a TFTP server for BIOS-based clients
PXEBOOT用のブートローダーや設定ファイルをTFTPサーバに格納します。
本セクションで紹介するのは、BIOSベースのクライアント向けの手順です。
UEFIベースのクライアント向けの手順は、#UEFI利用クライアント向けのブートローダー格納にて別途紹介します。
理由がなければ、両方のセクションを対応しましょう。
作業ディレクトリに移動し、ブートローダーRPMをISOイメージファイルから取り出します。
RPMファイルを展開し、中にあるブートローダーファイル群を/var/lib/tftpboot/pxelinux/
ディレクトリに格納します。
mkdir ~/tmp/ cd ~/tmp/ # RHEL8の公式手順ではISOファイルから取り出している # RHEL8の場合: cp -p /media/cdrom/BaseOS/Packages/syslinux-tftpboot*.rpm . # CentOS Stream9場合: cp -p /media/cdrom/AppStream/Packages/syslinux-tftpboot-*.rpm . dnf download syslinux-tftpboot rpm2cpio syslinux-tftpboot*.rpm | cpio -dimv sudo mkdir /var/lib/tftpboot/pxelinux sudo cp -p tftpboot/* /var/lib/tftpboot/pxelinux/
作業用ディレクトリは不要になったので、このタイミングで消しておきます。
cd rm -rf ~/tmp/
PXELINUXの設定ファイルを格納するディレクトリを作成します。
sudo mkdir /var/lib/tftpboot/pxelinux/pxelinux.cfg
PXELINUXの設定ファイルを作成します。
sudo vi /var/lib/tftpboot/pxelinux/pxelinux.cfg/default
default
ファイルには以下の内容を記述します。
IPアドレスや文言は環境に合わせてアレンジしてください。
default vesamenu.c32 timeout 50 display boot.msg label linux_cs9 menu label ^Install system menu default kernel images/centos_stream9/vmlinuz append initrd=images/centos_stream9/initrd.img ip=dhcp inst.repo=http://192.168.101.2/repositories/centos_stream9 inst.ks=http://192.168.101.2/kickstarts/centos_stream9 label vesa_cs9 menu label Install system with ^basic video driver kernel images/centos_stream9/vmlinuz append initrd=images/centos_stream9/initrd.img ip=dhcp inst.xdriver=vesa nomodeset inst.repo=http://192.168.101.2/repositories/centos_stream9 inst.ks=http://192.168.101.2/kickstarts/centos_stream9 label rescue_cs9 menu label ^Rescue installed system kernel images/centos_stream9/vmlinuz append initrd=images/centos_stream9/initrd.img rescue label local menu label Boot from ^local drive localboot 0xffff
BIOS画面からPXE Bootを試みるとき、このdefault
ファイルを参照してBoot Entryを選択します。
ファイル名は他にもUUIDやMACアドレス、IPアドレスを元にした文字列も指定可能です。
上記のファイル名の条件に一致するようなクライアントから接続があった場合、default
ファイルよりも優先してそれらのファイルが読み込まれます。
詳細はSYSLINUX Wiki - PXELINUX - #Configuration filenameを参照してください。
設定ファイルの文法については、SYSLINUX Wiki - Configを参照してください。
今回はシンプルにdefault
ファイルのみ作成しました。
MACアドレスやIPアドレスごとのファイルを作成するかは設計思想に依存すると思いますが、手間がかかるので基本default
のみで良いのではないかと思います。
default
ファイルは、RHEL8のマニュアルから以下の部分をアレンジしました。
変更前 | 変更後 | 詳細 |
---|---|---|
prompt 1 |
行削除 |
|
timeout 600 |
timeout 50 |
|
label linux |
label linux_cs9 |
|
label vesa |
label vesa_cs9 |
同上 |
label rescue |
label rescue_cs9 |
同上 |
vesa_cs9
, rescue_cs9
, local_cs9
については、不要であれば#
でコメントアウトしても問題ないと思います。
上表以外にも、各label
の配下に指定しているkernel
、initrd
、inst.repo
のIPアドレスとファイルパスを適切な値に変更しました。
kernel
とinitrd
については、/var/lib/tftpboot/
をrootとしたときの相対パスを指定します。
後続の#kernel, initrdファイルの格納において、ここで指定したパスにkernel
とinitrd
を格納する必要があります。
inst.repo
は、RPMパッケージリポジトリのURLです。
IPアドレスはHTTPサーバのものを指定します。
今回はDHCP/TFTP/HTTPサーバがすべて同じマシンに同居する構成のため、共通のIPアドレスである192.168.101.2
を指定します。
後続の#RPMパッケージリポジトリの格納において、RPMパッケージリポジトリをここで指定したファイルパスに格納する必要があります。
inst.repo
と同等のオプションはKickstartファイルのuri
オプションでも指定しますが、これらはどちらも指定する必要があります。
inst.repo
と同じ行にinst.ks
を追記し、KickstartファイルのURLを指定しました。
後続の#Kickstartファイルの格納において、Kickstartファイルをここで指定したファイルパスに格納する必要があります。
UEFI利用クライアント向けのブートローダー格納
参考元: 14.3. Configuring a TFTP server for UEFI-based clients
前セクションではBIOSベースのクライアント用のブートローダーをTFTPサーバに格納しました。
本セクションでは、UEFIベースのクライアント用のブートローダーを格納します。
異なるバイナリファイルや設定ファイルを用意する必要がありますが、設定のポイントは基本的にBIOS向けの対応手順と変わりません。
まず、作業用ディレクトリを作成して移動します。
mkdir ~/tmp cd ~/tmp
shim、grub2-efi RPMパッケージをISOファイルから取り出します。
これらのRPMはオンラインリポジトリには存在しなかったので、ISOファイルから取り出す必要がありました。
cp -p /media/cdrom/BaseOS/Packages/shim-x64-[0-9]*.rpm . cp -p /media/cdrom/BaseOS/Packages/grub2-efi-x64-[0-9]*.rpm .
RPMファイルを展開して中身のファイルを取り出します。
rpm2cpio shim-x64-[0-9]*.rpm | cpio -dimv rpm2cpio grub2-efi-x64-[0-9]*.rpm | cpio -dimv
EFIブートイメージファイルを取り出し、TFTPからアクセス可能な領域に格納します。
mkdir /var/lib/tftpboot/uefi # RHELの場合は... # sudo cp -p boot/efi/EFI/redhat/grubx64.efi # sudo cp -p boot/efi/EFI/redhat/shimx64.efi sudo cp -p boot/efi/EFI/centos/grubx64.efi sudo cp -p boot/efi/EFI/centos/shimx64.efi
EFI用のBoot Entryを追記します。
sudo vi /var/lib/tftpboot/grub.cfg
以下のように記載します。
set timeout=5 menuentry 'CentOS Stream 9' { linuxefi images/centos_stream9/vmlinuz ip=dhcp inst.repo=http://192.168.101.2/repositories/centos_stream9/ inst.ks=http://192.168.101.2/kickstarts/centos_stream9 initrdefi images/centos_stream9/initrd.img }
grub.cfg
の環境変数やコマンドについては、GNU GRUB Manual - #16 The list of available commandsを参照してください。
grub.cfg
ファイルは、RHEL8のマニュアルから以下の部分をアレンジしました。
変更前 | 変更後 | 詳細 |
---|---|---|
set timeout=60 |
set timeout=5 |
|
menuentry 'RHEL 8' |
menuentry 'CentOS Stream 9' |
|
上表の他にも各種ファイルのパスやURLを環境に合わせて変更しました。
vmlinuz
とinitrd.img
については、/var/lib/tftpboot/
をrootとしたときの相対パスを指定します。
後続の#kernel, initrdファイルの格納において、ここで指定したパスにkernel
とinitrd
を格納する必要があります。
inst.repo
は、RPMパッケージリポジトリのURLです。
IPアドレスはHTTPサーバのものを指定します。
今回はDHCP/TFTP/HTTPサーバがすべて同じマシンに同居する構成のため、共通のIPアドレスである192.168.101.2
を指定します。
後続の#RPMパッケージリポジトリの格納において、RPMパッケージリポジトリをここで指定したファイルパスに格納する必要があります。
inst.repo
と同等のオプションはKickstartファイルのuri
オプションでも指定しますが、これらはどちらも指定する必要があります。
inst.repo
と同じ行にinst.ks
を追記し、KickstartファイルのURLを指定しました。
後続の#Kickstartファイルの格納において、Kickstartファイルをここで指定したファイルパスに格納する必要があります。
kernel, initrdファイルの格納
PXE Bootで起動する際に必要なkernelイメージファイル、及びInit RAM DiskをISOファイルからコピーして格納します。
以下のコマンドを実行します。
mkdir -p /var/lib/tftpboot/pxelinux/images/centos_stream9 sudo cp -p /media/cdrom/images/pxeboot/{vmlinuz,initrd.img} /var/lib/tftpboot/pxelinux/images/centos_stream9/
TFTPサーバの起動
# sudo systemctl enable tftp.socket; sudo systemctl start tftp.socket と同じ sudo systemctl enable tftp.socket --now
HTTPサーバの構築
HTTPサーバにはKickstartファイルと、RPMパッケージリポジトリをアップロードします。
HTTPサーバのインストール
以下のコマンドでApache httpdをインストールします。
sudo dnf install httpd
firewalldによるHTTP通信許可
firewalldが有効な場合は、以下のコマンドでHTTP通信を許可しておきます。
重要なコマンドは「変更」と「設定反映」です。
# 事前確認。serviceにhttpがないこと sudo firewall-cmd --list-all # 変更 sudo firewall-cmd --add-service http --permanent # 差分比較 diff -u <(sudo firewall-cmd --list-all) <(sudo firewall-cmd --list-all --permanent) # -public (active) # +public # target: default # icmp-block-inversion: no # - interfaces: enp1s0 # + interfaces: # sources: # - services: cockpit dhcpv6-client ssh tftp # + services: cockpit dhcpv6-client http ssh tftp # ports: # protocols: # forward: yes # 設定反映 sudo firewall-cmd --reload # 事後確認。serviceにhttpがあること sudo firewall-cmd --list-all
Kickstartファイルの格納
参考元: 5.3. Making a Kickstart file available on an HTTP or HTTPS server
KickstartファイルをHTTPサーバにアップロードします。
使用するファイルは、KickstartによるLinuxインストール自動化 (手動トリガー・HTTP連携) - #書き換え後のKickstartファイルとほぼ同じです。
ただし、cdrom
とrepo
の行のみ以下のように書き換えます。
RPMパッケージリポジトリをCDROMではなく、HTTPサーバ上のリポジトリに変更します。
# cdrom url --url=http://192.168.101.2/repositories/centos_stream9 # repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream repo --name="AppStream" --baseurl=http://192.168.101.2/repositories/centos_stream9/AppStream
cdromはRPMパッケージリポジトリとしてISOイメージファイルを指定するコマンドです。
今回はRPMパッケージリポジトリとしてHTTPサーバを指定するので、これをurlコマンドに置き換えます。
repoは、baseなどデフォルトのRPMリポジトリに追加のリポジトリを指定するオプションです。
RHEL8以降は、インストール時にAppStreamというリポジトリを追加で指定する必要があります3。
用意したKickstartファイルをHTTPサーバにアップロードします。
sudo mkdir /var/www/html/kickstarts
sudo vi /var/www/html/kickstarts/centos_stream9
今回使用するKickstartファイルは以下のとおりです。
# Generated by Anaconda 34.25.0.25 # Generated by pykickstart v3.32 #version=RHEL9 # Use graphical install graphical repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream %addon com_redhat_kdump --enable --reserve-mb='auto' %end # Keyboard layouts keyboard --vckeymap=jp --xlayouts='jp' # System language lang en_US.UTF-8 # Network information network --bootproto=dhcp --device=enp1s0 --ipv6=auto --activate network --hostname=cs url --url=http://192.168.101.2/repositories/centos_stream9 %packages @^minimal-environment %end # Run the Setup Agent on first boot firstboot --enable # Generated using Blivet version 3.4.0 ignoredisk --only-use=vda # Partition clearing information clearpart --none --initlabel # Disk partitioning information part pv.111 --fstype="lvmpv" --ondisk=vda --grow part /boot --fstype="ext4" --ondisk=vda --size=1024 volgroup cs --pesize=4096 pv.111 logvol / --fstype="ext4" --percent=100 --name=root --vgname=cs logvol swap --fstype="swap" --size=1024 --name=swap --vgname=cs # System timezone timezone Asia/Tokyo --utc # Root password rootpw --iscrypted $6$GMEsgHeNZwjJWb.d$BuP/sn9FX6xKEFGYo8KzNmLB5jPl7RhFQyHnklgrK2CkQntcsT2aOCz4Ozzcefc5J7gXO7IXVvj7KdQOddpv81 user --groups=wheel --name=endy --password=$6$qtY89ARpZJNqk8ap$1u6e3CplnSGpqBppAyd/.f9fheOt74TA.fqMdPsROa3kmSSlHuOyXurBWSr5EHksAemR.3HjDjkI1n6JIeJIk1 --iscrypted --gecos="endy"
過去記事と同様に、お好みでシンボリックリンクを作っておくとCentOS Streamのバージョン差異を抽象化できて便利になります。
よろしければ、以下のコマンドでcentos_stream
というファイル名のシンボリックリンクを作成しておきましょう。
ln -s centos_stream9 centos_stream
RPMパッケージリポジトリの格納
参考元: 6.4. Creating an installation source using HTTP or HTTPS
ISOファイルからRPMパッケージリポジトリ情報をコピーします。
この部分の手順は、いわゆるリポジトリサーバの構築手順に近い内容かなと思います。
今回はLinuxの初期インストール用のパッケージを調達したいので、オンラインリポジトリではなくISOファイルからリポジトリデータをコピーします。
以下のコマンドでコピーします。
コピー元ディレクトリにある.treeinfo
という隠しファイルが重要です。
*
のようなワイルドカードを使うと隠しファイルのコピーが漏れてしまうので、以下の例のようにフォルダごとコピーしましょう。
sudo mkdir /var/www/html/repositories/ sudo cp -pr /media/cdrom/ /var/www/html/repositories/ sudo mv /var/www/html/repositories/cdrom /var/www/html/repositories/centos_stream9
HTTPサーバの起動
以下のコマンドでHTTPサーバを起動します。
# sudo systemctl enable httpd.service; sudo systemctl start httpd.service と同じ sudo systemctl enable httpd.service --now
Kickstartの実行
ここまでの操作により、Kickstartに必要なPXEサーバの構築は完了しました。
では、いよいよ空のVMをPXE Bootし、KickstartによってLinuxを自動インストールします。
(参考) 仮想マシンの作成
KVM配下に仮想マシンを作成する場合を例に、パラメータの例を示します。
詳細はKVMの基本操作集 - #VMの作成をご覧ください。
CockpitからVMを作成する際は、下図のようにパラメータを指定します。
今回はPXE Bootをするため、通常のCDROMからの起動ではなく、ネットワークからの起動を選択します。
また、PXEサーバと同じネットワークに接続するようにします。
今回の場合は、#DHCPが動作していない仮想ネットワークを作成するで作成したnodhcp
というネットワークに接続します。
virt-install
コマンドで仮想マシンを作成する場合は、例えば以下のようなコマンドを実行します。
Network bootを優先するため、普段指定している--cdrom
の代わりに--pxe
を指定します。
また、今回は仮想ネットワークにdefault
以外のものを指定するので、明示的に--network network=nodhcp
によって指定します。
コンソール画面の自動起動を無効化したい場合は、--no-autoconsole
オプションも付けましょう。
--no-autoconsole
を指定する場合は、末尾の&
は削除します。
virt-install \ --name test \ --memory 2048 \ --vcpus 2 \ --disk size=10 \ --graphics vnc \ --graphics spice \ --os-variant centos-stream9 \ --network network=nodhcp \ --pxe &
インストール手順を何度か試したいとも思いますので、作成したVMを停止して削除するコマンドも添えておきます。
--os-variant
の指定を省いた場合は、--storage vda
の部分が--storage hda
になることもあります。
詳細はKVMの基本操作集 - #VMの削除を参照してください。
virsh destroy test ; virsh undefine test --storage vda --snapshots-metadata --managed-save
Kickstartによる自動インストール
VMを起動すると、以下の処理が自動的に走ります。
- DHCP (
/etc/dhcp/dhcpd.conf
) - TFTP
正しく動作すれば、以下のブートローダーの画面が表示されます。
無操作のまま5秒待つか、一番上のInstall system
を選択するとこの先のインストールに進みます。
正しく処理が進めば、このままインストールが完了します。
(参考) トラブルのパターン
全てではありませんが、過去に踏んだことのあるトラブルを紹介します。
inst.repoの指定ミス
参考: 23.1. Configuring the Installation System at the Boot Menu - #Specifying the Installation Source
inst.repo
に指定したパス配下の.treeinfo
にHTTPアクセスできなかった場合、ブートローダーのグレーの画面を通過後、以下のようなエラー画面に遷移します。
↓.treeinfo
の読み取りに失敗し、inst.repo
やinst.ks
のパスに/images/install.img
を付与したパスから読み取る処理にフォールバックします。そのパスにもファイルが存在しないため、HTTP通信で404エラー応答が返り、処理に失敗します。
↓しばらく待つと、以下のようなエラーメッセージがしばらくループし続けた後、完全に処理を停止します。
このエラーが出た場合、inst.repo
に指定したパスを中心に、HTTP通信がエラーになった原因を探って修正する必要があります。
確認するファイルは以下の2つです。
/var/lib/tftpboot/pxelinux/pxelinux.cfg/default
/var/lib/tftpboot/grub.cfg
(参考) Kickstartでエラーが発生したときの対処法
1つ目の記事で紹介した(参考) Kickstartでエラーが発生したときの対処法を参照してください。
まとめ
PXE bootとKickstartを組み合わせて、ネットワーク越しに各種リソースにアクセスしてLinuxインストールを完全自動化する構成を紹介しました。
構成がなかなか複雑ですが、ネットワークに繋いでマシンの電源を入れるだけでLinuxのインストールが完了するというのは面白いと思います。
しかし、ローカル検証環境において活用するにはDHCPサーバの競合を回避する必要があります。
本番用途で活用するには、構築したサーバに何らかの方法で固定IPアドレスを割り振る工程も自動化するところで頭を使うと思います。
実際のユースケースと結びつけて正しく設計しようと考えると、今回紹介した構成は難易度が高いと思います。
他のKickstart構成やVMクローン、AnsibleなどのDevOpsツールなどの代替手段があるだけに、PXE bootの構成は中々採用されないかもしれません。
私も今のところ良いユースケースを思いつかない状況ですが、せっかく構築できたので本記事で紹介した次第です。
うまい使い方をご存知の方がいれば、ぜひコメントいただけますと幸いです。