使用 PXE 批量部署 Legacy CentOS 8 系统
后知后觉 暂无评论

使用 PXE 批量部署 Legacy CentOS 8 系统,需要注意的是 2021年12月31日 CentOS 8 将停止维护,主线版本将切换至 CentOS 8 Stream,如果仍需使用,推荐只在隔离的内网环境中使用。

环境

属性
系统版本CentOS Linux 8.5.2111
服务端地址192.168.15.100
光盘镜像CentOS-8.5.2111-x86_64-dvd1.iso

部署 PXE

先准备服务端的服务和配置文件,然后安装基础依赖。

sudo dnf install -y wget

DHCP 服务

  1. 首先安装 DHCP 服务,DHCP 服务为 PXE 客户端提供地址,需要注意的是网络中不可存在其他的 DHCP 服务器。

    sudo dnf install -y dhcp-server
  2. 配置服务自启动

    sudo systemctl enable dhcpd
  3. 配置服务

    cat <<EOF | sudo tee -a /etc/dhcp/dhcpd.conf
    option space pxelinux;
    option pxelinux.magic code 208 = string;
    option pxelinux.configfile code 209 = text;
    option pxelinux.pathprefix code 210 = text;
    option pxelinux.reboottime code 211 = unsigned integer 32;
    option architecture-type code 93 = unsigned integer 16;
    
    subnet 192.168.15.0 netmask 255.255.255.0 {
      option routers             192.168.15.2;
      option subnet-mask         255.255.255.0;
      option domain-name-servers 192.168.15.2;
      option time-offset         -18000;
      range dynamic-bootp 192.168.15.60 192.168.15.100;
      class "pxeclients" {
        match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
        next-server 192.168.15.100;
        if option architecture-type = 00:07 {
          filename "uefi/shimx64.efi";
        } else {
          filename "pxelinux/pxelinux.0";
        }
      }
    }
    EOF

参数解析:

参数说明
option routers网关
option subnet-mask子网掩码
option domain-name-serversDNS 搜索域
time-offset-18000 美国东部标准时间 (UTC -4)
range dynamic-bootp将要部署的 DHCP 区段
next-server下一跳指为 PXE 服务端地址

TFTP 服务

安装 TFTP 服务,为 PXE 客户端提供网络启动所需的镜像和虚拟磁盘文件等,保证系统安装所需的临时系统可以正常加载。

sudo dnf install -y tftp tftp-server

服务无需配置,默认分享的路径 /var/lib/tftpboot

xinetd 服务

  1. 先安装 xinetd 服务,用来监听网络请求而启动相应的服务程序,而不再需要手动启动服务。

    sudo dnf install -y xinetd
  2. 配置服务,CentOS8 默认不包含 tftp 服务的配置,需要手动添加。

    cat <<EOF | sudo tee /etc/xinetd.d/tftp-udp
    service tftp
    {
            socket_type             = dgram
            protocol                = udp
            wait                    = yes
            user                    = root
            server                  = /usr/sbin/in.tftpd
            server_args             = -s /var/lib/tftpboot --verbose
            disable                 = no
            per_source              = 100
            cps                     = 100 2
            flags                   = IPv4
            only_from               = 192.168.15.0
            log_type                = FILE /var/log/tftp.log
    }
    EOF
    小贴士:添加 --verbose 参数后日志会记录详细信息,使用命令 sudo tail -f /var/log/messages | grep tftp 即可查看详细的带文件名的访问日志。
  3. 服务配置自启动

    sudo systemctl enable xinetd.service
  4. 修正文件权限

    sudo chmod 600 /etc/xinetd.d/tftp-udp

HTTP 服务

  1. 安装 Apache,配置 HTTP 服务为 PXE 客户端提供 kickstart 配置和安装源。

    sudo dnf install -y httpd
  2. 服务配置自启动

    sudo systemctl enable httpd.service

firewalld 服务

如果系统开启了防火墙,那么需要为上述的服务开放防火墙对应的端口,以便 PXE 客户端能正确获取 IP 和获取引导文件。

sudo firewall-cmd --add-service=dhcp --permanent
sudo firewall-cmd --add-service=tftp --permanent
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --reload

添加完成后检查

sudo firewall-cmd --list-services

准备 PXE 系统

接下来配置 PXE 所需的环境和文件

配置网络

将 PXE 服务器的网络切换至私网,并配置网络地址,关闭网络中的 DHCP 服务。

## 以网卡名为 ens34 为例,执行时注意替换为实际名称
sudo nmcli connection add con-name ens34 type ethernet ifname ens34
sudo nmcli connection show ens34
sudo nmcli connection modify ens34 ipv4.method manual
sudo nmcli connection modify ens34 ipv4.addresses 192.168.15.100/24
sudo nmcli connection modify ens34 ipv4.gateway 192.168.15.1
sudo nmcli connection modify ens34 ipv4.dns 192.168.15.1
sudo nmcli connection up ens34

准备网络引导文件

为了可以同时引导 UEFI 和 Legacy BIOS 的机器,需要准备两份引导文件和配置文件。

