PXE网络启动安装操作系统

DHCP+TFTP

dnsmasq 是一个轻量级的 DNS 转发器和 DHCP 服务器。主要功能:

  • DNS 转发dnsmasq 可以作为 DNS 服务器,将 DNS 请求转发到上游 DNS 服务器,并将结果缓存以提高解析速度。

  • DHCP 服务dnsmasq 可以提供 DHCP 服务,为网络中的设备分配 IP 地址、子网掩码、网关和 DNS 服务器等信息。

  • TFTP 服务dnsmasq 可以提供简单的 TFTP 服务,用于文件传输。

yum安装

1
2
3
4
5
# 安装
yum install dnsmasq

# 启动
systemctl start dnsmasq

配置

配置文件地址 /etc/dnsmasq.conf

  • DHCP
1
2
3
4
5
# DHCH
interface=eth1
dhcp-range=192.168.100.50,192.168.100.150,12h
dhcp-option=3,192.168.100.1
dhcp-authoritative

interface 指定DHCP和DNS服务监听的网络接口

dhcp-range 定义DHCP 地址池的范围和租约

dhcp-option 3 表示设置默认网关

dhcp-authoritative dnsmasq将覆盖网络中其他 DHCP 服务器的配置

  • DNS
1
2
3
port=53
dhcp-option=6,192.168.100.2
address=/boot.erhuoyan.com/192.168.100.2

port DNS服务监听的端口号

dhcp-option 6 表示设置DNS服务器

address 配置域名解析

  • 根据客户端特征设置标签

用于pxe引导服务,根据客户端发送的DHCP标志,设置标签。 客户端不同的架构会使用相应的标签

RFC 4578

PixPin_2024-11-21_20-33-31

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
dhcp-match=set:ipxe,175
dhcp-match=set:bios,option:client-arch,0
dhcp-match=set:ia32-efi,option:client-arch,6
dhcp-match=set:x64-efi,option:client-arch,7
dhcp-match=set:x64-efi,option:client-arch,9

# RFC4758中没有规定,网上有人抓包分析得出的
# kunpeng 920 (aarch64) UEFI 模式下为11
dhcp-match=set:arm64-efi,option:client-arch,11

# 配置BIOS引导服务
dhcp-boot=tag:!ipxe,tag:bios,bios/undionly.kpxe
# 配置x86 64位EFI引导服务
dhcp-boot=tag:!ipxe,tag:x64-efi,efi64/ipxe.efi
# 配置ARM 64位EFI引导服务
# dhcp-boot=tag:!ipxe,tag:arm32-efi,efiarm/ipxe.efi
dhcp-boot=tag:!ipxe,tag:arm64-efi,efiarm/ipxe.efi

dhcp-boot=tag:ipxe,memu/boot.ipxe
  • TFTP
1
2
enable-tftp
tftp-root=/pxe/ipxe

tftp-root tftp根目录

  • LOG
1
2
log-queries
log-facility=/pxe/log/dnsmasq/dnsmasq.log

log目录

dnsmasq启动之后,为eth1所在内网环境同时提供DHCH、TFTP和DNS服务。内网机器启动后将自动分配192.168.100.50,192.168.100.150之间的IP地址。同时访问boot.erhuoyan.com将被解析到192.168.100.2,用于HTTP访问。

HTTP

使用nginx提供HTTP文件服务

安装

1
yum install nginx

配置

/etc/nginx/nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
user root;
worker_processes auto;
error_log /pxe/log/nginx/error.log;
pid /pxe/log/nginx/nginx.pid;

events {
worker_connections 1024;
}

http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /pxe/log/nginx/access.log main;

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;

include /pxe/conf/nginx/mime.types;
default_type application/octet-stream;

server {
listen 80;
listen [::]:80;
server_name _;

root /pxe/http;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;
}
}

ipxe

iPXE 是一个开源的网络启动固件,它扩展了传统 PXE 的功能,提供了更多的网络启动选项和功能。iPXE 可以用于从网络启动操作系统、运行虚拟机、访问网络存储等。支持定制化编译,diy启动固件。

ipxe

官方固件

undionly.kpxe bios引导固件

snponly.efi ipxe.efi uefi引导固件

