搭建pxe网络批量安装系统环境

dnsmasq+ipxe无人值守批量安装系统

安装脚本

源码在文章底部

1
curl -o ipxe.sh http://xz.itcytblog.cn/ipxe.sh && bash ipxe.sh

简介
PXE (preboot execute environment,预启动执行环境) 是由 Intel 公司设计的协议,它可以使计算机通过网络启动。当计算机引导时,BIOS 把 PXE client 调入内存执行,并显示出命令菜单,经用户选择后,PXE client将放置在远端的操作系统通过网络下载到本地运行。除了可以通过网络直接运行操作系统外,也可以用于通过网络来将系统安装到本地。在运维中工作中,通过 PXE 来为机房服务器批量部署系统是非常方便的。
环境
PXE 对运行环境没有什么需求,只需能提供 tftp, dhcp, http 等服务的系统即可。这里使用 Linux 环境来搭建PXE服务。使用 dnsmasq 这个小巧玲珑的软件提供 tftp 和 dhcp 服务,使用 Nginx 来提供 http 服务。
步骤
PXE 的启动原理是 PXE client 在网卡的 ROM 中,可以在计算机开机的时候选择通过硬盘引导还是 PXE 等引导方式,比如 DELL 的服务器在出现开机 LOGO 画面后通过键入 F12 来进入 PXE 引导,Vmware 新创建的虚拟机在第一次启动的时候如果没有装载光驱或者ISO镜像,则会尝试通过网络引导。如果是笔记本或者台式机可以在开机的时候进入引导菜单,然后选择通过网卡设备启动。
当进入 PXE 引导界面后,PXE client 会向网络中的 dhcp 服务器请求IP地址,dhcp 服务器发现是个 PXE client 的请求会将分配好的IP和引导程序的访问地址返回给 PXE client。这个引导程序一般是名为 pxelinux.0 的文件,这个文件是通过 tftp 协议发送给 PXE client 的。当客户端成功获取到引导文件和引导文件的相关配置文件后就成功加载出引导菜单。这个菜单则是我们通过更改 pxelinux.0 的配置文件来的。下面是通过Vmware引导的效果:

如果在30秒内没做任何选择则默认从本地磁盘启动,这样就避免了某些将PXE启动作为第一启动项的服务器重启后误重装系统。当选择了某个项目的时候,比如 Install CentOS6.8 for vmware 则向服务器获取根据配置文件中指定的 CentOS 内核文件和启动参数。当需要的数据都准备好后,系统则开始启动 Linux 内核,接下来的操作就跟普通的安装系统没两样了,只不过需要的数据都是通过网络获取的。比如安装 CentOS 过程中需要的所有 rpm 包都是通过 http 服务提供的 CentOS 镜像站提供的了。
但是如何通过 PXE 来同时安装成百上千台服务器呢?在安装系统的过程中,总会遇到各种需要交互的地方,比如给硬盘分区,选择语言,创建用户等地方,幸好大部分的系统安装镜像都支持通过 Kickstart 自动应答在安装过程中免人工干预的进行系统安装。就像是你的所有问题的回答我先写成一个文件,然后你需要问的时候先从文件中找答案一样。自动应答文件通常是 ks.cfg 文件,此文件的位置大多通过在启动 Linux 内核的时候通过启动参数的方式告诉内核。
接下来就看看 PXE 启动该如何配置。
服务配置

安装 dnsmasq

可以首先从Linux发行版的官方仓库中找找有没有 dnsmasq 的软件包,如果没有可以下载编译。
编译方法:

1
2
3
4
5
cd /usr/local/src/
wget http://www.thekelleys.org.uk/dnsmasq/dnsmasq-2.79.tar.xz
tar xvf dnsmasq-2.79.tar.xz
cd dnsmasq-2.79 && make
cp src/dnsmasq /usr/local/bin/

只需要将 dnsmasq 的二进制文件放到系统环境变量就可以了,接下来给它提供一个配置文件来告诉它要启动哪些服务。源码目录下有一个官方提供的配置文件模板,不过我们并不需要这么多的配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mkdir -p /data/pxeboot          # PXE启动所需要的文件就都放到这里了
cd /data/pxeboot
vim dnsmasq.conf
然后写入以下内容:
# enable dhcp
dhcp-range=192.168.4.10,192.168.4.200,12h
dhcp-option=3,192.168.4.254
dhcp-option=option:dns-server,114.114.114.114,119.29.29.29
#dhcp-boot=pxelinux.0
dhcp-boot=undionly.kpxe

# disable dns
port=0

# enable tftp
enable-tftp
tftp-root=/data/pxeboot

一定要注意,dhcp-range 给客户端分配的IP地址池一定要是自己网段的。根据前面讲解的 PXE 启动的原理,可能大家会比较好奇,为什么这里 dhcp 推送的是 undionly.kpxe 这个文件呢?这个会在下面讲到,接下来就可以先启动 dnsmasq 了。

