PXE 技术:PXE 自动装机技术分享

1,987 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情

一、PXE

1. 概述

  • PXE (Preboot eXecution Environment)也叫预启动执行环境,由 intel 和 systemsoft 提出规范并进行描述,提供了用网络接口(NIC)来引导计算机启动的机制,能够不依赖本地存储设备,比如硬盘或本地已安装的系统。
  • PXE 环境使用多种 C/S 架构协议,如 DHCP 和 TFTP。
    • PXE 客户端程序,由 NIC 网卡固件实现,提供基本的通用网络设备接口 (UNDI)、简约的 UDP/IP 堆栈、预引导 (DHCP) 客户端模块和 TFTP 客户端模块,共同形成 PXE 应用程序编程接口( APIs)。在与 PXE 服务端交互时,由 NBP(Network Bootstrap Program,网络引导程序,也叫 bootloader)使用。

2. PXE 架构

  • PXE 客户端:即 PXE client,指需要通过网络接口引导启动的服务器主机,需要网卡固件支持 PXE 引导启动。
  • PXE 服务端:即 PXE server,指提供 DHCP、TFTP 服务端的服务器主机,同时也要提供 NBP 程序(也叫 bootloader)以及其他引导启动相关的软件或文件包。

3. PXE 服务端组件

  • DHCP 服务

    • 使用 DHCP 动态主机设置协议,在 PXE 环境中的主要功能是为 PXE 客户端自动分配 IP 地址,并告知其 TFTP 服务端的 IP 地址。
    • 端口号:服务端 67/UDP,客户端 68/UDP
  • TFTP 服务

    • 使用 TFTP 普通文件传输协议,主要功能是允许客户端从 PXE 服务端下载文件(如,bootloader、内核及内存文件系统镜像等等)
    • 端口号:69/UDP
  • NBP 网络引导程序

    • 也叫 bootloader 引导加载程序,主要功能有提供引导菜单的扩展功能、脚本功能,加载 kernel 内核、解压 initramfs 内存文件系统等功能。
    • 常见的 NBP 程序:
      • SYSLINUX 的 PXELINUX
      • GRUB2
      • iPXE

二、引导启动流程

1. 硬盘引导启动流程

CentOS7系统引导启动示意图.png

  1. 电源启动
  2. CPU 从 ROM 中执行 BIOS。
  3. BIOS 执行 POST 开机自检,确认启动顺序,读取 MBR 信息,激活引导加载程序(bootloader 第一阶段)。
  4. 引导加载程序,查询分区表,从可引导分区加载 GRUB2 到 RAM 中执行(bootloader 第一阶段)。
  5. GRUB2 提供内核选择菜单及内核启动参数,加载 kernel 内核镜像,解压 initramfs 内存文件系统到 RAM ,移交控制权给内核(bootloader 第二阶段)。
  6. 内核 Kernel 侦测硬件,通过 initramfs 内存文件系统加载驱动,切换挂载实际根文件系统,运行 Systemd 。
  7. Systemd 根据 default.target 执行系统启动流程。

2. PXE 引导启动流程

以主板固件为 BIOS,Bootloader 为 pxelinux 举例: PXE引导启动流程.png

  1. 电源启动
  2. CPU 从 ROM 中执行 BIOS。
  3. BIOS 执行 POST 开机自检,确认引导启动顺序,加载 PXE Client的网卡固件系统。
  4. PXE Client,发送广播请求,向网络中的 DHCP 服务器申请 IP 。
  5. DHCP 服务器,验证 PXE Client 请求,为 Client 分配 IP 地址,并提供 Bootloader 文件位置(告知其 TFTP 服务端 IP 地址 + Bootloader filename)。
  6. PXE Client 请求下载 pxelinux.0(Bootloader),并加载到 RAM 中执行。
  7. pxelinux.0 请求下载 pxelinux.cfg 相关配置文件,并根据规定顺序进行读取。
  8. pxelinux.0 提供内核选择菜单(如果有)及内核启动参数,加载 kernel 内核镜像,解压 initramfs 内存文件系统到 RAM ,移交控制权给内核。
  9. 内核根据启动参数,下载和读取自动应答文件 ks.cfg,然后执行自动安装流程。
  10. 安装完成后,系统自动重启。

提示:如何主板固件系统是 UEFI,区别就是将 Bootloader 替换成 syslinux.efi 来支持此模式引导,并在 DHCP 服务器配置中修改 filename。

三、PXE 技术应用

参考文章

Server 端组件配置说明

以主板固件为 BIOS,Bootloader 为 pxelinux,系统版本为 CentOS 7 举例:

PXE 软件包安装

$ yum -y install xinetd syslinux dhcp tftp-server httpd rsync

DHCP 服务也可以使用 dnsmasq

DHCP

  1. dhcpd 配置文件
$ cp /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.bak 
$ cat > /etc/dhcp/dhcpd.conf <<EOF 
ddns-update-style none;
subnet 192.168.3.0 netmask 255.255.255.0 {				# 子网及掩码
     option routers             192.168.3.1;
     option domain-name-servers 192.168.3.10;				# 路由网关
     option subnet-mask         255.255.255.0;
     range dynamic-bootp        192.168.3.100 192.168.3.254;            # dhcp地址池范围
     default-lease-time         21600;
     max-lease-time             43200;
     next-server                192.168.3.10;				# tftp 地址
     class "pxeclients" {
          match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
          if option pxe-system-type = 00:00 {
                  filename "pxelinux.0";				# 网络引导程序(bios)
          } else {
                  filename "syslinux.efi";                              # 网络引导程序(uefi)
          }
     }
}
EOF

$ systemctl start dhcpd
$ systemctl enable dhcpd
  1. Dnsmasq 配置文件
# config dnsmasq
# [log]
log-queries
log-facility=/var/log/dnsmasq.log
log-async=20

# [tftp]						# 提供 tftp 服务,无需单独安装
enable-tftp
tftp-root=/tftpboot

# [dhcp]
dhcp-hostsdir=/etc/dnsmasq_client
interface=ens34                         # 配置 DHCP 的网卡接口
bind-interfaces
listen-address=10.0.0.5,127.0.0.1
dhcp-range=10.0.0.100,10.0.0.200,255.255.255.0,24h
dhcp-lease-max=1000
dhcp-authoritative
dhcp-option=3,10.0.0.1			# 3 = router 网关地址 (参数号与参数名对应关系见下表)
dhcp-option=6,10.0.0.5			# 6 = dns 服务器地址
dhcp-option=66,10.0.0.5			# 66 = tftp 服务器地址

# [pxe path]
# set 可设置 tag,当后面给定数值时,只有当选项被发送并且与值匹配时,才会设置标签
dhcp-match=set:bios,option:client-arch,0			# 0 = Standard PC BIOS(参考RFC 4578 https://www.rfc-editor.org/rfc/rfc4578,本卡片后面也有简略介绍) 
dhcp-boot=tag:bios,pxelinux.0					# 是 bios,用 pxelinux.0
dhcp-boot=tag:!bios,syslinux.efi				# 不是 bios (是 uefi),用 syslinux.efi (syslinux latsest 版本有提供) 
  1. RFC 4578 可用于区分客户端的固件系统是 BIOS 还是 UEFI: DHCP服务器_client架构代码.png

TFTP

  • 安装:
    • CentOS:yum -y install tftp-server xinetd
      • tftp 依赖于 xinetd 服务
    • Ubuntu:apt-get install tftpd-hpa
  • 配置:
# CentOS
$ vim /etc/xinetd.d/tftp
service tftp 
{ 
	socket_type 	= dgram 
	protocol 		= udp 
	wait 			= yes 
	user 			= root 
	server 			= /usr/sbin/in.tftpd 
	server_args 	= -s /var/lib/tftpboot 
	disable 		= no #默认为yes,这里我们将其更改为no 
	per_source 		= 11 
	cps 			= 100 2 
	flags 			= IPv4 
}
$ systemctl restart xinetd

# Ubuntu
$ vim /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/var/lib/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="-l -c -s"
#-c: Allow new files to be created
#-s: Change  root  directory  on startup.
#-l:  Run the server in standalone (listen) mode, rather than run from inetd.
$ systemctl restart tftpd-hpa

PXELINUX

  1. pxelinux.0
# 通过 rpm 安装 syslinux
$ yum -y install syslinux
$ cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
$ cp /usr/share/syslinux/menu.c32 /var/lib/tftpboot/

# 下载指定版本 syslinux 的二进制包
$ wget https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/6.xx/syslinux-6.03.zip
$ unzip -d syslinux syslinux-6.03.zip

## BIOS
$ cp syslinux/bios/core/pxelinux.0 /var/lib/tftpboot/
$ cp syslinux/bios/com32/menu/menu.c32 /var/lib/tftpboot/

## UEFI
$ cp syslinux/efi64/efi/syslinux.efi /var/lib/tftpboot/
$ cp syslinux/efi64/com32/elflink/ldlinux/ldlinux.e64 /var/lib/tftpboot/
$ cp syslinux/bios/com32/menu/menu.c32 /var/lib/tftpboot/
  1. pxelinux.cfg 引导文件选择顺序: pxelinux配置选择顺序2.png

  2. 配置文件解释:

