搭建基于Ubuntu Server的PXE自動安裝環境的實用指南
Ubuntu 在不斷進化,從 20.04 開始,Ubuntu 決定更新實時服務器安裝程序,只用 Subiquity 就能完全完成操作系統及附加程序的自動安裝。以前用的 kickstart、debian-installer 都不是 Ubuntu 自家技術,用起來也不是很方便。
同時,PXE 技術雖然出來很久了,但是整個安裝過程還不是特別順暢,隨著 Ubuntu 升級到 20.04,使用 cloud-init 安裝配置實現 Subiquity 參數的自動填寫,整個過程變得些微優雅起來,讓我有較大興趣嘗試使用 PXE 安裝 Ubuntu 20.04 Server。
本文,我想講的是在 Ubuntu 20.04 Server 上搭建一套自動安裝 Ubuntu 20.04 Server 的部署環境,其主要內容有兩部分:
- 使用 PXE 自動從網絡加載安裝程序,發起安裝。
- 使用 Ubuntu 的自動安裝功能,自動加載 cloud-init 安裝配置,完成操作系統的自動選擇。
第一部分所有操作系統應該都是一樣的,第二部分和 Ubuntu 20.04 版本緊密相關,其他的操作系統需要考慮其他方法。
PXE 安裝流程
PXE(預啟動執行環境)的實現依賴于網卡,只有支持 PXE 客戶端的網卡才能實現網絡自動安裝。這種網卡實現了 DHCP 客戶端和 TFTP 客戶端,在 BIOS 的引導下通過 DHCP 協議自動分配 IP 地址,通過 TFTP 獲取最小內核,然后在最小內核環境下通過 HTTP 協議或 NFS 協議獲取 Ubuntu 安裝版本。之后最小內核引導進行 Ubuntu 20.04 的安裝。
下圖是詳細的安裝流程。
上圖有幾個前提:
- 網卡支持 PXE,今年新出的網卡基本都支持,同時 BIOS 的啟動項也要配置,請大家自行研究。
- UEFI 啟動才會請求
bootx64.efi
,如果是傳統啟動模式),那么 PXE 客戶端會請求pxelinux.0
。 - 可以采用 nfsboot 方式,這個流程采用的是 ISO 鏡像下載再安裝的方式。
安裝必須的服務端軟件
- 安裝 DHCP、TFTP 服務器。
dnsmasq
同時實現了 DHCP、TFTP、DNS 三種服務器- sudo apt-get install dnsmasq
- 安裝 HTTP 服務器
HTTP 服務器有很多,大家可以使用自己的熟悉的服務器如 Nginx,這里使用的是apache2
- sudo apt-get install apache2
準備啟動文件
- 下載 UEFI 引導文件:
shim.signed
、grub-efi-amd64-signed
apt-get download shim.signed
apt-get download grub-efi-amd64-signed
- 下載 Ubuntu 20.04 Server ISO 鏡像
直接去官網下載,我下載的是
ubuntu-20.04.2-live-server-amd64.iso
,需要注意的是只有 Live 版本才能支持 subiquity。
創建 TFTP 文件夾
TFTP 文件夾是 TFTP 服務的根目錄,PXE 啟動過程中下載的文件都存在在該目錄中:
tftp
├── boot
│ └── live-server
│ ├── initrd
│ └── vmlinuz
├── grub
│ ├── bootx64.efi
│ ├── font.pf2
│ └── grub.cfg
└── grubx64.efi
說明:
bootx64.efi
、grubx64.efi
引導程序來自shim.signed
安裝包grub.cfg
自行創建- 其他文件來自 Ubuntu 安裝包
- 這五個文件是需要的,但是目錄結構是自行創建的,大家可以根據自己的喜好修改
創建目錄
在 /home/mine
(可根據實際情況修改)目錄下創建 tftp
目錄:
mkdir /home/mine/tftp
mkdir /home/mine/tftp/grub
mkdir /home/mine/tftp/boot
mkdir /home/mine/tftp/boot/live-server
獲取引導文件
- 在安裝包下載目錄創建一個
shim
文件夾 - 解壓
shim
安裝包到shim
文件夾:dpkg -x <%剛才下載的shim.signed 安裝包包名%> shim
- 解壓 grub 安裝包到
grub
文件夾 - 拷貝引導文件到
tftp
目錄
cp ./sgrub/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed /home/mine/tftp/grubx64.efi
cp ./shim/usr/lib/shim/shimx64.efi.signed /home/mine/tftp/grub/bootx64.efi
獲取內核鏡像文件
- 在下載目錄掛載 ISO 文件
sudo mount ubuntu-20.04.2.0-desktop-amd64.iso /media
系統會提示只讀,不影響使用。
mount: /media: WARNING: device write-protected, mounted read-only.
- 拷貝內核鏡像文件
cp /media/casper/initrd /home/mine/tftp/boot/live-server
cp /media/casper/vmlinuz /home/mine/tftp/boot/live-server
- 拷貝 grub 文件
grub.cfg
拷貝過來做個參考,內容會被全部修改掉。cp /media/grub/font.pf2 /home/mine/tftp/grub
cp /media/grub/grub.cfg /home/mine/tftp/grub
配置 dnsmasq
關鍵配置有以下幾個:
- 配置 DHCP 地址段
- 配置引導文件目錄
- 配置 tftp 根目錄
- 配置日志路徑
- 配置服務網卡,多網卡機器需關注
# 配置外網 DNS 服務器地址
server=114.114.114.144
# 指定服務的網卡
interface=enp2s0,lo
# 綁定端口
bind-interfaces
# 設置 DHCP 分發 IP 端范圍、地址掩碼、IP 地址有效時間
dhcp-range=192.168.1.100,192.168.1.150,255.255.255.0,12h
# 指定網關地址
# 和安裝無關,應該可以不配置
dhcp-option=3,192.168.1.9
# 指定 DNS 服務器地址
# 和安裝無關,應該可以不配置
dhcp-option=6,114.114.114.114
# 設置引導程序相對 tftp 根目錄的路徑
dhcp-match=set:efi-x86_64,option:client-arch,7
dhcp-boot=tag:efi-x86_64,grub/bootx64.efi
# 啟用 tftp 服務
enable-tftp
# 設置 tftp 根路徑
tftp-root=/home/mine/tftp
# 設置日志路徑
log-facility=/var/log/dnsmasq.log
修改配置后,重啟 dnsmasq
服務才能生效。
創建 HTTP 文件夾
Apache2 的默認服務根目錄是 /var/www/html
,在其下創建目錄:
html/
├── autoinstall
│ ├── meta-data
│ └── user-data
├── index.html
└── iso
└── ubuntu-20.04.2-live-server-amd64.iso
說明:
autoinstall
目錄存放參數自動配置文件,user-data
、meta-data
是cloud-init 要求的文件名iso
目錄存放操作系統鏡像文件
創建目錄
mkdir /var/www/html/autoinstall
mkdir /var/www/html/iso
拷貝 ISO 文件
到下載目錄拷貝 ISO 文件:
cp ubuntu-20.04.2-live-server-amd64.iso /var/www/html/iso
創建參數自動配置文件
先創建空文件,meta-data
無需修改,user-data
后續會詳細描述配置。
touch /var/www/html/autoinstall/user-data
touch /var/www/html/autoinstall/meta-data
配置 grub.cfg
if loadfont /grub/font.pf2 ; then
set gfxmode=auto
insmod efi_gop
insmod efi_uga
insmod gfxterm
terminal_output gfxterm
fi
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
set timeout=5
menuentry "Ubuntu server 20.04 autoinstall" {
set gfxpayload=keep
linux /boot/live-server/vmlinuz root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url='http://192.168.1.9/iso/ubuntu-20.04.2-live-server-amd64.iso' autoinstall ds=nocloud-net\;s=http://192.168.1.9/autoins
tall/ ---
initrd /boot/live-server/initrd
}
menuentry
之前是配置樣式,也可以刪除,重點關注 menuentry "Ubuntu server 20.04 autoinstall"
內的配置:
- 指定鏡像文件相對于
tftp
根目錄的路徑/boot/live-server/initrd
root=/dev/ram0 ramdisk_size=1500000
為了指定內核鏡像掛載空間,是否可刪除我不確定ip=dhcp
指定內核鏡像掛載后使用 DHCP 獲取 IP 地址url=
指定 ISO 文件的網絡存放路徑autoinstall ds=nocloud-net\;s=http://192.168.1.9/autoinstall/ ---
該配置指明參數自動填寫,并指明配置文件所在路徑
坑
網上很多文章配置是這么寫的 ds=nocloud-net;s=http://192.168.1.9/autoinstall/
,我試了很多次,都沒有自動安裝。
在網上查到,由于 UEFI 啟動使用了 grub,它將 ;
識別為了特殊字符,所以要在 ;
前加 \
轉義。
配置 user-data
#cloud-config
autoinstall:
version: 1
# 修改apt 服務地址
apt:
primary:
- arches: [default]
uri: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
user-data:
# 配置時區
timezone: Asia/Shanghai
# 去使能 root賬號
disable_root: true
# 配置用戶
identity:
hostname: ubuntu-server
password: "yours"
username: ubuntu
# 配置鍵盤
keyboard: {layout: us, variant: ''}
locale: en_US.UTF-8
# 配置代理
proxy: http://192.168.1.112:3128
# 默認安裝ssh server
ssh:
install-server: true
# 指定安裝的包
packages:
- net-tools
- python3-pip
# 配置磁盤分區
storage:
grub:
reorder_uefi: False
config:
- {ptable: gpt, path: /dev/sda, wipe: superblock-recursive, preserve: false, name: '',
grub_device: false, type: disk, id: disk-sda}
- {device: disk-sda, size: 536870912, wipe: superblock, flag: boot, number: 1,
preserve: false, grub_device: true, type: partition, id: partition-0}
- {fstype: fat32, volume: partition-0, preserve: false, type: format, id: format-0}
- {device: disk-sda, size: -1, wipe: superblock, flag: '', number: 2,
preserve: false, type: partition, id: partition-1}
- {fstype: ext4, volume: partition-1, preserve: false, type: format, id: format-1}
- {device: format-1, path: /, type: mount, id: mount-1}
- {device: format-0, path: /boot/efi, type: mount, id: mount-0}
說明:
- 密碼需要加密,可以先用工具對自己的密碼進行加密后填入
- 代理不是必須的配置,與網絡拓撲有關
- 磁盤分區配置要注意,配置不對會導致自動安裝走不下去,提示 crash;這個配置的整體思路是先格式化
disk-sda
,然后在disk-sda
下劃分/dev/sda1
、/dev/sda2
,然后分別掛載/
、/boot/efi
目錄 - 安裝過程日志在
/var/log/installer/
,如果安裝失敗可以通過nc
等工具實時發出去
網絡拓撲
- 我在電腦上搭建了 DHCP、TFTP、HTTP 三種服務
- 我在代理機上搭建了 squid,作為 HTTP 代理
- 目標機器不能上網,三臺機器在同一個局域網
配置靜態 IP
在服務機開始服務前,需要在提供服務的網卡上配置靜態 IP,Ubuntu 20.04 配置 netplan 即可,參考以下配置修改文件 /etc/netplan/00-installer-config.yaml
,修改完成后執行 netplan apply
配置即可生效。
# This is the network config written by 'subiquity'
network:
ethernets:
enp2s0:
addresses:
- 192.168.1.9/24
gateway4: 192.168.1.1
nameservers:
addresses:
- 114.114.114.114
search:
- 114.114.114.114
鳴謝
- 文章的基石來自 Grffion,沒有這篇文章我會摸索更長時間
- 這篇 askubuntu 的討論 解決了坑
- user-data 磁盤分區配置來自 小崔