扔掉cobbler,PXE简单实现批量部署(一)
扔掉cobbler,PXE简单实现批量部署多种操作系统
背景
最近在尝试使用cobbler实现批量部署,在走了几天弯路之后,确定,cobbler可以扔掉了,这货把人坑的太狠;按照网上搜来的文档,在CentOS7和8下都在执行cobbler get-loaders
命令出错,要么是Python的包太老,导致连接GitHub下载的时候,提示TLS不支持,要么是下载失败;通过官档,换成了openSUSE,看起来一切都执行顺利,但在投入使用的时候,各种失败,要么Access Denied,要么Not Found;经过细查之后才发现,在执行get-loaders
的时候是从Cobbler的GitHub仓库上拉取文件,但是!!!这个仓库已经5年没有更新过了,而且在使用openSUSE下载的时候,没有报错,但是下载的文件却是一个404的HTML,比如pxelinux.0
和menu.c32
;如果一开始你没有注意到的话,再执行cobbler sync
它还会把syslinux的pxelinux.0
和menu.c32
文件替换为假的,就是那个用HTML重命名之后的。如果你把get-loaders
的下载链接粘贴到浏览器会发现,页面404!
伪难点
几乎所有的PXE和Cobbler教程都会要求安装DHCP,但就是不服,经过试验发现,完全可以不用安装DHCP服务,使用当前已有的完全可以,相信这点更符合现实,哪个有网络的环境里,没有DHCP服务呢;特别是对于SOHO和HOME来说。
话虽如此,但环境还是各异的,这里提供两种方案来满足几乎大部分的场景。
方案1-安装DHCP
这里并非是指替换掉当前的DHCP,而是将DHCP配置为只响应引导的DHCP,这里安装的DHCP支持的参数(option)更多,可以根据厂商、网卡、Mac地址等条件来筛选响应的机器,并分配指定的IP或引导类型,支持if
语句;比如这里openSUSE给的示例;
# The following lines are optional
option domain-name "my.lab";
option domain-name-servers 192.168.1.1;
option routers 192.168.1.1;
option ntp-servers 192.168.1.1;
ddns-update-style none;
default-lease-time 3600;
# The following lines are required
option arch code 93 = unsigned integer 16; # RFC4578
subnet 192.168.1.0 netmask 255.255.255.0 {
next-server 192.168.1.1;
range 192.168.1.100 192.168.1.199;
default-lease-time 3600;
max-lease-time 3600;
if option arch = 00:07 or option arch = 00:09 {
filename "/EFI/x86/grub.efi";
}
else if option arch = 00:0b {
filename "/EFI/aarch64/bootaa64.efi";
}
else {
filename "/BIOS/x86/pxelinux.0";
}
}
我没有对此进行尝试,所以没法给出更多的信息和线索。
方案2-使用现有的DHCP
这种看起来最简单,也不用担心和当前DHCP冲突,但其实是有门槛的,如果是一般的家用路由器之类的,是没有额外的DHCP选项的,在PXE中,需要使用到DHCP的66和67选项,如果软路由器或企业环境,大部分都具备;比如我使用的pfSense。

