Contents
Overview
PXE と Autoinstall を使用して Ubuntu のインストールを自動化します。本稿では UEFI のみを対象としています。PXE の仕組みはさまざまな要素が複合的に動作するため、ある程度の経験のあるエンジニアでないと構築そのものが難しい可能性もあります。
PXE
PXE (Preboot Execution Environment) は、コンピューターの起動時にネットワークを介して自動的に OS やその他のソフトウェアをインストールするための標準化されたプロセスです。RFC 2131, 4578 などで標準化されています。PXE を使用すると、コンピューターは特別な PXE ブート ROM を介してネットワークに接続し、DHCP サーバーから IP アドレスを取得し、PXE サーバーから起動イメージをダウンロードします。これにより、ハードディスクに OS がインストールされていない新しいコンピューターでも、ネットワーク経由で OS のインストールやシステムのセットアップを自動化することができます。PXE は、大規模なデプロイメントや管理で時間と手間を節約するために広く使用されています。
PXE サーバーは主に以下のコンポーネントから構成されます。
- DHCP サーバー: PXE boot 対象のデバイスにネットワーク設定をするとともに、後続の参照先 TFTP サーバーとブートローダーのファイル名を対象デバイスに伝えます。
- TFTP サーバー: Linux の boot に必要となる vmlinuz, initrd, grub.cfg, UEFI boot loader などを配置します。対象デバイスはこれらのファイルを参照して起動します。
- Web サーバー: ISO ファイル、Autoinstall の設定ファイルなどを配置します。対象デバイスはこれらのファイルを参照して OS の自動インストールを開始します。
Autoinstall
Autoinstall は、Ubuntu のインストールプロセスを自動化するための仕組みで、内部的には cloud-init が使用されています。この機能を使用すると、ユーザーは手動で OS をインストールする必要なく、事前に定義された設定ファイルを使用して、インストール手順やシステム構成を定義することができます。この設定ファイルには、ネットワーク設定、パーティショニング、ソフトウェアの選択、ユーザーアカウントの設定などの情報が含まれています。これにより、大規模な環境での一貫したデプロイメントや、繰り返しの作業を自動化することが可能になります。
前提条件
- こちらを参考に DHCP サーバーの構築が完了していること。「PXE boot 用の設定」を参照して下さい。
- こちらを参考に TFTP サーバーの構築が完了していること。
- こちらを参考に Web サーバーの構築が完了していること。
- 本稿では同一ホスト内で DHCP, TFTP, Web サーバーが稼働していることを前提に説明しています。別ホストになる場合は適宜読み替えて下さい。
ISO イメージの配置
iso ディレクトリを作成し、ISO イメージを配置します。ISO イメージはこちらからダウンロードして下さい。
myadmin@ubuntu:~$ sudo mkdir /var/www/html/iso
myadmin@ubuntu:~$ ls -l /var/www/html/iso/ubuntu-22.04.3-live-server-amd64.iso
vmlinuz, initrd, grub.cfg の抽出と配置
ISO イメージをマウントします。
myadmin@ubuntu:~$ sudo mount /var/www/html/iso/ubuntu-22.04.3-live-server-amd64.iso /mnt
必要なディレクトリを作成します。
myadmin@ubuntu:~$ sudo mkdir -p /srv/tftp/{grub,casper}
必要なファイルをを TFTP のルートディレクトリにコピーします。grub.cfg は後で書き換える為、一旦、名前を変更してコピーしています。
myadmin@ubuntu:~$ sudo cp /mnt/boot/grub/grub.cfg /srv/tftp/grub/grub.cfg.sample
myadmin@ubuntu:~$ sudo cp /mnt/casper/{vmlinuz,initrd} /srv/tftp/casper
ISO イメージのマウントを解除します。
myadmin@ubuntu:~$ sudo umount /mnt
grub.cfg.sample をベースに grub.cfg を作成します。grub.cfg の書き方は、各々こだわりがあるかもしれませんが、以下の例では、GRUB のメニューから対象デバイスを選択することで、適用する Autoinstall ファイルを分けられる設定としています。特に Autoinstall ファイルを分ける必要性がない場合は、一つにまとめて良いでしょう。
myadmin@ubuntu:~$ sudo tee /srv/tftp/grub/grub.cfg <<EOF
set timeout=30
loadfont unicode
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
set web_server=10.1.0.80
set iso_url=http://${web_server}/iso/ubuntu-22.04.3-live-server-amd64.iso
set autoinstall_url=http://${web_server}/autoinstall
menuentry "PXE boot autoinstall ubuntu1" {
set gfxpayload=keep
linux /casper/vmlinuz ip=dhcp url=${iso_url} autoinstall cloud-config-url=${autoinstall_url}/ubuntu1.yaml
initrd /casper/initrd
}
menuentry "PXE boot autoinstall ubuntu2" {
set gfxpayload=keep
linux /casper/vmlinuz ip=dhcp url=${iso_url} autoinstall cloud-config-url=${autoinstall_url}/ubuntu2.yaml
initrd /casper/initrd
}
menuentry "PXE boot autoinstall ubuntu3" {
set gfxpayload=keep
linux /casper/vmlinuz ip=dhcp url=${iso_url} autoinstall cloud-config-url=${autoinstall_url}/ubuntu3.yaml
initrd /casper/initrd
}
grub_platform
if [ "$grub_platform" = "efi" ]; then
menuentry 'Boot from next volume' {
exit 1
}
menuentry 'UEFI Firmware Settings' {
fwsetup
}
else
menuentry 'Test memory' {
linux16 /boot/memtest86+.bin
}
fi
EOF
ブートローダーの配置
UEFI ブートローダーを配置します。ここまでで TFTP サーバーの準備は完了です。この情報はこちらを参考にしました。
myadmin@ubuntu:~$ sudo wget -O /srv/tftp/grubnetx64.efi.signed http://archive.ubuntu.com/ubuntu/dists/jammy/main/uefi/grub2-amd64/current/grubnetx64.efi.signed
Autoinstall
Autoinstall ファイルの作成前に、対象デバイスに手動インストールを行い、必要な情報(ネットワークインターフェイス名、ストレージデバイス名など)を入手しておくことが重要です。インストール後は、Autoinstall ファイルのテンプレートとして /var/log/installer/autoinstall-user-data が作成されますので、それを参考にすると良いでしょう。
myadmin@ubuntu:~$ cat /var/log/installer/autoinstall-user-data
Autoinstall ファイルを配置するディレクトリを作成します。
myadmin@ubuntu:~$ sudo mkdir /var/www/html/autoinstall
Autoinstall ファイルに記載する管理者パスワードのハッシュを生成します。
myadmin@ubuntu:~$ openssl passwd -6 -salt $(openssl rand -hex 8) 'password'
- -6: SHA-512 アルゴリズムを使用してパスワードのハッシュを生成します。
- -salt $(openssl rand -hex 8): 8 バイトのランダムな 16 進数文字列 (solt) を生成します。
- ‘password’ を実際のパスワードとして指定しています。
autoinstall-user-data をベースに Autoinstall ファイルを作成します。この例は前述の grub.cfg の ubuntu1 を想定しており、ubuntu1 は KVM を想定したパーティション構成となっています。
myadmin@ubuntu:~$ sudo tee /var/www/html/autoinstall/ubuntu1.yaml <<EOF
#cloud-config
autoinstall:
apt:
disable_components: []
fallback: abort
geoip: true
mirror-selection:
primary:
- country-mirror
- arches:
- amd64
- i386
uri: http://archive.ubuntu.com/ubuntu
- arches:
- s390x
- arm64
- armhf
- powerpc
- ppc64el
- riscv64
uri: http://ports.ubuntu.com/ubuntu-ports
preserve_sources_list: false
codecs:
install: false
drivers:
install: false
identity:
hostname: ubuntu1
# plain text: password, openssl passwd -6 -salt $(openssl rand -hex 8) 'password'
password: xxxxxxxx
realname: myadmin
username: myadmin
kernel:
package: linux-generic
keyboard:
layout: jp
toggle: null
variant: ''
locale: en_US.UTF-8
network:
ethernets:
eno1:
dhcp4: true
version: 2
source:
id: ubuntu-server
search_drivers: false
ssh:
allow-pw: true
authorized-keys: [ssh-ed25519 xxxxxxxx myadmin@ubuntu]
install-server: true
storage:
config:
# /dev/sda
- ptable: gpt
path: /dev/sda
wipe: superblock-recursive
preserve: false
name: ''
grub_device: false
type: disk
id: d-sda
# sda1, /boot/efi
- device: d-sda
size: 1G
wipe: superblock
flag: boot
number: 1
preserve: false
grub_device: true
type: partition
id: p-sda1
- fstype: fat32
volume: p-sda1
preserve: false
type: format
id: f-sda1
- path: /boot/efi
device: f-sda1
type: mount
id: m-sda1
# sda2, /boot
- device: d-sda
size: 2G
wipe: superblock
number: 2
preserve: false
grub_device: false
type: partition
id: p-sda2
- fstype: ext4
volume: p-sda2
preserve: false
type: format
id: f-sda2
- path: /boot
device: f-sda2
type: mount
id: m-sda2
# sda3, vg0
- device: d-sda
size: -1
wipe: superblock
number: 3
preserve: false
grub_device: false
type: partition
id: p-sda3
- name: vg0
devices:
- p-sda3
preserve: false
type: lvm_volgroup
id: vg0
# vg0, root
- name: root
volgroup: vg0
size: 20G
wipe: superblock
preserve: false
type: lvm_partition
id: p-root
- fstype: ext4
volume: p-root
preserve: false
type: format
id: f-root
- path: /
device: f-root
type: mount
id: m-root
# vg0, var
- name: var
volgroup: vg0
size: 10G
wipe: superblock
preserve: false
type: lvm_partition
id: p-var
- fstype: ext4
volume: p-var
preserve: false
type: format
id: f-var
- path: /var
device: f-var
type: mount
id: m-var
# vg0, home
- name: home
volgroup: vg0
size: 40G
wipe: superblock
preserve: false
type: lvm_partition
id: p-home
- fstype: ext4
volume: p-home
preserve: false
type: format
id: f-home
- path: /home
device: f-home
type: mount
id: m-home
# vg0, /var/lib/libvirt/images
- name: var_lib_libvirt_images
volgroup: vg0
size: -1
wipe: superblock
preserve: false
type: lvm_partition
id: p-var_lib_libvirt_images
- fstype: ext4
volume: p-var_lib_libvirt_images
preserve: false
type: format
id: f-var_lib_libvirt_images
- path: /var/lib/libvirt/images
device: f-var_lib_libvirt_images
type: mount
id: m-var_lib_libvirt_images
updates: security
version: 1
EOF
主な変数を以下に示します。
- hostname: ホスト名を設定します。
- password: ハッシュした管理者パスワードを設定します。
- realname, username: 管理者のユーザー名を設定します。
- network: 対象デバイスのインターフェイス名を設定します。この時点で固定 IP アドレスを設定することも可能ですが、本稿の例では DHCP としています。インターフェイス名が異なると Autoinstall は失敗します。完全一致ではない書き方も可能ではあります。
- authorized-keys: SSH の公開鍵を設定しています。
- storage: パーティション、LVM の設定です。Autoinstall の設定で一番面等なのがこの設定でしょう。この例は筆者が見やすく書きやすい状態としていますが、見る人によっては見づらいかもしれません。とにかく、どのような構造で書かれているかをまずは理解することが重要です。YAML をフロー形式で記載することも見やすくする選択肢になるかもしれません。この設定もデバイス名が異なると Autoinstall は失敗します。
自動インストールの確認
ここまでで PXE を使用した自動インストールが可能な状態となっています。PXE ブート可能なデバイスを起動して確認しましょう。UEFI での PXE ブート設定は、各デバイスの BIOS に依存しますので、それぞれのマニュアルなどを参考にして下さい。
補足
- KVM の virt-install では、Autoinstall ファイルを指定して読み込ませることができるため、PXE 環境は不要となります。
- 22.04.2 あたりから Autoinstall の指定方法がおそらく変わっています。それ以前は metadata, userdata として指定が必要でしたが、その方式ではうまくいかなくなりました。本稿の例は 22.04.3 で確認しています。
最後に
冒頭にも述べましたが、PXE の仕組みは複合的で複雑であるため、デバッグを含めた検証にもかなり時間を使いました。もし参考になりましたら、コメントを頂けますと励みになります。