1
2
3
4
5
6
dnsmasq -C dnsmasq.conf -d      # 如果不加 -d 参数,dnsmasq 则进入后台运行
[root@localhost pxeboot]# dnsmasq -C dnsmasq.conf -d
dnsmasq: started, version 2.79 DNS disabled
dnsmasq: compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN ......
dnsmasq-dhcp: DHCP, IP range 192.168.4.10 -- 192.168.4.200, lease time 12h
dnsmasq-tftp: TFTP root is /data/pxeboot

现在基础的 dhcp 和 tftp 服务已经搭建完成了,dhcp 监听在 udp 67 端口,tftp 监听在 udp 69,使用前最好关闭服务器的 selinux 和 iptables。
安装 Nginx
也不一定非要使用 Nginx,只要是能提供通过 HTTP 协议对文件进行访问服务的程序都可以,只不过感觉 Nginx 用起来更得心应手一些。同样,如果可以从发行版的官方仓库安装就非常省事了,或者手动编译也可以。
编译方法:

1
2
3
4
5
6
cd /usr/local/src/
wget http://nginx.org/download/nginx-1.14.0.tar.gz
tar xf nginx-1.14.0.tar.gz
cd nginx-1.14.0
./configure --prefix=/usr/local/nginx --without-http_rewrite_module
make -j4 && make install

因为用不到 Nginx 的 rewrite 规则,而且这个模块依赖 pcre 库,所以就去掉了,接下来简单的配置下 Nginx。

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
mkdir -p /data/wwwroot/pxefiles         # /data/wwwroot 作为HTTP根目录
vim /usr/local/nginx/conf/nginx.conf
然后写入以下内容:
worker_processes 4;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
autoindex on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /data/wwwroot;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

/usr/local/nginx/sbin/nginx # 启动Nginx服务

安装 ipxe 引导文件

为什么这里又出现了 ipxe 引导文件呢?理论上来说,只是用 pxelinux.0 确实也可以引导各种系统,但是 pxelinux.0 只支持使用 tftp 协议来加载需要的文件。 tftp 在使用 UDP 传输数据,为了保证文件的完整性,tftp 自己实现了一套数据校验机制,但是却大大降低了文件传输效率。而且某些未知情况下 tftp 在局域网内居然只有 KB 级别的传输速率。于是,一些支持 http 、ftp、nfs 等文件传输协议的引导程序诞生了,ipxe 就是其中一种。
ipxe 提供的引导文件针对不同使用场合又分好几种,比如 .pxe,.kpxe,.kkpxe 格式的引导文件。比较常见的是 .pxe,.kpxe,其中的区别可以看这里:点此打开,这里使用 undionly.kpxe 引导文件,采用链式加载的方法加载 pxelinux.0。这样就可以实现既使用 ipxe 提供的网络协议支持,还可以使用 pxelinux.0 提供的引导界面了。
编译 undionly.kpxe:

1
2
3
4
5
6
7
8
9
10
11
cd /usr/local/src/
git clone git://git.ipxe.org/ipxe.git
cd ipxe/src
vim embed.ipxe
写入如下内容:
#!ipxe
dhcp
chain tftp://${next-server}/menu.ipxe
其中 ${next-server} 会自动解析为 dhcp 服务器的地址,tftp 也搭建在这个地址上。当通过 dhcp 获取到IP地址后,通过 tftp 协议请求 menu.ipxe 文件,然后 ipxe 会解析和执行文件里的内容,这个文件可以说就是 ipxe 的配置文件了。接着编译出 undionly.kpxe,这样 undionly.kpxe 才会默认就加载同目录下的 menu.ipxe 文件了。
make bin/undionly.kpxe EMBED=embed.ipxe
cp bin/undionly.kpxe /data/pxeboot/

其中编译步骤需要 lzma.h 这个头文件,需要安装你的发行版上提供这个头文件的软件包。编译好的 undionly.kpxe 可以保存下来下次搭建环境的时候直接用,如果服务是搭建在 Windows 系统上也可以使用这个编译好的文件。
然后编辑 menu.ipxe 文件,配置接下来的文件都通过 http 协议来访问,并且链接到 pxelinux.0。

1
2
3
4
5
6
vim /data/pxeboot/menu.ipxe
写入如下内容:
#!ipxe
set 210:string http://192.168.4.6/pxefiles/
set 209:string pxelinux.cfg/default
chain ${210:string}pxelinux.0

其中 set 210:string 定义了请求的文件的主目录,因为之前创建的 /data/wwwroot/ 为 http 的根目录,/data/wwwroot/pxefiles/ 目录中存放 pxelinux.0 相关的数据文件。其中的服务器IP地址需要替换为你实际的服务器IP。
set 209:string 则定义了 pxelinux.0 直接加载 pxelinux.cfg/default 这个配置文件,否则 pxelinux.0 会阶梯性的查找配置文件,如果都没找到最后默认才加载 pxelinux.cfg/default。
安装 pxelinux.0 引导文件
接下来的操作就是在 /data/wwwroot/pxefiles/ 目录下进行了,因为 ipxe 启动后剩下的文件都是通过 http 协议访问的。
pxelinux.0 可以通过发行版的 syslinux 包来获取,或者自己从官方下载也可,这里采用从官方下载的方式。