类别目录
UEFI/var/lib/tftpboot/uefi/
Legacy/var/lib/tftpboot/pxelinux/

下载引导文件

cd ~
sudo dnf install -y --downloadonly --downloaddir . syslinux-tftpboot grub2-efi-x64 shim-x64

如果没有网络可以使用有外网的机器从镜像站中下载。

wget https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/grub2-efi-x64-2.02-106.el8.x86_64.rpm
wget https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/shim-x64-15-15.el8_2.x86_64.rpm
wget https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/Packages/syslinux-tftpboot-6.04-5.el8.noarch.rpm

解压安装包

rpm2cpio grub2-efi-x64-2.02-106.el8.x86_64.rpm | cpio -dimv
rpm2cpio shim-x64-15-15.el8_2.x86_64.rpm | cpio -dimv
rpm2cpio syslinux-tftpboot-6.04-5.el8.noarch.rpm | cpio -dimv

UEFI

先准备 UEFI 方式的引导文件,将刚才解压的 grubx64.efishim.efi 复制到共享目录。

sudo mkdir /var/lib/tftpboot/uefi/
sudo cp ~/boot/efi/EFI/centos/grubx64.efi /var/lib/tftpboot/uefi/
sudo cp ~/boot/efi/EFI/centos/shimx64.efi /var/lib/tftpboot/uefi/

准备引导配置文件。

cat <<EOF | sudo tee /var/lib/tftpboot/uefi/grub.cfg
set timeout=5
menuentry 'Install CentOS Linux 8' {
  linuxefi pxelinux/vmlinuz ip=dhcp inst.ks="http://192.168.15.100/anaconda-ks.cfg" inst.repo="http://192.168.15.100/images/CentOS-8/x86_64"
  initrdefi pxelinux/initrd.img
}
EOF

修正引导文件权限。

sudo chmod 644 /var/lib/tftpboot/uefi/grub.cfg
sudo chmod 755 /var/lib/tftpboot/uefi/{grubx64.efi,shimx64.efi}

Legacy BIOS

然后准备 Legacy BIOS 方式的引导文件,并下载所需要的文件。

sudo mkdir /var/lib/tftpboot/pxelinux/
cd /var/lib/tftpboot/pxelinux/
sudo wget https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/isolinux/boot.msg
sudo wget https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/isolinux/initrd.img
sudo wget https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/isolinux/ldlinux.c32
sudo wget https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/isolinux/libcom32.c32
sudo wget https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/isolinux/libutil.c32
sudo wget https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/isolinux/splash.png
sudo wget https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/isolinux/vesamenu.c32
sudo wget https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os/isolinux/vmlinuz

找到刚才解压的安装包路径,找到文件并复制到引导目录

sudo cp ~/tftpboot/pxelinux.0 /var/lib/tftpboot/pxelinux

然后创建默认引导配置目录

sudo mkdir /var/lib/tftpboot/pxelinux/pxelinux.cfg

写入配置

cat <<EOF | sudo tee /var/lib/tftpboot/pxelinux/pxelinux.cfg/default
default vesamenu.c32
prompt 1
timeout 50

display boot.msg

menu clear
menu background splash.png
menu title CentOS Linux 8
menu vshift 8
menu rows 18
menu margin 8
menu helpmsgrow 15
menu tabmsgrow 13

menu color border * #00000000 #00000000 none
menu color sel 0 #ffffffff #00000000 none
menu color title 0 #ff7ba3d0 #00000000 none
menu color tabmsg 0 #ff3a6496 #00000000 none
menu color unsel 0 #84b8ffff #00000000 none
menu color hotsel 0 #84b8ffff #00000000 none
menu color hotkey 0 #ffffffff #00000000 none
menu color help 0 #ffffffff #00000000 none
menu color scrollbar 0 #ffffffff #ff355594 none
menu color timeout 0 #ffffffff #00000000 none
menu color timeout_msg 0 #ffffffff #00000000 none
menu color cmdmark 0 #84b8ffff #00000000 none
menu color cmdline 0 #ffffffff #00000000 none

menu tabmsg Press Tab for full configuration options on menu items.

menu separator

label linux
  menu label ^Install CentOS Linux 8
  menu default
  kernel vmlinuz
  append initrd=initrd.img ip=dhcp inst.ks=http://192.168.15.100/anaconda-ks.cfg inst.repo=http://192.168.15.100/images/CentOS-8/x86_64/

menu separator
EOF

至此 /var/lib/tftpboot/ 目录结构如下:

.
├── pxelinux
│   ├── boot.msg
│   ├── initrd.img
│   ├── ldlinux.c32
│   ├── libcom32.c32
│   ├── libutil.c32
│   ├── pxelinux.0
│   ├── pxelinux.cfg
│   │   └── default
│   ├── splash.png
│   ├── vesamenu.c32
│   └── vmlinuz
└── uefi
    ├── grub.cfg
    ├── grubx64.efi
    └── shimx64.efi

kickstart 配置

