Automate CentOS and RHEL installation with PXE

Pushbutton

DHCP and TFTP Rollout

Now it's time to get down to business. Ansible is prepared well enough to roll out the TFTP and DHCP servers. You need to enforce this by typing the command:

ansible-playbook -i hosts infra.yml

The individual work steps of the two Playbooks then flash by on your screen.

If you are wondering why I do not go into more detail concerning the configuration of the firewall (i.e., firewalld), the chosen roles take care of this automatically and open the required ports for the respective services. The use of Ansible and the prebuilt modules definitely saves you some work.

Move Nginx into Position

Not all files for the automated RHEL or CentOS installation can be submitted to the installer over TFTP. That's not what the protocol is made for. You need to support your TFTP service with an Nginx server that can host the Kickstart files for Anaconda, for example.

A prebuilt Ansible role for this job, directly from the Ansible developers, works wonderfully on CentOS systems. Just clone the role into the roles/ folder:

$ cd roles
$ git clone https://github.com/nginxinc/ansible-role-nginx nginxinc.nginx

After that, open the host_vars/Hostname.yml file again and save the configuration for Nginx (Listing 2). The entry for server_name needs to match the full hostname of the infrastructure system.

Listing 2

Nginx Configuration

nginx_http_template_enable: true
nginx_http_template:
  default:
    template_file: http/default.conf.j2
    conf_file_name: default.conf
    conf_file_location: /etc/nginx/conf.d/
    servers:
      server1:
        list:
          listen_localhost:
            port: 80
        server_name: infrastructure.cloud.internal
        autoindex: true
        web_server:
          locations:
            default:
              location: /
              html_file_location: /srv/data
              autoindex: true
          http_demo_conf: false

Now add the nginxinc.nginx role you cloned to the infra.yml playbook and execute the ansible-playbook command again. Of most import here is that the /srv/data/ be created on the infrastructure node, either manually or by the playbook. The folder needs to belong to the >nginx user and the nginx group so that Nginx can access it.

Enabling PXE Boot

A specific series of commands enable PXE booting of the systems. Here, I assume that the unified extensible firmware interface (UEFI) with the secure boot function is enabled on the target systems.

The boot process will later proceed as follows: Configure the system with the intelligent platform management interface (IPMI) – or manually – for a network or PXE boot. To do this, the system first sends a DHCP request, which also contains the file name of the bootloader in its response. The PXE firmware of the network card then queries this and, once it has loaded the bootloader locally, executes it. The bootloader then reloads its configuration file.

Depending on the requesting MAC address, the bootloader configuration can be influenced, which is very important for the configuration of the finished system. First, however, you will be interested in configuring the basics of the whole process. Conveniently, the chosen DHCP role already configured the DHCP server to always deliver pxelinux/shimx64.efi as the filename for the bootloader to UEFI systems.

In the first step, create under /var/lib/tftpboot/ the pxelinux/ subdirectory; then, create the centos8/ and pxelinux.cfg/ subdirectories below that. Next, copy the /boot/efi/EFI/centos/shimx64.efi file to the pxelinux/ folder. If it is not in place, also install the shim-x64 package.

The pxelinux/ folder also needs to contain the grubx64.efi file, which you will find online [3]. While you are on the CentOS mirror, you can load the two files found in the pxeboot directory (initrd.img and vmlinuz) [4] and store them in pxeboot/centos8/.

Still missing is a configuration file for GRUB that tells it which kernel to use. In the pxeboot/ folder, store the grub.cfg file, which follows the pattern shown in Listing 3.

Listing 3

Generic GRUB Config

set default="0"
function load_video {
  insmod efi_gop
  insmod efi_uga
  insmod video_bochs
  insmod video_cirrus
  insmod all_video
}
load_video
set gfxpayload=keep
insmod gzio
insmod part_gpt
insmod ext2
set timeout=10
menuentry 'Install CentOS 8' --class centos --class gnu-linux --class gnu --class os {
  linuxefi pxelinux/centos8/vmlinuz devfs=nomount method=http://mirror.centos.org/centos/8/BaseOS/x86_64/os inst.ks=http://172.23.48.31/kickstart/ks.cfg
  initrdefi pxelinux/centos8/initrd.img
}

If you were to run a server through the PXE boot process, it would get a bootloader, a kernel, and an initramfs. However, the Kickstart file (Listing 4) is still missing.

Listing 4

Sample Kickstart Config

01 ignoredisk --only-use=sda
02 # Use text install
03 text
04 # Keyboard layouts
05 keyboard --vckeymap=at-nodeadkeys --xlayouts='de (nodeadkeys)','us'
06 # System language
07 lang en_US.UTF-8
08 # Network information
09 network --device=bond0 --bondslaves=ens1f0,ens1f1 --bondopts=mode=802.3ad,miimon-100 --bootproto=dhcp --activate
10 network --hostname=server.cloud.internal
11 network --nameserver=10.42.0.10,10.42.0.11
12 # Root password
13 rootpw --iscrypted <Password>
14 # Run the Setup Agent on first boot
15 firstboot --enable
16 # Do not configure the X Window System
17 skipx
18 # System timezone
19 timezone Europe/Vienna --isUtc --ntpservers 172.23.48.8,172.23.48.9
20 # user setup
21 user --name=example-user --password=<Password> --iscrypted --gecos="example-user"
22 # Disk partitioning information
23 zerombr
24 bootloader --location=mbr --boot-drive=sda --driveorder=sda
25 clearpart --all --initlabel --drives=sda
26 part pv.470 --fstype="lvmpv" --ondisk=sda --size 1 --grow
27 part /boot --size 512 --asprimary --fstype=ext4 --ondisk=sda
28 volgroup cl --pesize=4096 pv.470
29 logvol /var --fstype="xfs" --size=10240 --name=var --vgname=cl
30 logvol / --fstype="xfs" --size=10240 --name=root --vgname=cl
31 logvol swap --fstype="swap" --size=4096 --name=swap --vgname=cl
32 reboot
33
34 %packages
35 @^server-product-environment
36 kexec-tools
37 %end
38
39 %addon com_redhat_kdump --enable --reserve-mb='auto'
40 %end
41
42 %anaconda
43 pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
44 pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
45 pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
46 %end

If you want to know which format the password in the user (line 21) and rootpw (line 13) lines must have, you can find corresponding information online [5]. Save the file as ks.cfg in the /srv/data/kickstart/ directory on the infrastructure host; then, set the permissions to 0755 so that Nginx can access the file.

After completing this step, you will be able to PXE boot a 64-bit system with UEFI and secure boot enabled. However, at the moment, you will encounter one catch: The installed systems want to pick up their IP addresses over DHCP, and the default Kickstart template assumes that all servers use the same hardware layout.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus