扔掉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.0menu.c32;如果一开始你没有注意到的话,再执行cobbler sync它还会把syslinux的pxelinux.0menu.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。

pfsense-启用网络引导

基本信息

  • Based PVE 7
  • PXE Server openSUSE Leap 15
  1. TFTP
  2. Syslinux
  3. Apache2
  • PXE Boot
  1. CentOS 7
  2. Rocky 8
  3. openSUSE Leap 15
  4. 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.imgvmlinuz

openSUSE Leap是initrdlinux

Ubuntu是initrdvmlinuz;

配置启动文件

/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中,使用网络启动;

pve-seabios-ipxe
pxe-boot-tui

默认情况下,根据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方式。

参考资料