准备自动化部署文件,如果不熟悉语法可以手动配置选项安装一个系统,然后从系统 /root/anaconda-ks.cfg 处复制即可获取安装配置模板。

sudo cp /root/anaconda-ks.cfg /var/www/html/anaconda-ks.cfg

或者直接使用下面的模板(安装完成后系统自动重启,并创建管理员账户,用户和密码可以根据需要自行修改)。

#version=RHEL8
#graphical
text
reboot

#repo --name="AppStream" --baseurl="https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/AppStream/x86_64/os"

%packages
@^minimal-environment
bash-completion
vim
wget
%end

keyboard --xlayouts='us'
lang en_US.UTF-8

network  --bootproto=dhcp --device=ens34 --ipv6=auto --activate
network  --hostname=localhost.localdomain

#url --url="https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.5.2111/BaseOS/x86_64/os"

firstboot --enable

ignoredisk --only-use=sda
autopart
clearpart --none --initlabel

timezone Asia/Taipei --isUtc

rootpw --lock
user --groups=wheel --name=kane --password=$6$7gBYQ/feyVt8e0zI$hq7I5x8JqngyXf7LUn5n4a2L3Vod1568cNuFJT0Mr4z6BFogWFDCg8XijRRlWbq/47gT70a3DtsQxyC6Mg2EL. --iscrypted --gecos="kane"

%addon com_redhat_kdump --disable --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

预配置

因为 CentOS 8 即将停止支持,因此官方的安装源即将失效,同时常见的网络镜像站的地址也将废弃并归档,需要在安装系统后对其系统源进行修改。

创建修改脚本,内容参考自清华大学开源镜像站

cat <<EOF | sudo tee /var/www/html/init.sh
minorver=8.5.2111
sed -e "s|^mirrorlist=|#mirrorlist=|g" \
         -e "s|^#baseurl=http://mirror.centos.org/\$contentdir/\$releasever|baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos-vault/$minorver|g" \
         -i.bak \
         /etc/yum.repos.d/CentOS-*.repo
sed -ri '110s/#\s%/%/' /etc/sudoers
sed -ri '107s/%/#\ %/' /etc/sudoers
EOF

添加至 anaconda-ks.cfg 配置文件中 %anaconda 段落前

%post --log=/root/ks-post.log
curl -O http://192.168.15.100/init.sh
sh -x init.sh 
%end

创建本地安装源

因为一个历史遗留问题,在网络安装源中缺失 .treeinfo 文件,导致 kickstart 配置中无法使用类似 CentOS 7 的网络安装源进行联网安装,并且发行版后期已经停止维护,估计未来也不会修复,所以需要搭建本地安装源。

需要 DVD 版安装镜像,然后挂载本地并使用 HTTP 提供对外下载。

sudo mkdir -p /var/www/html/images/CentOS-8/x86_64/
sudo mount CentOS-8.5.2111-x86_64-dvd1.iso /var/www/html/images/CentOS-8/x86_64/
## 如果使用光驱,直接挂载光驱即可
sudo mount /dev/sr0 /var/www/html/images/CentOS-8/x86_64/

上述问题虽然没有修复,但国内的部分镜像站已经同步了完整的安装镜像,可以使用在线安装的方式进行安装系统了,删除引导文件中的 inst.repo=... 参数(Legacy BIOS 和 UEFI 的都需要改),然后去掉 anaconda-ks.cfgrepourl 行前的注释即可使用网络源进行安装,无需再准备镜像进行挂载。


测试

整体配置完成后启动服务即可

sudo systemctl start dhcpd.service xinetd.service httpd.service

然后将新裸机接入子网开始测试。


疑难解答

如果客户端开机后可以正常分配地址,也能看到系统开始了安装过程,但中途出现如下类似报错:

[   29.947321] dracut: FATAL: Failed to find a root filesystem in /tmp/curl_fetch_url1/install.img.
[   29.952413] dracut: Refusing to continue
[   29.962341] dracut-initqueue[1100]: /lib/dracut-lib.sh: line 465: echo: write error: No space left on device
[   29.974241] dracut-initqueue[1100]: /lib/dracut-lib.sh: line 466: echo: write error: No space left on device
[   29.983985] dracut-initqueue[1100]: /lib/anaconda-lib.sh: line 142: printf: write error: No space left on device
[   29.983985] dracut-initqueue[1100]: //lib/dracut/hooks/initqueue/online/80-anaconda-netroot.sh: line 92: echo: write error: No space left on device

这种情况一般出现在 KVM 或其他虚拟化环境中,这是因为分配的内存过小导致的,在 PXE 安装过程中会将下载的临时系统挂载在内存中展开用于引导继续安装系统,CentOS 8 及之后的版本官方的引导镜像至少需要 1.5GiB 的内存才能正常完成安装,修改虚拟机内存限额重启即可正常安装。


附录

参考链接

本文撰写于一年前,如出现图片失效或有任何问题,请在下方留言。博主看到后将及时修正,谢谢!
禁用 / 当前已拒绝评论,仅可查看「历史评论」。