官方有arm64引导固件 因为暂时没有arm环境没有测试

官方编译的固件不支持console命令,无法定制启动console背景和分辨率等,可手动编译

boot.ipxe

ipxe的启动脚本,这里可以配置启动参数和菜单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!ipxe

set http_server boot.erhuoyan.com
console --picture http://${http_server}/template/bootbg.png

:start
menu Welcome to iPXE's Boot Menu

item --gap -- ------------------------- Install CentOS Linux ----------------
item install_c82 Install CentOS Linux 8
item install_c82_with_ks Install CentOS Linux 8 with Kickstart

item --gap -- ------------------------- Install Kylin Linux V10 SP2----------
item install_k2x86 Install Kylin Linux V10 SP2 X86_64
item install_k2arm Install Kylin Linux V10 SP2 ARM64

item --gap -- ------------------------- Install Kylin Linux V10 SP3----------
item install_k3x86 Install Kylin Linux V10 SP3 X86_64

item --gap -- ------------------------- Other Options -----------------------
item --key l local [L] Boot from local disk
item --key r reboot [R] Reboot the Computer
item --key x exit [X] Exit to BIOS

choose --default local --timeout 30000 option && goto ${option}

:install_c82
set base http://${http_server}/centos/82
kernel ${base}/repo/images/pxeboot/vmlinuz
initrd ${base}/repo/images/pxeboot/initrd.img
chain vmlinuz initrd=initrd.img net.ifnames=0 biosdevname=0 inst.repo=${base}/repo
#sanboot http://${http_server}/centos/82/iso/CentOS-8.2.2004-x86_64-dvd1.iso
boot || goto failed
goto start


:install_c82_with_ks
set base http://${http_server}/centos/82
kernel ${base}/repo/images/pxeboot/vmlinuz
initrd ${base}/repo/images/pxeboot/initrd.img
chain vmlinuz initrd=initrd.img net.ifnames=0 biosdevname=0 inst.repo=${base}/repo inst.ks=${base}/kscfg/ks.cfg
boot || goto failed
goto start

:install_k2x86
set base http://${http_server}/kylin/v10sp2_x86
kernel ${base}/repo/images/pxeboot/vmlinuz
initrd ${base}/repo/images/pxeboot/initrd.img
chain vmlinuz initrd=initrd.img biosdevname=0 net.ifnames=0 inst.repo=${base}/repo inst.ks=${base}/kscfg/ks.cfg
boot || goto failed
goto start

:install_k2arm
set base http://${http_server}/kylin/v10sp2_arm64
kernel ${base}/repo/images/pxeboot/vmlinuz
initrd ${base}/repo/images/pxeboot/initrd.img
chain vmlinuz initrd=initrd.img net.ifnames=0 biosdevname=0 inst.repo=${base}/repo
boot || goto failed
goto start

:install_k3x86
set base http://${http_server}/kylin/v10sp3_x86
kernel ${base}/repo/images/pxeboot/vmlinuz
initrd ${base}/repo/images/pxeboot/initrd.img
chain vmlinuz initrd=initrd.img net.ifnames=0 biosdevname=0 inst.repo=${base}/repo
boot || goto failed
goto start

:local
sanboot --no-describe --drive 0x80

:reboot
reboot

:exit
exit

:failed
echo Booting failed, dropping to shell
goto start

详细脚本参数可参考官方文档ipxe cmd

某些命令官方固件不支持需要编译

kickstart

centos8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
text

# Clear MBR
zerombr

# 分区 /boot /boot/efi /
%include /tmp/partation.ks

part /boot --fstype="xfs" --size=1024
part /boot/efi --fstype="vfat" --size=1024
part pv.01 --fstype="lvmpv" --grow
volgroup vg_root --pesize=4096 pv.01
logvol / --fstype="xfs" --percent=100 --name=root --vgname=vg_root

# Use CDROM installation media
#cdrom
url --url=http://boot.erhuoyan.com/centos/82/repo

# Keyboard layouts
keyboard --xlayouts='us'

# System language
lang en_US.UTF-8

# System timezone
timezone Asia/Shanghai --utc --nontp

# Disable SELinux
selinux --disabled