1
2
3
4
5
6
7
8
9
10
cd /usr/local/src/
wget https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/Testing/3.86/syslinux-3.86-pre4.tar.xz
tar xvf syslinux-3.86-pre4.tar.xz
cd syslinux-3.86-pre4
cp com32/menu/vesamenu.c32 /data/wwwroot/pxefiles/
cp core/pxelinux.0 /data/wwwroot/pxefiles/
cp memdisk/memdisk /data/wwwroot/pxefiles/
syslinux 最新版是16年发布的 6.04,但是使用中发现无法引导 ESXI,而且 pxelinux.0 引导后还要加载好几个 .c32 文件,所以采用老一点的 3.86 版本。 接着给 pxelinux.0 提供配置文件
cd /data/wwwroot/pxefiles/
mkdir pxelinux.cfg

vim pxelinux.cfg/default
写入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
default vesamenu.c32
timeout 300

menu title Welcome to PXE server!
menu background splash.jpg
menu color border 0 #ffffffff #00000000
menu color sel 7 #ffffffff #ff000000
menu color title 0 #ffffffff #00000000
menu color tabmsg 0 #ffffffff #00000000
menu color unsel 0 #ffffffff #00000000
menu color hotsel 0 #ff000000 #ffffffff
menu color hotkey 7 #ffffffff #ff000000
menu color scrollbar 0 #ffffffff #00000000

label local
menu label Boot from local drive
menu default
localboot 0xffff

这里为了界面美观使用了一张背景图片: splash.jpg,图片需要是一张 640*480 像素的 jpg 图片,并根据图片的主题颜色调整下页面边框、文字等颜色,如果不需要使用背景图片的话可以将 menu background 和 menu color 的配置项都删掉或者注释掉。
其中 timeout 300 会在引导界面30秒无操作就就启动下面 label 中定义为 menu default 的条目。到这一步已经可以尝试将虚拟机或者主机通过 PXE 启动,看看是否可以加载出引导界面了。

接下来,试试通过 PXE 实际启动或安装一些系统吧!
网络启动
即使是通过网络安装,也是需要系统的镜像包的。最好先将需要安装的系统的镜像下载到本地,当然如果对自己网速很自信的话是可以直接通过公网来安装系统的(方法见附录)。

安装 CentOS

下载系统镜像
下载最新的CentOS镜像可以去官网或者国内的镜像站找,旧版本的可以在官网里找到。或者一个简单的方法,http://mirror.nsc.liu.se/centos-store/6.8/isos/x86_64/ 把其中的6.8改为相应的版本号就可以了。
这里使用和机房服务器系统版本一致的 CentOS 6.8 镜像,如果只是想安装一个最小化的 CentOS 系统的话,选择 minimal.iso,而如果想安装带桌面的甚至想搭建一个本地的yum源,就使用 bin-DVD1.iso 和 bin-DVD2.iso 这两个镜像。其中 bin-DVD2.iso 不可用于系统安装,因为里面只是额外的RPM包,搭建 yum源的话可以将两个镜像的内容合并到一个目录中。还有个是 LiveCD.iso 或者 LiveDVD.iso 的镜像,这种镜像可以直接刻录到光盘并从光盘启动系统。
这里直接使用 bin-DVD 的镜像。
配置安装源
首先将 bin-DVD1.iso 和 bin-DVD2.iso 的内容合并到一个目录中

