概述
Ubuntu Server 18.04.5 系统安装使用 debian-installer,兼容 Kickstart 但不够灵活,比如从 5 块 NVMe 硬盘中找到容量最小的盘安装系统这种操作就很难做到。自家的脚本是 Preseed,功能非常强大,能完成一些图形安装界面届不到的操作(缺点是有一点点复杂)。
在 CentOS 篇中,PXE Server 需要安装 DHCP/TFTP/Nginx 等众多软件。这次改用 Dnsmasq 同时提供 DHCP 和 TFTP 服务。也省去 Nginx,直接从软件源安装系统。
安装软件
下载 Ubuntu 镜像,文中使用的是 ubuntu-18.04.5-server-amdyes.iso
。
安装 dnsmasq 服务。
sudo apt updatesudo apt install dnsmasq
配置 dnsmasq,开启 DHCP 和 TFTP 功能。
mkdir -p /srv/tftp/vim /etc/dnsmasq.conf
内容如下。
interface=eth0bind-interfacesdhcp-range=172.16.199.1,172.16.199.254dhcp-boot=grubnetx64.efi.signeddhcp-host=172.16.199.1enable-tftptftp-root=/srv/tftp/
其中,interface 是当前使用的网络接口,dhcp-boot 是 grub 引导程序的位置,dhcp-host 是 DHCP Server 网关 IP(可用来可访问本机器),tftp-root 则是 TFTP Server 的根目录。
启动 dnsmasq 服务。
sudo systemctl start dnsmasq
配置 PXE Server
Boot loader
UEFI 启动需要一个 boot loader(文中是 GRUB)。从软件源下载,然后丢进 TFTP 根目录。
sudo apt-get install grub-efi-amd64-signedsudo cp /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed /srv/tftp/grubnetx64.efi.signed
grubnetx64.efi.signed 这个名字就是在 /etc/dnsmasq.conf 的 dhcp-boot 字段中定义的那个。
GRUB
配置 GRUB,其实就是 Ubuntu 那个选择系统的启动菜单,添加一个启动项,把系统位置从硬盘改为网络。
mkdir -p /srv/tftp/grubvim /srv/tftp/grub/grub.cfg
内容如下。
set default="0"
set timeout=6
menuentry "Install Ubuntu" {
set gfxpayload=keep
linux /ubuntu/linux gfxpayload=800x600x16,800x600 --- auto=true priority=critical interface=auto hostname=fox GRUB_DISABLE_OS_PROBER=true url=tftp://172.16.1.1/preseed.cfg quiet
initrd /ubuntu/initrd.gz
}
...
由于 Ubuntu 18.04 的 os-prober 操作 LVM 分区时会触发 BUG,所以加了个环境变量 GRUB_DISABLE_OS_PROBER=true 禁用 os-prober。其他配置项说明参考 CentOS 篇。
网络引导
从这里下载 Ubuntu 的网络引导镜像,解压到 TFTP 目录下。
mkdir -p /srv/tftp/ubuntuwget http://archive.ubuntu.com/ubuntu/dists/bionic-updates/main/installer-amd64/current/images/netboot/netboot.tar.gztar -xvzf netboot.tar.gz -C /srv/tftp/ubuntu
软件包缓存
Ubuntu 安装程序支持 APT 安装软件包,默认是从官方软件源下载。但如果批量安装,外网怕是会炸,所以要在内网(PXE Server)搭建软件包缓存服务。
sudo apt-get install apt-cacher-ng
安装完成后,在 Preseed 脚本中配置源代理 d-i mirror/http/proxy string http://<YOUR_IP>:3142/
指向该机器。
Preseed
Preseed 脚本可配置项非常多,详细可参见官方文档。下面简单举几个🌰,可根据自身需求修改。
- 相同的部分
系统盘使用 LVM 方式分区,除了 /boot,/boot/efi
分区外,其余空间全给根目录,禁用 SWAP 分区。启用 ROOT 用户,允许 ROOT 用户远程登录,安装 openssh-server openssh-client vim curl
软件。
- 系统盘名字固定,比如单块 SATA 系统盘默认设备名是
/dev/sda
,单块 NVMe SSD 是/dev/nvme0n1
,这样系统盘可以写死在配置中。
### Unattended Installationd-i auto-install/enable boolean trued-i debconf/priority select critical### Localizationd-i debian-installer/locale string en_US.UTF-8d-i localechooser/languagelist select end-i localechooser/shortlist/en select USd-i localechooser/continentlist select Asiad-i localechooser/countrylist/Asia select Chinad-i console-setup/ask_detect boolean falsed-i keyboard-configuration/xkb-keymap select us### Account setupd-i passwd/root-login boolean trued-i passwd/make-user boolean falsed-i passwd/root-password password ABC123defd-i passwd/root-password-again password ABC123defd-i user-setup/allow-password-weak boolean true### Network configurationd-i netcfg/choose_interface select autod-i netcfg/get_hostname string catd-i hw-detect/load_firmware boolean true# If you want the preconfiguration file to work on systems both with and# without a dhcp server, uncomment these lines and the static network# configuration below.d-i netcfg/dhcp_failed noted-i netcfg/dhcp_options select Configure network manually# Static network configuration.d-i netcfg/get_ipaddress string 172.16.1.207d-i netcfg/get_netmask string 255.255.0.0d-i netcfg/get_gateway string 172.16.255.254d-i netcfg/get_nameservers string 223.5.5.5d-i netcfg/confirm_static boolean true### Partition# Specify a disk to partition. The device name# can be given in either devfs or traditional non-devfs format.d-i partman-auto/disk string /dev/nvme0n1d-i grub-installer/bootdev string /dev/nvme0n1# In addition, you'll need to specify the method to use.# The presently available methods are: "regular", "lvm" and "crypto"d-i partman-auto/method string lvm# If one of the disks that are going to be automatically partitioned# contains an old LVM configuration, the user will normally receive a# warning. This can be preseeded away...d-i partman-auto/purge_lvm_from_device boolean true# http://cptyesterday.wordpress.com/2012/06/17/notes-on-using-expert_recipe-in-debianubuntu-preseed-files/d-i partman-auto/choose_recipe select boot-rootd-i partman-auto-lvm/new_vg_name string maind-i partman-auto-lvm/guided_size string maxd-i partman-auto/expert_recipe string \ boot-root :: \ 1 1 1 free \ $bios_boot{ } \ method{ biosgrub } \ . \ 256 256 256 fat32 \ $primary{ } \ $iflabel{ gpt } \ $reusemethod{ } \ method{ efi } format{ } \ mountpoint{ /boot/efi } \ . \ 512 512 512 ext4 \ $primary{ } \ $bootable{ } \ method{ format } format{ } \ use_filesystem{ } filesystem{ ext4 } \ mountpoint{ /boot } \ . \ 4096 4096 -1 ext4 \ $lvmok{ } \ method{ format } format{ } \ use_filesystem{ } filesystem{ ext4 } \ mountpoint{ / } \ lv_name{ root } \ .# Write the changes to disks and configure LVMd-i partman/confirm boolean trued-i partman-lvm/confirm boolean trued-i partman-lvm/confirm_nooverwrite boolean true# http://ubuntuforums.org/showthread.php?p=9626883d-i partman-lvm/device_remove_lvm boolean true# This makes partman automatically partition without confirmation.d-i partman/choose_partition \ select Finish partitioning and write changes to diskd-i partman/confirm_nooverwrite boolean trued-i pkgsel/include string openssh-server openssh-client vim curl### Mirror settingsd-i mirror/country string manuald-i mirror/http/hostname string mirrors.ustc.edu.cnd-i mirror/http/directory string /ubuntud-i mirror/http/proxy string http://172.16.1.1:3142/# Custom commandsd-i preseed/late_command string \ in-target sh -c 'sed -i "/#PermitRootLogin/a PermitRootLogin yes" /etc/ssh/sshd_config';finish-install finish-install/keep-consoles boolean falsed-i finish-install/reboot_in_progress note
- 机器安装多块硬盘,比如有 5 块 NVMe SSD,256GBx1 & 2TBx4,系统装在 256GB 的硬盘上。
基于上面的脚本,在 early_command 中使用 Bash 脚本,通过 debconf-set 来动态指定硬盘位置。
# 删除下面两个配置d-i partman-auto/disk string /dev/nvme0n1d-i grub-installer/bootdev string /dev/nvme0n1# 用这个脚本找出小于 300GB 的硬盘,指定为系统盘d-i partman/early_command string \ for BOOTDEV in nvme0n1 nvme1n1 nvme2n1 nvme3n1 nvme4n1; do \ if [ -d /sys/block/$BOOTDEV ]; then \ SIZE=`cat /sys/block/$BOOTDEV/size`; \ GB=$(($SIZE/2**21)); \ if [ $GB -lt 300 ]; then \ debconf-set partman-auto/disk "/dev/$BOOTDEV"; \ debconf-set grub-installer/bootdev "/dev/$BOOTDEV"; \ fi; \ fi; \ done
- 机器本来有系统,需要批量重装,原系统也是 LVM 方式分区。
先移除已存在的 LVM 分区,再尝试安装(虽然有相关配置项,但该版本可能存在 BUG)。
# 移除 LVM 分区d-i partman-lvm/device_remove_lvm boolean trued-i partman-auto/purge_lvm_from_device boolean true# 上述配置项可能存在 BUG,那就亲自删一遍d-i partman/early_command string \ set -- $(vgs --rows --noheadings | head -n 1); \ for vg in "$@"; do \ swapoff "/dev/$vg/swap"; \ vgremove -f "$vg"; \ done; \ set -- $(pvs --rows --noheadings | head -n 1); \ for pv in "$@"; do \ pvremove -f "$pv"; \ done
Preseed 文件放到 TFTP 根目录 /srv/tftp/
下,也就是 GRUB 菜单配置里 url 指定的那个。
PXE 引导
确保内网中没有其他 DHCP 服务,将机器接在 PXE Server 同一个交换机下。重启机器,启动时选择从 PXE 引导,观察是否获得 IP,能否下载启动文件。正常的话稍后就能看到 Ubuntu 安装界面。