# Disable Firewall
firewall --disabled

# Network information
network --device=link --bootproto=dhcp --onboot=yes --noipv6 --hostname=node1

# Accept EULA
eula --agreed

# Reboot after installation
reboot

# Root password
rootpw --iscrypted $1$9sE5T..b$RL5rayCC95V.XketRo2640

# Run the Setup Agent on first boot
firstboot --disable

# Do not configure the X Window System
skipx

# System services
services --disabled="chronyd"

%packages
@^minimal-environment
#@development
#kexec-tools
wget

%end

%addon com_redhat_kdump --enable --reserve-mb='auto'
%end

%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end

# 自动选择最接近指定大小的盘
%pre
target_size=40 # GB

best_disk=""
best_diff=999999999

for disk in $(ls /sys/block | grep sd); do
size=$(cat /sys/block/$disk/size)
size=$((size * 512 / 1024 / 1024 / 1024)) # Convert to GB
diff=$((size - target_size))
if [ $diff -lt 0 ]; then
diff=$((-diff))
fi
if [ $diff -lt $best_diff ]; then
best_diff=$diff
best_disk=$disk
fi
done

echo "Selected disk: /dev/$best_disk"

echo bootloader --location=mbr --driveorder=$best_disk >> /tmp/partation.ks
echo ignoredisk --only-use=$best_disk >> /tmp/partation.ks
echo clearpart --all --initlabel >> /tmp/partation.ks

%end

# Post-installation script (chroot)
%post
ingect_url=http://192.168.100.2/centos/82/inject
repo_url=http://192.168.100.2/centos/82/repo

mkdir -p /localrepo
# 把iso中的文件都wget到/localrepo
wget -r -np -nH --cut-dirs=3 --reject='index.html*' -P /localrepo http://boot.erhuoyan.com/centos/82/repo/

echo > /etc/motd && echo > /etc/issue && echo > /etc/issue.net

mkdir -p /etc/yum.repos.d/bak
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/
cat > /etc/yum.repos.d/local.repo <<EOF
[AppStream]
name=AppStream
baseurl=file:///localrepo/AppStream
enabled=1
gpgcheck=0

[BaseOS]
name=BaseOS
baseurl=file:///localrepo/BaseOS
enabled=1
gpgcheck=0
EOF

yum install -y bash* vim
%end

编译支持自定义背景

参考

  • 安装编译环境
1
dnf install gcc binutils make perl xz-devel mtools genisoimage syslinux -y
  • 获取源码
1
git clone https://github.com/ipxe/ipxe.git
  • 修改config/general.h

仅支持png格式图片

PixPin_2024-11-22_13-30-55

PixPin_2024-11-22_13-29-49

  • 修改config/console.h

PixPin_2024-11-22_13-37-16

  • make

在src目录下执行

1
2
3
4
# bios 固件
make -j16 bin/undionly.kpxe
# x86 efi固件
make -j16 bin-x86_64-efi/ipxe.efi

在x86机器上编译arm固件需要交叉编译环境

  • 交叉编译

gcc-linaro-11.3.1-2022.06-x86_64_aarch64-linux-gnu.tar.xz

下载解压后添加到环境变量

1
2
3
4
export PATH=/opt/linaro/bin:$PATH

# 编译arm64 efi固件 //还没测试过
make -j16 CROSS=aarch64-linux-gnu- bin-arm64-efi/ipxe.efi

迁移

打包的根目录为/pxe,其他机器上安装也在该目录

目录结构

log 日志目录

script 脚本工具

start_pxe.sh stop_pxe.sh 启动和停止脚本。自动执行挂载iso、启动dnsmasq和caddy

PixPin_2024-11-22_10-20-51

  • conf

配置文件目录

PixPin_2024-11-22_10-29-32

  • http

http 文件服务器根目录

PixPin_2024-11-22_10-22-27

iso 存放iso镜像文件

repo iso挂载点

kscfg ks文件地址

inject 需要传入操作系统的文件,在ks文件中wegt获取

mount_iso.sh umount_iso.sh 挂载卸载脚本

  • install

可执行文件

PixPin_2024-11-22_10-30-10

  • ipxe

TFTP根目录所指路径/pxe/ipxe就是这里

boot.ipxe 是引导菜单

PixPin_2024-11-22_10-21-32

dnsmasq

  • 下载源码包

dnsmasq-2.90.tar.gz

  • 修改Makefile

指定安装位置

PixPin_2024-11-22_10-19-14

1
2
make -j 4
make install
  • 配置文件

/pxe/conf/dnsmasq/dnsmasq.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# DHCH
filterwin2k
interface=eth1
dhcp-range=192.168.100.50,192.168.100.150,12h
dhcp-option=3,192.168.100.1
dhcp-authoritative

# DNS
port=53
dhcp-option=6,192.168.100.2
#listen-address=192.168.100.2
address=/boot.erhuoyan.com/192.168.100.2

# 根据客户端特征设置标签
dhcp-match=set:ipxe,175
dhcp-match=set:bios,option:client-arch,0
dhcp-match=set:ia32-efi,option:client-arch,6
dhcp-match=set:x64-efi,option:client-arch,7
dhcp-match=set:arm32-efi,option:client-arch,9
dhcp-match=set:arm64-efi,option:client-arch,11

# 配置BIOS引导服务
dhcp-boot=tag:!ipxe,tag:bios,bios/undionly.kpxe
# 配置x86 64位EFI引导服务
dhcp-boot=tag:!ipxe,tag:x64-efi,efi64/ipxe.efi
# 配置ARM 64位EFI引导服务
dhcp-boot=tag:!ipxe,tag:arm32-efi,efiarm/ipxe.efi
dhcp-boot=tag:!ipxe,tag:arm64-efi,efiarm/ipxe.efi

dhcp-boot=tag:ipxe,memu/boot.ipxe

# TFTP
enable-tftp
tftp-root=/pxe/ipxe

# LOG

log-queries
log-facility=/pxe/log/dnsmasq/dnsmasq.log

Caddy

可以选择手动编译nginx,最终选择使用caddy官网可直接下载可执行文件

  • 配置文件

/pxe/conf/caddy/Caddyfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
# 全局配置
admin :2019
log {
level debug
output file /pxe/log/caddy/access.log {
roll_size 100mb
roll_keep 10
roll_keep_for 720h
}
}
}

:80 {
root * /pxe/http
#header Accept-Ranges bytes
file_server browse
encode gzip
log {
output file /pxe/log/caddy/access.log {
roll_size 100mb
roll_keep 10
roll_keep_for 720h
}
}
handle_errors {
@404 {
expression {http.error.status_code} == 404
}
handle @404 {
rewrite * /404.html
file_server
}
}
}

部署

pxe服务端

在vbox中搭建一台pxe服务器

  • 重要

pxe服务的网络接口使用桥接,桥接到本机电脑的板载网口。使用这个网口连接物理机,可以为物理机提供pxe服务。

系统关闭selinux和防火墙!!!

PixPin_2024-11-22_11-06-53

  • 部署步骤
  1. 将pxe.tar.gz解压到目标系统/pxe目录

  2. 配置dhcp服务器ip,如将eth1配置静态ip192.168.100.2

PixPin_2024-11-22_10-41-41

  1. 修改dnsmasq配置文件中的网络接口和ip

PixPin_2024-11-22_10-48-58

  1. 打包时会排除iso镜像文件,所以要把iso文件拷贝到相应目录

PixPin_2024-11-22_10-50-16

  1. 定制修改boot.ipxe (可选)

PixPin_2024-11-22_10-55-25

  1. 定制修改ks.cfg (可选)

  2. 执行启动脚本start_pxe.sh

pxe客户端(需要安装系统的机器)

PixPin_2024-11-22_11-30-43

PixPin_2024-11-22_11-47-51

测试

  • 启动

PixPin_2024-11-22_12-42-10

  • DHCP正常启动ipxe

PixPin_2024-11-22_13-19-39

  • diy菜单

PixPin_2024-11-22_13-19-58

  • ks自动化安装

PixPin_2024-11-22_13-22-12


PXE网络启动安装操作系统
https://blog.erhuoyan.cn/2024/11/18/32176f686225/
作者
erhuoyan
发布于
2024年11月18日
许可协议