1
2
3
4
5
6
7
8
mkdir -p /data/wwwroot/yum/CentOS6.8/ 
mount -o loop CentOS-6.8-x86_64-bin-DVD1.iso /mnt/
cp -rf /mnt/* /data/wwwroot/yum/CentOS6.8/
umount /mnt/
mount -o loop CentOS-6.8-x86_64-bin-DVD2.iso /mnt/
cp -rf /mnt/* /data/wwwroot/yum/CentOS6.8/ # 所有同名文件都覆盖掉
umount /mnt/
ln -s /data/wwwroot/yum/ /data/wwwroot/pxefiles/yum

这里创建了一个软链接的原因是 menu.ipxe 中定义为pxe主目录在 /data/wwwroot/pxefiles/ 中。
准备自动应答文件
每次安装完 CentOS 的系统后不知道大家是否有留意root用户家目录下的三个文本文件 anaconda-ks.cfg,install.log,install.log.syslog。其中 anaconda-ks.cfg 就是系统安装过程中的所有问答产生的 ks.cfg 自动应答文件,这个是可以直接拿来用的。
如果这个文件被删除了,那么也可以通过软件包 system-config-kickstart 来定制,此工具需要在图形化界面下或者配置好了X11转移的环境中使用。使用 yum -y install system-config-kickstart 安装后使用 system-config-kickstart 运行程序。

配置好后使用 Ctrl+S 保存并退出,将制作好的 ks.cfg 文件或者 anaconda-ks.cfg 复制到刚才创建的yum源中。因为不同的主机类型可能对应着不同的自动应答文件,所以可以保存为针对不同安装类型或平台的自动应答文件。

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
cp /root/anaconda-ks.cfg /data/wwwroot/yum/CentOS6.8/ks-minimal-vmware.cfg
ks-minimal-vmware.cfg 文件内容为:
install
reboot
text
url --url=http://192.168.4.6/yum/CentOS6.8
lang zh_CN.UTF-8
keyboard us
network --onboot yes --device eth0 --mtu=1500 --bootproto dhcp --noipv6
# root passwd : 123456
rootpw --iscrypted $6$5dCFp4Me$YkPWb8h0M/wRUPH3puKXcmbhsErJxfFPCXTtIzfglpfHriMBJsRtqjS5Ewh6Vj/h3mnRdXfsAGcadD3TpRAlk1
firewall --service=ssh
authconfig --enableshadow --passalgo=sha512
selinux --disabled
timezone --utc Asia/Shanghai
bootloader --location=mbr --driveorder=sda --append="crashkernel=auto rhgb rhgb quiet quiet"
zerombr
clearpart --all --drives=sda
part /boot --fstype=ext4 --size=500
part swap --size=2048
part / --fstype=ext4 --grow --size=1
repo --name="CentOS" --baseurl=http://192.168.4.6/yum/CentOS6.8 --cost=100
%packages
@Base
@Core
%post
cd /etc/yum.repos.d/
mkdir bak
mv * bak
cat >> CentOS-Base.repo <<END
[base]
name=CentOS-$releasever Base
baseurl=http://192.168.4.6/yum/CentOS6.8
enabled=1
gpgcheck=0
END
yum update
yum -y install lrzsz

其中配置了 root 密码为 123456,只安装了最基础的软件包。在安装完之后自动配置系统的yum源到本地服务器上,并且安装 lrzsz 工具包。这里密码是通过加密后的,也可以直接使用 rootpw 123456 这种方式。其中 reboot 会在安装完成后自动重启。
添加PXE启动项
该为 pxelinux.0 添加 CentOS6.8 的启动项了,编辑 pxelinux.cfg/default,在 label local 前添加如下配置块:

1
2
3
4
label centos6.8
menu label Install CentOS6.8 for vmware (minimal install)
kernel /yum/CentOS6.8/images/pxeboot/vmlinuz
append initrd=/yum/CentOS6.8/images/pxeboot/initrd.img ks=http://192.168.4.6/yum/CentOS6.8/ks-minimal-vmware.cfg ksdevice=eth0

kernel 和 initrd 可以使用文件对于URL的相对路径,加载的内核也是 CentOS 镜像中提供的支持PXE启动的内核文件。ks 是传给内核的参数,制定了自动应答文件的位置。内核启动后就不是由PXE控制网卡了,就无法使用相对路径的方式获取文件,所以自动应答文件要使用全路径。ksdevice 在单网卡的情况下可以不指定,如果是多网卡的服务器不指定 ksdevice 的话,安装过程则会停在让你手动选择要使用的网卡界面。
开始安装
再次进入PXE引导界面,可以看到刚才新加的启动项生效了,接着选择它并回车。

可以看到剩下的过程根本没有人工干预就安装完成了。

安装完成后会自动重启。

安装 Ubuntu

下载系统镜像
镜像可以从Ubuntu官网下载,也可以在中科大或其他的国内开源镜像站中下载。点此打开
这里使用 ubuntu-16.04.4-server-amd64.iso 这个镜像,最新的 ubuntu-18.04 并没有经过测试,不知道是否还能用此方法进行安装。
配置安装源
同理将镜像解压到web目录。

1
2
3
4
5
mkdir -p /data/wwwroot/apt/ubuntu16.04
mount -o loop ubuntu-16.04.4-server-amd64.iso /mnt/
cp -rf /mnt/* /data/wwwroot/apt/ubuntu16.04
umount /mnt/
ln -s /data/wwwroot/apt/ /data/wwwroot/pxefiles/apt

准备自动应答文件
也可以在 ubuntu 上使用 system-config-kickstart 工具来制作自动应答文件,使用前先安装:apt install system-config-kickstart。ubuntu 的自动应答文件不可以和 CentOS 的通用。
vim /data/wwwroot/apt/ubuntu16.04/ks-server-vmware.cfg
文件内容如下:

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
lang en_US
langsupport en_US
keyboard us
mouse
timezone Asia/Shanghai
rootpw --disabled
# ubuntu password: 123456
user ubuntu --fullname "ubuntu" --iscrypted --password $1$4C9x9TxO$PfPaSIUWQwN80J0MtEyQ3.
reboot
text
install
url --url http://192.168.4.6/apt/ubuntu16.04/
bootloader --location=mbr
zerombr yes
clearpart --all --initlabel
part / --fstype ext4 --size 1 --grow
part swap --size 2048
auth --useshadow --enablemd5
network --bootproto=dhcp --device=eth0
firewall --disabled
skipx
%packages
@^minimal
@core
openssh-server

其中新建了一个叫 ubuntu 的用户,用户密码是 123456。默认没有配置root用户的密码,可以使用普通用户登陆后使用 sudo 来切换到 root 用户。ubuntu 默认是不允许 root 用户登陆的,需要修改 /etc/ssh/sshd_config 中的 PermitRootLogin 为 yes。
添加PXE启动项
编辑 pxelinux.cfg/default 添加如下 label 块:

1
2
3
4
label ubuntu server 16.04
menu label Install Ubuntu server 16.04.4 (minimal install)
kernel /apt/ubuntu16.04/install/netboot/ubuntu-installer/amd64/linux
append initrd=apt/ubuntu16.04/install/netboot/ubuntu-installer/amd64/initrd.gz ks=http://192.168.4.6/apt/ubuntu16.04/ks-server-vmware.cfg --- live-installer/net-image=http://192.168.4.6/apt/ubuntu16.04/install/filesystem.squashfs

开始安装
安装完成后会自动重启。

安装 ESXI

下载系统镜像
在官网下载需要登陆,官方下载地址。如果是用于服务器安装,那最好找找有没有服务器官方提供的针对服务器硬件的 ESXI 版本,比如戴尔官方提供的定制版 ESXI 戴尔官方下载地址
这里使用戴尔官方提供的 VMware ESXi 5.5 Update 3 点此下载
配置安装源
ESXI 的镜像比较特殊,需要做些调整才可以通过 PXE 安装。

1
2
3
4
5
mkdir -p /data/wwwroot/esxi/5.5
mount -o loop VMware-VMvisor-Installer-5.5.0.update03-3029944.x86_64-Dell_Customized-A00.iso /mnt
cp -rf /mnt/* /data/wwwroot/esxi/5.5/
umount /mnt
ln -s /data/wwwroot/esxi/ /data/wwwroot/pxefiles/esxi

修改 exsi/5.5 目录中的 boot.cfg

1
2
3
sed -i '1a\prefix=/esxi/5.5/' /data/wwwroot/esxi/5.5/boot.cfg
sed -i '6s/\///g' /data/wwwroot/esxi/5.5/boot.cfg
sed -i 's/^kernel=.*$/kernel=tboot.b00/g' /data/wwwroot/esxi/5.5/boot.cfg

准备自动应答文件
编辑 /data/wwwroot/esxi/5.5/ks.cfg,写入如下内容:

1
2
3
4
5
6
accepteula
rootpw 12345678
clearpart --firstdisk=local --overwritevmfs
install --firstdisk=local --overwritevmfs
network --bootproto=dhcp --device=vmnic0
reboot

root 用户的密码是 12345678
添加PXE启动项
编辑 pxelinux.cfg/default 添加如下 label 块:

1
2
3
4
label Install ESXI 5.5 for dell
menu label Install ESXI 5.5 for dell
kernel /esxi/5.5/mboot.c32
append -c /esxi/5.5/boot.cfg ks=http://192.168.4.6/esxi/5.5/ks.cfg

开始安装
虽然下载的是针对服务器的,但是为了方便截图依然使用虚拟机测试。需要注意的是,虚拟机安装 ESXI 需要将操作系统设置为 VMware EXS(X)

然后正常进入PXE引导菜单

安装完成后会自动重启。

安装 Windows

Windows 系统的安装就比较特殊了,因为不像 Linux 可以通过内核引导启动,虽然也可以实现无人应答安装,但是研究的成本高于工作中的实际成本,所以这里只实现了可以通过网络手动安装 Windows 系统。
Windows 系统的安装需要一个 WinPE 的安装环境,先通过网络引导启动 WinPE,然后在 WinPE 环境中安装 Windows 镜像。
下载系统镜像
除了可以在微软官方下载镜像,也可以在国内好心人制作的 MSDN I Tell You 里下载。
这里使用 windows_server_2008_R2_standard_enterprise_and_datacenter_x64_dvd_x15-59777.iso 这个镜像。
配置镜像站
首先需要一个带网络功能的 WinPE,如果不嫌麻烦的话可以百度如何制作 WinPE 镜像,如果采用第三方提供做好的 WinPE 就需要保证镜像是否是干净安全的,而且还需要集成了网卡驱动,如果是用于服务器安装,可能还需要集成 Raid 卡的驱动。
这里使用无垠PE制作的 Win8PE64网络版.iso 点此打开网盘分享 密码:sees。其中有一个 win8pe_x64_raid_network.iso 的镜像据说是集成了 Raid 卡驱动适用于服务器的 WinPE,实际还并未测试过。
PXE环境对中文的支持能力几乎没有,所以下载后需要将文件名中的中文去掉,然后放到相应目录。然后将 Windows 系统安装镜像解压。

1
2
3
4
5
6
mkdir -p /data/wwwroot/windows/windows_server_2008_x64
mv Win8PE64网络版.iso /data/wwwroot/windows/win8pe.iso
ln -s /data/wwwroot/windows/ /data/wwwroot/pxefiles/windows
mount -o loop windows_server_2008_R2_standard_enterprise_and_datacenter_x64_dvd_x15-59777.iso /mnt
cp -rf /mnt/* /data/wwwroot/windows/windows_server_2008_x64/
umount /mnt

接下来就是另一个比较麻烦的地方了,因为在 WinPE 中通过网络安装 Windows 系统最简单方便的方法就是在 Linux 上创建 Samba 共享,然后 WinPE 中挂载使用。Samba 软件也可以从发行版的官方仓库中获得,或者手动编译安装。
编译安装 Samba:

1
2
3
4
5
wget https://download.samba.org/pub/samba/stable/samba-4.8.2.tar.gz
tar xf samba-4.8.2.tar.gz
cd samba-4.8.2
./configure --prefix=/usr/local/samba
make -j4 && make install

配置过程中如果出现了什么错误,就根据提示自行解决依赖。接着配置 Samba 共享目录并启动服务。
vim /usr/local/samba/etc/smb.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
[global]
workgroup = MYGROUP
server string = Samba Server
server role = standalone server
log file = /dev/stdout
max log size = 50
dns proxy = no
pam password change = yes
map to guest = bad user
usershare allow guests = yes
create mask = 0664
force create mode = 0664
directory mask = 0775
force directory mode = 0775
force user = root
force group = root
follow symlinks = yes
load printers = no
printing = bsd
printcap name = /dev/null
disable spoolss = yes
socket options = TCP_NODELAY
strict locking = no
vfs objects = recycle
recycle:keeptree = yes
recycle:versions = yes
min protocol = SMB2

[public]
path = /data/wwwroot/windows/
browsable = yes
read only = yes
guest ok = yes
veto files = /._*/.apdisk/.AppleDouble/.DS_Store/.TemporaryItems/.Trashes/desktop.ini/ehthumbs.db/Network Trash Folder/Temporary Items/Thumbs.db/
delete veto files = yes

