概述
预启动执行环境(Preboot eXecution Environment,PXE)提供了一种使用网络接口(Network Interface)启动计算机的机制,可用于安装操作系统。流程一般如下。
- 客户端从 Network 启动,发送 DHCP 请求。
- DHCP 服务器发送一个带有 next-server 信息的响应。
- 客户端发送 DHCPREQUEST/DHCPINFORM 请求。
- DHCP 服务器发送 TFTP 服务器地址和所需的文件名。
- 客户端从 TFTP 服务器下载这个文件,一般是很小的引导文件。
- pxelinux/grub 读取配置文件,下载相关文件。
- 进入安装程序,下载 Anaconda 的 Kickstart 自动应答脚本,开始安装。
准备工作
下载 CentOS 镜像,文中使用的是 CentOS-7-x86_64-Minimal-2003.iso
。
Optional: 手动装一台机器(安装程序选择非图形界面,Troubleshooting -> Install CentOS Linux 7 in basic graphics mode)。进入系统,在$HOME
目录下有个 Kickstart 文件,里面是安装程序自动生成的脚本,保存起来作为模板。
选一台机器用作 PXE Server(比如上面装好的),开放 tftp 和 http 端口(或者禁用防火墙),关闭 SELinux(会阻止从网络访问本地文件)。
systemctl disable firewalld.service --nowsed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/configsetenforce 0
如果路由器是 DHCP 模式,最好先从交换机上拔掉,或者改为静态 IP 模式(如果机器都接在路由器上),因为内网中存在多个 DHCP Server 会相互干扰。
Optional: 也可以用 Dnsmasq 替代 dhcp 和 tftp-server,具体参见 Ubuntu 篇。
DHCP Server
支持 PXE 启动的网卡会内置 DHCP Client,用于从内网 PXE Server 获取 IP,顺便查询 TFTP Server 的 IP。那我们第一步就是在 PXE Server 上安装 DHCP Server 为 PXE 设备分配 IP。
yum install dhcp -y
考虑到服务器配置各不相同,安装方法肯定也有所不同,但装系统也只需在意系统盘的区别。比如 NVMe SSD 或 SATA SSD,前者仅支持 UEFI 引导,后者可用 UEFI 或 Legacy,但机器只支持 Legacy PXE 启动。想一次性装完所有机器,可以在 DHCP Server 的配置中加入判断,区分客户端是普通 DHCP 还是 UEFI PXE 或是 Legacy PXE。dhcpd
的配置位于/etc/dhcp/dhcpd.conf
。
option pxe-system-type code 93 = unsigned integer 16;subnet 172.16.22.0 netmask 255.255.255.0 { range 172.16.22.2 172.16.22.254; option routers 172.16.22.1; option subnet-mask 255.255.255.0; next-server 172.16.22.1; if option pxe-system-type = 00:07 { filename "uefi/shim.efi"; } else if option pxe-system-type = 00:09 { filename "uefi/shim.efi"; } else { filename "pxelinux.0"; }}
next-server
用于提示 TFTP Server 的 IP 地址,可以是本机。
shim
是 Linux 的引导程序,支持 EFI 引导,如果检测到 UEFI PXE 就用这个。
pxelinux.0
也是 Linux 的引导程序(SYSLINUX),用于 Legacy PXE。
TFTP Server
PXE 支持 TFTP 协议,我们把引导程序(shim & pxelinux.0)放在 TFTP 服务器对应目录。
yum install xinetd tftp-server –y
xinetd 是 TFTP 的守护进程,启动 xinetd 就能拉起 TFTP。
systemctl start xinetdsystemctl enable xinetd
TFTP 服务器默认根目录在/var/lib/tftpboot
,后面会把引导文件放这里。
HTTP Server
TFTP 基于小块(512KB)的 UDP 协议传输数据,速度很慢,只适合传输小文件。软件包等大文件可以换用 NGINX 之类的 HTTP Server 下载。
yum install epel-releaseyum install nginx
默认配置文件在/etc/nginx/nginx.conf
,在 location 中添加autoindex on
配置打开文件索引,大文件就放在网络根目录下。
server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { autoindex on; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { }}
UEFI 引导
用 yum 下载 CentOS 7 的 UEFI 引导软件包。
yum install grub2-efi-x64 shim-x64
在 TFTP 服务器根目录下新建目录,用于存放 uefi 启动文件。
mkdir /var/lib/tftpboot/uefi
复制相关文件,修改文件权限。
cp -p /boot/efi/EFI/centos/*.efi /var/lib/tftpboot/uefi/chmod 755 /var/lib/tftpboot/uefi/*.efi
Optional: 或者直接从系统镜像复制过来也行,方法如下。
mkdir /centosmkdir $HOME/uefi_tmpmount -t iso9660 CentOS-7-x86_64-Minimal-2003.iso /centos -o loop,rocp -pr /centos/Packages/shim-version-architecture.rpm $HOME/uefi_tmpcp -pr /centos/Packages/grub2-efi-version-architecture.rpm $HOME/uefi_tmp
解压 rpm 软件包。
cd $HOME/uefi_tmprpm2cpio shim-version-architecture.rpm | cpio -dimvrpm2cpio grub2-efi-version-architecture.rpm | cpio -dimv
复制 EFI 引导程序到 TFTP 目录。
cp $HOME/uefi_tmp/boot/efi/EFI/centos/shim.efi /var/lib/tftpboot/uefi/cp $HOME/uefi_tmp/boot/efi/EFI/centos/grubx64.efi /var/lib/tftpboot/uefi/
在下面的栗子中,Vmlinuz 是 Linux 内核可执行文件,它将 OS 加载到内存中,这样就可以启动机器了。inst.ks
是 Kickstart 自动应答脚本。Initrd 镜像用来初始化 RAM 磁盘,然后将其挂载为根文件系统,并从中运行 CentOS 安装程序。
在grubx64.efi
同级目录新建 GRUB 配置文件/var/lib/tftpboot/uefi/grub.cfg
。
set default="0"function load_video { insmod efi_gop insmod efi_uga insmod video_bochs insmod video_cirrus insmod all_video}load_videoset gfxpayload=keepinsmod gzioinsmod part_gptinsmod ext2set timeout=6menuentry 'Install CentOS Linux 7.8' --class fedora --class gnu-linux --class gnu --class os { linuxefi CentOS-7.8/vmlinuz ip=dhcp inst.ks=http://172.16.22.1:80/supermicro.cfg initrdefi CentOS-7.8/initrd.img}
Legacy 引导
安装 syslinux,把引导程序复制到 TFTP 根目录。
yum -y install syslinuxcp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
创建 pxelinux 的配置文件。
mkdir /var/lib/tftpboot/pxelinux.cfgvim /var/lib/tftpboot/pxelinux.cfg/default
内容如下。
default vesamenu.c32prompt 1timeout 6display boot.msglabel linux menu label ^Install system menu default kernel CentOS-7.8/vmlinuz append initrd=CentOS-7.8/initrd.img ip=dhcp ks=http://172.16.22.1/supermicro.cfg
这里依然能看到 vmlinuz & initrd & ks 熟悉的身影,如需修改可参考上一步说明。
Kickstart
建议先用准备好的镜像在非图形界面下手动安装一台,复制 $HOME 目录下自动生成的anaconda-ks.cfg
脚本作为参考。
下面的脚本中,系统将从网络安装,url
是内网的安装源,rootpw
是 root 用户密码。系统盘是nvme1n1
,使用 LVM,默认分区表。详细的语法说明参见官方文档。
#version=DEVELinstall# System authorization informationauth --enableshadow --passalgo=sha512# Use text mode installtext# Run the Setup Agent on first bootfirstboot --enableignoredisk --only-use=nvme1n1# Keyboard layoutskeyboard --vckeymap=us --xlayouts=''# System languagelang en_US.UTF-8# Use network installationurl --url="http://172.16.22.1/CentOS-7.8"# Reboot after installationreboot# Network informationnetwork --bootproto=dhcp --device=eno1 --onboot=off --ipv6=auto --no-activatenetwork --bootproto=dhcp --device=eno2 --onboot=off --ipv6=autonetwork --bootproto=static --device=enp33s0 --onboot=yes --ip 172.16.1.10 --netmask 255.255.0.0 --gateway 172.16.255.254 --ipv6=auto --nameserver 114.114.114.114# Firewall configurationfirewall --disable#Root passwordrootpw --plaintext "123@def"# SELinux configurationselinux --disabled# System servicesservices --enabled="chronyd"# Do not configure the X Window Systemskipx# System timezonetimezone Asia/Shanghai --isUtc# System bootloader configurationbootloader --append=" crashkernel=auto" --location=mbr --boot-drive=nvme1n1autopart# Partition clearing informationclearpart --all --initlabel --drives=nvme1n1%packages@corechronykexec-tools%end%addon com_redhat_kdump --enable --reserve-mb='auto'%end%anacondapwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notemptypwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyokpwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty%end
开始安装
通过 BIOS 或 IPMI,将机器首选启动项改为 PXE,重启机器就能看到 CentOS 的安装程序,无需操作,等待安装失败完成(ε = = (づ′▽`)づ