# 使用文本模式的简单菜单系统(vesamenu.c32 为图形)
DEFAULT menu.c32

# 是否等待用户选择:
# "1" 表示等待用户选择,界面会出现"boot: "提示符,用户需敲回车确认。
# "0" 表示直接启动 "default" 参数中指定的内容。
PROMPT 0

# 等待用户输入的超时时间,单位为 1/10 秒,600表示60秒()
TIMEOUT 30

# 指定默认的 label
DEFAULT CentOS-7.5-x86_64

LABEL CentOS-7.5-x86_64
  # 菜单标签名
  MENU LABEL ^CentOS2-7.5-x86_64
  
  # 设置为默认菜单
  MENU DEFAULT

  # 指定内核文件 
  KERNEL vmlinuz
  
  # 指定初始化内存文件系统
  INITRD initrd.img

  # 向内核追加命令行参数(指定内核相关的参数)
  # ks : 指定ks文件位置 (centos or redhat)
  # biosdevname=0 + net.ifnames=0: 让网卡继续使用 eth0 命名
  APPEND ks=http://192.168.3.10/ks.cfg net.ifnames=0 biosdevname=0

  # 指定安装程序应该使用与系统启动时相同的网络接口。
  # 目的是为了让系统启动时用 pxe 网卡作为eth0。
  IPAPPEND 2

MENU end

Kernel + ISO 镜像挂载

# # 挂载镜像(iso镜像需要自己手动上传到服务器)
$ mkdir /var/www/html/centos7
$ mount -o loop /root/CentOS-7-x86_64-DVD-1804.iso /var/www/html/centos7

# # 拷贝 kernel + initrd
$ cp /var/www/html/centos7/os/x86_64/images/pxeboot/{vmlinuz,initrd.img} /var/lib/tftpboot/

# # 启动 httpd 服务
$ systemctl restart httpd
$ systemctl enable httpd

kickstart

#platform=x86, AMD64, or Intel EM64T
#version=CentOS7
# Install OS instead of upgrade #全新安装而不是升级
install
# Keyboard layouts
keyboard 'us'
# Root password
rootpw --iscrypted $1$uMOl6YMI$7AAO8YG7l37ipRXCmmame. #采用加密记录
#rootpw --plaintext 12456 #采用明文记录
# System language
lang en_US
# Firewall configuration #屏蔽防火墙
firewall --disabled
# System authorization information #设定NIS信息
auth  --useshadow  --passalgo=sha512 --enablenis --nisdomain=mydomain.org --nisserver=192.168.100.254
# Use text mode install #安装方式,文本界面,图形的话graphy
text
# SELinux configuration #关闭SELinux
selinux --disabled
# Do not configure the X Window System #不配置X图形界面
skipx

# Use NFS installation media #设定安装方式
# nfs --server=192.168.100.254 --dir=/centos
# Use http installation source
url --url=http://192.168.3.10/centos7/
# Network information #采用DHCP获取IP
network  --bootproto=dhcp --device=eth0 --onboot=on
# Reboot after installation 
#安装后自动重启,如果BIOS中设置从PXE首先启动,那么会重复安装,请注意,安装后应设置为从先硬盘启动
reboot
# System timezone
timezone Asia/Shanghai
# System bootloader configuration
bootloader --location=mbr --append="net.ifnames=0" --boot-drive=sda
# Partition clearing information #清除原有分区
clearpart --all --initlabel
# Disk partitioning information
zerombr
# autopart --type=lvm 自动分区
part / --fstype="xfs" --size=10000
part /boot --fstype="xfs" --size=200
#part /boot/efi --fstype=efi --size=200 #UEFI引导安装时需要,传统LEGACY引导时可屏蔽此选项
part swap --fstype="swap" --size=8000
part /tmp --fstype="xfs" --grow --size=1

%packages #设定所需要的软件包,按需要调整
@base #@表示一组软件包
@network-server
@performance
@system-admin-tools	
@^minimal	# 最小化安装
@core		# 核心软件包
sdparm
tree
tuned
tuned-utils
ypbind
nfs-utils
vim-enhanced
#-表示从默认软件包的需要去除的软件包
-lvm2
-nano
-pcmciautils
-plymouth
-rfkill
-rsync
-system-config-firewall-tui
-system-config-network-tui
-unzip
-vconfig
-wireless-tools
%end #%packages结尾

%pre #预安装脚本,非必须
date
%end #%pre结尾

%post #安装后脚本,非必须
cat >>/root/.bashrc <>/etc/fstab
%end #%post结尾

文件需要放在 /var/www/html 目录下,由 httpd 提供下载服务。

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情