启动 Samba 服务后可以在 Windows 上连接试试
/usr/local/samba/sbin/smbd -D
在 Windows 资源管理器中输入 \192.168.4.6 就可以打开共享的目录了。

添加PXE启动项
还记得之前和 pxelinux.0 同一目录的 memdisk 文件吧,这通过这个文件可以将 iso 镜像加载到内存中启动,就利用这个方式来启动 WinPE 镜像。
编辑 pxelinux.cfg/default 添加如下 label 块:

1
2
3
4
label Install windows for vmware (WinPE)
menu label Install Windows for vmware (WinPE)
kernel memdisk
append initrd=/windows/win8pe.iso ksdevice=bootif raw iso

开始安装
选择启动 WinPE

进入 WinPE 桌面环境后连接到服务端的 Samba 共享目录,然后执行 Windows 系统安装镜像中的 setup.exe

剩下的步骤就是 Windows 系统的普遍安装方式了。

Ubuntu LiveCD

LiveCD 是个比较有意思的模式,用于直接通过光盘或者镜像启动 Linux,相当于直接将光盘作为根文件系统,在不安装到硬盘的情况下就可以体验到当前发行版了。而且稍加修改就可以通过网络来启动,由于不依赖硬盘启动,个人认为还可以将 LiveCD 模式当作救援模式使用,因为 LiveCD 模式下相当于正常启动了 Linux 系统,因此也可以正常使用包管理器来安装软件,以及挂载和卸载硬盘。
LiveCD 需要通过 NFS 来加载镜像内容,因此还需要搭建一个 NFS 目录共享。
下载系统镜像
由于 Ubuntu Server 的镜像不支持 LiveCD 模式,所以这里使用桌面版的 Ubuntu-16.04 镜像。镜像名为:ubuntu-16.04.3-desktop-amd64.iso
配置 NFS 共享
各发行版的 NFS 使用的软件包名称都不太一样,可以借助搜索引擎获取你所使用的发行版是如何安装 NFS 共享软件包的,这里就使用 CentOS 6.8 的 NFS 共享为例。