基本信息
- Based PVE 7
- PXE Server openSUSE Leap 15
- TFTP
- Syslinux
- Apache2
- PXE Boot
- CentOS 7
- Rocky 8
- openSUSE Leap 15
- Ubuntu Server 20
安装并配置TFTP
sudo zypper in -y tftp
sudo systemctl enable --now tftp
sudo firewall-cmd --add-service=tftp --permanent
安装并配置Apache2
sudo zypper in -y apache2
sudo systemctl enable --now apache2
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --reload
简单配置一下Apache2
cd /etc/apache2/vhosts.d/
cp vhost.template pxe.conf
# 把几处vhost路径修改为htdocs即可
/srv/www/htdocs
# 修改后的文件,其他不用动
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
ServerName pxe.home.lan # 修改
DocumentRoot /srv/www/htdocs/ # 修改
ErrorLog /var/log/apache2/pxe.home.lan-error_log
CustomLog /var/log/apache2/pxe.home.lan-access_log combined
HostnameLookups Off
UseCanonicalName Off
ServerSignature On
ScriptAlias /cgi-bin/ "/srv/www/htdocs/cgi-bin/" # 修改
<Directory "/srv/www/htdocs/cgi-bin"> # 修改
AllowOverride None
Options +ExecCGI -Includes
<IfModule !mod_access_compat.c>
Require all granted
</IfModule>
<IfModule mod_access_compat.c>
Order allow,deny
Allow from all
</IfModule>
</Directory>
<IfModule mod_userdir.c>
UserDir public_html
Include /etc/apache2/mod_userdir.conf
</IfModule>
<Directory "/srv/www/htdocs"> # 修改
Options Indexes FollowSymLinks
AllowOverride All
<IfModule !mod_access_compat.c>
Require all granted
</IfModule>
<IfModule mod_access_compat.c>
Order allow,deny
Allow from all
</IfModule>
</Directory>
</VirtualHost>
重启Apache2
sudo systemctl restart apache2
安装并Syslinux
sudo zypper in -y syslinux
这个没有服务,装完就算完事,就是用它几个文件
配置PXE服务
拷贝启动文件到TFTP的目录
cp -v /usr/share/syslinux/{pxelinux.0,menu.c32,mboot.32,chain.c32} /srv/tftpboot
创建几个必要的目录
# tftp
sudo mkdir /srv/tftpboot/{pxelinux.cfg,pxeboot}
sudo mkdir /srv/tftpboot/pxeboot/{bios,uefi}
sudo mkdir /srv/tftpboot/pxeboot/bios/{centos7,rocky8,opensuse15,ubuntu20}
# apache2
sudo mkdir /srv/www/htdocs/{bios,uefi}
挂载ISO镜像,之后拷贝文件到Apache2的发布目录
# 挂载镜像
sudo mount CentOS-7-x86_64-Minimal-2009.iso /mnt
# 拷贝镜像文件
sudo cp -r /mnt /srv/www/htdocs/bios/centos7
# 拷贝启动文件
sudo cp -v /mnt/isolinux/{initrd.img,vmlinuz} /srv/tftpboot/pxeboot/bios/centos7
CentOS系列都是initrd.img
与vmlinuz
;
openSUSE Leap是initrd
和linux
;
Ubuntu是initrd
和vmlinuz;
配置启动文件
/srv/tftpboot/pxelinux.cfg/default
default menu.c32
prompt 0
timeout 60
menu title PXE Menu
# Rocky 8
label Manual Install Rocky 8
kernel /pxeboot/bios/rocky8/vmlinuz
append initrd=/pxeboot/bios/rocky8/initrd.img inst.repo=http://pxe.home.lan/bios/rocky8
# CentOS 7
label Manual Install CentOS 7
kernel /pxeboot/bios/centos7/vmlinuz
append initrd=/pxeboot/bios/centos7/initrd.img inst.repo=http://pxe.home.lan/bios/centos7
# OpenSUSE Leap - DVD
label Manual Install OpenSUSE Leap 15 - DVD
kernel /pxeboot/bios/opensuse-leap15-dvd/linux
append initrd=/pxeboot/bios/opensuse-leap15-dvd/initrd install=http://pxe.home.lan/bios/opensuse-leap15-dvd ip=dhcp splash=verbose textmode=1
# Ubuntu Server 20.04
label Manual Install Ubuntu Server 20.04
linux /pxeboot/bios/ubuntu20/vmlinuz
initrd /pxeboot/bios/ubuntu20/initrd file=http://pxe.home.lan/bios/ubuntu20/preseed/ubuntu-server.seed boot=casper quiet splash
append ip=dhcp url=http://pxe.home.lan/iso/ubuntu-20.04.3-live-server-amd64.iso
完成
在PVE的SeaBIOS中,使用网络启动;


默认情况下,根据pxelinux.cfg/default
中的timeout
值6秒后,自动选择第一个;
FAQ
如果Ubuntu出现con not mount /dev/loop1 (/cdrom/casper/filesystem.squashfs) on /filesystem.squashfs,然后卡在initramfs那里,则去检查ubuntu镜像的sha256值,可能镜像不完整。
后记
目前只是完成了基于BIOS的手动安装,就像放入光盘那样,因为没有附加自动应答文件;在CentOS中,安装完在当前目录会有个anaconda.cfg
文件是当前安装自动生成的应答文件,可以使用ks=anaconda.cfg
来使用自动安装;
下一篇将更新UEFI方式。
参考资料
- Setup a PXE Boot Server in RHEL/CentOS 7 - CentLinux
- Step-by-step guide to deploy different OSes through Windows Deployment Services (veeam.com)
- SDB:PXE 引导安装 - openSUSE Wiki
- openSUSE Lizards
- SDB:网络安装方式 - openSUSE Wiki
- Preparing Network Boot Environment | Deployment Guide | SUSE Linux Enterprise Server 15 SP1
- How can current Ubuntu versions be installed via PXE network boot and an automated installation? | Newbedev
- PXELINUX - Syslinux Wiki