1
2
3
4
5
mkdir /data/wwwroot/apt/ubuntu16.04-desktop/
mount -o loop ubuntu-16.04.3-desktop-amd64.iso /mnt/
cp -rf /mnt/* /data/wwwroot/apt/ubuntu16.04-desktop/
umount /mnt
yum install -y rpcbind nfs-utils

vim /etc/exports
写入如下内容:

1
2
3
4
5
/data/wwwroot/apt/ubuntu16.04-desktop/    *    (ro,sync,no_root_squash)
启动 NFS 服务
1
2 service rpcbind restart
service nfs restart

共享成功后可以在其他主机上看到自己的共享:

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# showmount -e 192.168.4.6
Export list for 192.168.4.6:
/data/wwwroot/apt/ubuntu16.04-desktop *
[root@localhost ~]#
添加PXE启动项
编辑 pxelinux.cfg/default 添加如下 label 块:
label Ubuntu 16.04 amd64
menu label Ubuntu 16.04 amd64 LiveCD
kernel /apt/ubuntu16.04-desktop/casper/vmlinuz.efi
append initrd=/apt/ubuntu16.04-desktop/casper/initrd.lz boot=casper netboot=nfs nfsroot=192.168.4.133:/data/wwwroot/apt/ubuntu16.04-desktop/ splash locale=zh_CN url=http://192.168.4.133/apt/ubuntu16.04-desktop/preseed/ubuntu.seed

进入 LiveCD 模式

加载过程可能会比较慢,但最后还是成功进入了 Ubuntu 桌面。

脚本源码

该脚本参考此教程编写,适配了centos和Ubuntu系统

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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
#!/bin/env bash
#dnsmasq+pxe无人值守批量安装系统

input(){
if [ -z $1 ];then
echo "Enter not null."
elif [ $1 == exit -o $1 == quit -o $1 == q ];then
exit 1;
elif [[ $1 =~ ^[1-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]];then
a=`echo $ip |cut -d. -f1`
b=`echo $ip |cut -d. -f2`
c=`echo $ip |cut -d. -f3`
d=`echo $ip |cut -d. -f4`
if [ $a -le 255 -a $b -le 255 -a $c -le 255 -a $d -le 255 ];then
echo "继续执行...."
else
echo "IP format error,Please enter the IP again."
exit 1;
fi
else
echo "IP format error,Please enter the IP again."
exit 1;
fi
}

read -p "请输入服务器ip:" ip
input ${ip}
read -p "请输入DHCP的ip分发的范围(请填写开始网段ip):" dhcp1
input ${dhcp1}
read -p "请输入DHCP的ip分发的范围(请填写结束网段ip):" dhcp2
input ${dhcp2}
read -p "请输入服务器的网关:" mask
input ${mask}
read -p "请输入需要安装的系统类型(Centos7.9请输入1,Ubuntu16.10请输入2,两个系统都预装请输入3):" sys

if [ -z $sys ];then
echo "Enter not null."
elif [ $sys -ne 1 -a $sys -ne 2 -a $sys -ne 3 ];then
echo "Enter fail!."
fi

sed -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://mirror.centos.org|baseurl=https://opentuna.cn|g' \
-i.bak \
/etc/yum.repos.d/CentOS-*.repo

yum makecache

yum install gcc gcc-g++ gdb git wget xz-devel net-tools -y
cd /usr/local/src/
`wget http://xz.itcytblog.cn/dnsmasq-2.79.tar.xz`
tar xvf dnsmasq-2.79.tar.xz
cd dnsmasq-2.79 && make
wait
cp src/dnsmasq /usr/local/bin/
mkdir -p /data/pxeboot # PXE启动所需要的文件存放的目录
cd /data/pxeboot
cat <<EOF > dnsmasq.conf
# enable dhcp
dhcp-range=${dhcp1},${dhcp2},12h
dhcp-option=3,${mask}
dhcp-option=option:dns-server,114.114.114.114,8.8.8.8
#dhcp-boot=pxelinux.0
dhcp-boot=undionly.kpxe

# disable dns
port=0

# enable tftp
enable-tftp
tftp-root=/data/pxeboot
EOF

wget -P /etc/yum.repos.d/ http://xz.itcytblog.cn/nginx.repo
yum install nginx -y

mkdir -p /data/wwwroot/pxefiles # /data/wwwroot 作为HTTP根目录

cat << EOF > /etc/nginx/nginx.conf
worker_processes 4;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
autoindex on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /data/wwwroot;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
EOF

setenforce 0
service nginx restart

cd /usr/local/src/
git clone git://git.ipxe.org/ipxe.git
cd ipxe/src
cat <<EOF > embed.ipxe
#!ipxe
dhcp
chain tftp://\${next-server}/menu.ipxe
EOF
make bin/undionly.kpxe EMBED=embed.ipxe
wait
cp bin/undionly.kpxe /data/pxeboot/
cat << EOF > /data/pxeboot/menu.ipxe
#!ipxe
set 210:string http://${ip}/pxefiles/
set 209:string pxelinux.cfg/default
chain \${210:string}pxelinux.0
EOF

cd /usr/local/src/
`wget http://xz.itcytblog.cn/syslinux-3.86-pre1.tar.xz`
tar xvf syslinux-3.86-pre1.tar.xz
cd syslinux-3.86-pre1
cp com32/menu/vesamenu.c32 /data/wwwroot/pxefiles/
cp core/pxelinux.0 /data/wwwroot/pxefiles/
cp memdisk/memdisk /data/wwwroot/pxefiles/
cd /data/wwwroot/pxefiles/
mkdir pxelinux.cfg
touch pxelinux.cfg/default

centos(){
mkdir -p /data/wwwroot/yum/CentOS7.9/
`wget -P /data/wwwroot/yum/CentOS7.9/ https://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso`
mount -o loop /data/wwwroot/yum/CentOS7.9/CentOS-7-x86_64-Minimal-2009.iso /mnt/
cp -rf /mnt/* /data/wwwroot/yum/CentOS7.9/
wait
umount /mnt/
ln -s /data/wwwroot/yum/ /data/wwwroot/pxefiles/yum
cat << EOF >/data/wwwroot/yum/CentOS7.9/ks-minimal-vmware.cfg
#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Install OS instead of upgrade
install
# Use text mode install
text
# Firewall configuration
firewall --enabled --service=ssh
firstboot --disable
ignoredisk --only-use=sda
# Keyboard layouts
keyboard --vckeymap=us --xlayouts=''
# System language
lang zh_CN.UTF-8

# Network information
network --bootproto=dhcp --device=eth0 --mtu=1500 --noipv6 --activate
network --bootproto=dhcp --hostname=localhost.localdomain
# Reboot after installation
reboot
# Use network installation
url --url="http://${ip}/yum/CentOS7.9/"
# Root password
rootpw --iscrypted \$1\$/Hu9dpB5\$XRyJZbN9NOqoF10Qh2ZSp.
# SELinux configuration
selinux --disabled
# System services
services --enabled="chronyd"
# Do not configure the X Window System
skipx
# System timezone
timezone Asia/Shanghai --isUtc
# System bootloader configuration
bootloader --append="rhgb rhgb quiet quiet crashkernel=auto" --location=mbr --driveorder="sda" --boot-drive=sda
# Clear the Master Boot Record
zerombr
# Partition clearing information
clearpart --all --drives=sda
# Disk partitioning information
part swap --fstype="swap" --size=2048
part /boot --fstype="ext4" --size=500
part / --fstype="ext4" --size=17931

%packages
@core
chrony
kexec-tools
kexec-tools

%end

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

%end
EOF

cat << EOF > pxelinux.cfg/default
default vesamenu.c32
timeout 50

menu title Welcome to PXE server!


label centos7.9
menu label Install CentOS7.9 for vmware (minimal install)
kernel /yum/CentOS7.9/images/pxeboot/vmlinuz
append initrd=/yum/CentOS7.9/images/pxeboot/initrd.img ks=http://${ip}/yum/CentOS7.9/ks-minimal-vmware.cfg
EOF
}

ubuntu(){
mkdir -p /data/wwwroot/apt/ubuntu16.10
cd /data/wwwroot/apt/ubuntu16.10
`wget http://old-releases.ubuntu.com/releases/yakkety/ubuntu-16.10-server-amd64.iso`
mount -o loop ubuntu-16.10-server-amd64.iso /mnt/
cp -rf /mnt/* /data/wwwroot/apt/ubuntu16.10
umount /mnt/
ln -s /data/wwwroot/apt/ /data/wwwroot/pxefiles/apt
cat << EOF > /data/wwwroot/apt/ubuntu16.10/ks-server-vmware.cfg
lang en_US
langsupport en_US
keyboard us
mouse
timezone Asia/Shanghai
rootpw --disabled
# ubuntu password: 123456
user ubuntu --fullname "ubuntu" --iscrypted --password \$1\$/Hu9dpB5\$XRyJZbN9NOqoF10Qh2ZSp.
reboot
text
install
url --url http://${ip}/apt/ubuntu16.10/
bootloader --location=mbr
zerombr yes
clearpart --all --initlabel
part / --fstype ext4 --size 1 --grow
part swap --size 2048
auth --useshadow --enablemd5
network --bootproto=dhcp --device=eth0
firewall --disabled
skipx
%packages
@^minimal
@core
openssh-server
EOF

cat << EOF > /data/wwwroot/pxefiles/pxelinux.cfg/default
default vesamenu.c32
timeout 50

menu title Welcome to PXE server!

label ubuntu server 16.10
menu label Install Ubuntu server 16.10 (minimal install)
kernel /apt/ubuntu16.10/install/netboot/ubuntu-installer/amd64/linux
append initrd=apt/ubuntu16.10/install/netboot/ubuntu-installer/amd64/initrd.gz ks=http://${ip}/apt/ubuntu16.10/ks-server-vmware.cfg --- live-installer/net-image=http://${ip}/apt/ubuntu16.10/install/filesystem.squashfs
EOF
}
if [ $sys -eq 1 ];then
centos
elif [ $sys -eq 2 ];then
ubuntu
elif [ $sys -eq 3 ];then
centos
ubuntu
fi

service firewalld status &>/dev/null
if [ $? -eq 0 ];then
kou1=(80 22)
for i in ${!kou1[@]}
do
firewall-cmd --permanent --zone=public --add-port=${kou1[$i]}/tcp
firewall-cmd --reload
done
kou2=(67 68 69)
for i in ${!kou2[@]}
do
firewall-cmd --permanent --zone=public --add-port=${kou2[$i]}/udp
firewall-cmd --reload
done

fi &>/dev/null

echo "---------------------------------------------------------------------------------------------------------"
echo "tftp和DHCP,pxe服务器已经开启,请把裸金属接入于pxe服务器同一网卡,重启即可自动安装系统。"
echo "系统默认密码是123456,Ubuntu系统是ubuntu用户,root密码请登录后修改。应答文件建议可以根据自己需求进行修改。"
echo "---------------------------------------------------------------------------------------------------------"
cd /data/pxeboot/
dnsmasq -C dnsmasq.conf -d

该文章摘自:https://yunfwe.cn/2018/06/03/2018/一步步搭建PXE网络装机