Centos 8 kickstart

最後更新: 2020-08-04

前言

Anaconda is a free and open-source system installer for Linux distributions.

It is mainly written in Python with some modules written in C.

目錄

  • anaconda-ks.cfg
  • ...
  • Cleanup CD
  • Sample kickstarts and snippets
  • Troubleshoot

 


anaconda-ks.cfg

 

After the installation completes, all choices made during the installation are saved into a file named anaconda-ks.cfg

 


Tools

 

ISO Tools

dnf install genisoimage -y       # 將 unzip file 打包回 ISO

Verify tools

dnf install pykickstart -y

Usage

ksvalidator -v RHEL8 /path/to/kickstart.ks

 


ks.cfg

 

To load your Kickstart file automatically without having to specify the "inst.ks=" boot option

file ks.cfg and place it on a local storage volume (HDD, USB-DISK) labeled OEMDRV

ls myiso/

ks.cfg

genisoimage -V OEMDRV -o ks.iso myiso/

 


Sections

 

Sections must be specified in order.

Items within the sections do not have to be in a specific order unless otherwise specified.

 


Syntax Reference

 

 

cdrom (optional)

It performs the installation from the first optical drive on the system

You must specify the type of installation from cdrom, harddrive, nfs, liveimg, or url

---- Disk ----

ignoredisk (optional)

Causes the installation program to ignore the specified disks.

--only-use - Specifies a list of disks for the installation program to use. All other disks are ignored.

                  用唔到, 因為唔知會係 sda 還是 vda

i.e.

ignoredisk --only-use=vda

clearpart (optional)

Removes partitions from the system, prior to creation of new partitions. By default, no partitions are removed.

--none (default)

Do not remove any partitions.

--initlabel

Initializes a disk (or disks) by creating a default disk label for ALL disks

in their respective architecture that have been designated for formatting (for example, msdos for x86).

--disklabel=LABEL  # msdos / gpt

--drives=hda,hdb

Specifies which drives to clear partitions from.

--all

Erases all partitions from the system.

This option will erase all disks which can be reached by the installer, including any attached network storage.

ie.

clearpart --none --initlabel

autopart (optional)

Automatically creates partitions:

  • a root (/) partition (1 GB or larger),
  • a swap partition, and
  • an appropriate /boot partition for the architecture.
  • On large enough drives (50 GB and larger), this also creates a /home partition.

The autopart option cannot be used together with the part/partition, raid, logvol, or volgroup

i.e.

# --type: lvm, btrfs, plain, thinp

# plain: Regular partitions with no LVM or Btrfs

# --nohome - Disables automatic creation of the /home partition.

autopart --type=plain --nohome

Note

要配合 clearpart 使用

part (optional)

Syntax

part mntpoint [Opts]

Example

# 方法 1
part /boot --fstype="xfs"  --label="boot" --ondisk=vda --size=300  --asprimary
part swap  --fstype="swap" --label="swap" --ondisk=vda --recommended
part /     --fstype="xfs"  --label="root" --ondisk=vda --size=2000 --grow

mntpoint

/path

pv.id              # The partition is used for LVM

raid.id            # The partition is used for software RAID

swap              # The partition is used as swap space.

EFI

# 2
part biosboot  --fstype="biosboot" --size=1   --ondisk=vda
part /boot/efi --fstype="xfs"      --size=200 --label="efi" --ondisk=vda

biosboot

# The partition will be used for a BIOS Boot partition.

# A 1 MiB BIOS boot partition is necessary on BIOS-based AMD64 and Intel 64 systems using a GUID Partition Table (GPT);

# the boot loader will be installed into it. It is not necessary on UEFI systems.

/boot/efi

# An EFI System Partition.

# A 50 MiB EFI partition is necessary on UEFI-based AMD, Intel, and ARM; the recommended size is 200 MiB.

# It is not necessary on BIOS systems. See also the bootloader command.

Opts

--asprimary

Forces the partition to be allocated as a primary partition.

--recommended

To determine the size of the swap partition automatically

--size=

The minimum partition size in MiB

--grow

Tells the partition to grow to fill available space (if any),

or up to the maximum size setting(--maxsize=)

--label=

assign a label to an individual partition.

--ondisk= or --ondrive=

Forces the partition to be created on a particular disk.

Note

 * 用了 ignoredisk 就不用 "--ondisk=vda" 了

 * part 要配合 clearpart 使用

LVM

i.e.

# Create the partition first(pv.01), create the logical volume group(Centos), and then create the logical(/)

part pv.01 --size 1 --grow
volgroup centos pv.01
logvol / --vgname=centos --fstype=xfs --name=root --percent=80

--grow

Tells the logical volume to grow to fill available space (if any), or up to the maximum size setting,

if one is specified. A minimum size must be given, using either the --percent= option or the --size= option.

--percent=N

A percentage of the free space in the volume group after any statically-sized logical volumes are taken into account.

This option cannot be used together with the --size= option.

--name=name

* Do not use the dash (-) character in logical volume name

zerombr (optional)

Reinitialize Partition Tables

If zerombr is specified, any invalid partition tables found on disks are initialized.

--------

bootloader (required)

mbr - The default option.

Depends on whether the drive uses the Master Boot Record (MBR) or GUID Partition Table (GPT) scheme:

  •  On a GPT-formatted disk, this option will install stage 1.5 of the boot loader into the BIOS boot partition.
  •  On an MBR-formatted disk, stage 1.5 will be installed into the empty space between the MBR and the first partition.

i.e.

bootloader --location=mbr

firewall (optional)

--remove-service     # Do not allow services through the firewall

--enabled

--trust em1, em2

--port=22:tcp

--service=ssh

firewall --remove-service="cockpit,dhcpv6-client"
firewall --enabled --service=ssh

firstboot (optional) # disabled by default

Determine whether the Initial Setup application starts the first time the system is booted.

If enabled, the "initial-setup" package must be installed.

---- UI ----

graphical(default), text, or cmdline

graphical (optional)

Perform the installation in graphical mode.

text (optional)

Perform the Kickstart installation in text mode.

cmdline (optional)

Perform the installation in a completely non-interactive command line mode.

Any prompt for interaction halts the installation.

eula (optional)

Use this option to accept the End User License Agreement (EULA) without user interaction.

eula --agreed

 

-----

%addon com_redhat_kdump (optional)

%addon com_redhat_kdump --disable --reserve-mb='auto'
%end

keyboard (required)

keyboard --vckeymap=us --xlayouts='us'

lang (required)

lang en_US.UTF-8

network (optional)

# Hostname

network --hostname=c8

# DHCP

network --bootproto=dhcp --device=eth0 --noipv6 --activate

--activate

# the device is reactivated to use the details specified in the Kickstart file.

# Static IP

network --bootproto=static --ip=192.168.88.126 --gateway=192.168.88.1 --netmask=255.255.255.0 --nameserver=8.8.8.8,8.8.4.4 --noipv4

 * cannot wrap lines using a backslash "\"

--device=eth0

specifies the device to be configured

If the --device= option is missing on the first use of the network command,

  the value of the ksdevice= Anaconda boot option is used, if available.

ksdevice=?

# Use a specific network interface for kickstart, add "ksdevice=?" to the kernel command line

  • ksdevice=eth0
  • ksdevice=link       # use the first interface it finds that has a active link.
  • ksdevice=bootif    #  use the interface that did the PXE boot

part / partition (optional)

Creates a partition on the system.

# Device names in the sdX (or /dev/sdX) format are not guaranteed to be consistent across reboots

part / --fstype=xfs --onpart=sda1

# 所以要用

part / --fstype=xfs --onpart=/dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:0-part1

OR

part / --fstype=xfs --onpart=/dev/disk/by-id/ata-ST3160815AS_6RA0C882-part1

Other Opts

--label= - assign a label to an individual partition.

---- Power Control ----

reboot (optional)

Normally, Kickstart displays a message and waits for the user to press a key before rebooting.

reboot --eject

reboot --kexec        # 唔 work

poweroff

# equivalent to the "shutdown -P" command

shutdown

# equivalent to the shutdown command

rootpw (required)

Sets the system 's root password to the password argument.

rootpw --plaintext xxxx

rootpw --iscrypted $6$...

rootpw --lock --plaintext xxxx

selinux (optional)

selinux --disabled

services (optional)

ie.

services --disabled="chronyd"

timezone (required)

i.e.

# --nontp - Disable the NTP service automatic starting.

timezone Asia/Hong_Kong --isUtc --nontp

# Specify a list of NTP servers to be used as a comma-separated list without spaces

timezone Asia/Hong_Kong --isUtc --ntpservers=stdtime.gov.hk

vnc (optional)

Allows the graphical installation to be viewed remotely through VNC.

skipx (optional)

If present, X is not configured on the installed system.

pwpolicy (optional)

enforce a custom password policy during installation

%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

--notstrict

Passwords which do not meet the minimum quality requirements specified by the --minquality= and -minlen= options will be allowed

相當於 "Done" is clicked twice in the GUI.

# empty password

--emptyok      # Allow empty passwords. Enabled by default.

--notempty     # Do not allow empty passwords.

# Change password

--changesok

Allow changing the password in the user interface, even if the Kickstart file already specifies a password.

--nochanges

Do not allow changing passwords which are already set in the Kickstart file. Enabled by default.

加 user 及 group

user (optional) - Creates a new user on the system.

user --name=username [OPTIONS]

OPTIONS

  • --password=1234 --plaintext
  • --shell=
  • --lock

group (optional)

group --name=name [--gid=gid]

 


自動安裝 Package

 

 

查看 iso 內有什麼 Package

ls BaseOS/Packages/ | less

Package Selection

# Specifying Individual Packages

 * 當 repo 沒有此 package 時就會 error

ie.

%packages
screen
vim
-iw*-firmware
%end

# Specifying an Environment

@^server-product-environment

# Specifying Groups

@X Window System

# Individual Packages

curl*

# Individual packages to be removed

-iw*-firmware

# You can specify packages by environment, group

./BaseOS/repodata/?-comps-BaseOS.x86_64.xml

<group>
  <id>base</id>
  ...
</group>
...
<environment>
  <id>server-product-environment</id>
  ...
</environment>

repo (optional)

Configures additional yum repositories that can be used as sources for package installation.

i.e.

repo --name="Minimal" --baseurl=file:///run/install/sources/mount-0000-cdrom/Minimal
repo --name="MyPackages" --baseurl=file:///run/install/repo/MyPackages

Remark:

[1] Kickstart ISO Path 的 "/" => "/run/install/repo"

[2] MyPackages 是一個 repos 來, 放 rpm 入內是無效的

DVD 內置有的 Package

curl
rsync
zip
unzip
usbutils
psmisc
net-tools
mailx
lshw
strace
xz
pciutils
yum-utils
bash-completion

More Info.

Link

 


Custom ISO

 

mkdir -p /home/kickstart/tmp

cd /home/kickstart/

mount -o loop /path/to/iso tmp

cp -a tmp myiso

umount iso

cp ~/anaconda-ks.cfg myiso/ks.cfg

ksvalidator ~myiso/ks.cfg

# 修改 Title to isolinux/isolinux.cfg

menu title Rocky Linux 8.5 (Cust)

# Add label to isolinux/isolinux.cfg

# 1 seconds
timeout 10
...
label kickstart
 menu label Kickstart
 menu default
 kernel vmlinuz
 append initrd=initrd.img inst.stage2=hd:LABEL=CentOS8_x86_64 inst.ks=cdrom:/dev/cdrom:/ks.cfg net.ifnames=0 biosdevname=0 nomodeset nodetect

Remark

net.ifnames=0 biosdevname=0

為了方便 set NIC

# Build ISO

genisoimage -o centos8-custom.iso \
 -boot-load-size 4 -boot-info-table -J -r -R -T \
 -V 'Rocky_x86_64' \
 -no-emul-boot -b isolinux/isolinux.bin -c isolinux/boot.cat \
 -eltorito-alt-boot -no-emul-boot -eltorito-boot images/efiboot.img ./myiso

 


isolinux 與 EFI

 

舊的主板是用 isolinux 啟動的, 新的則用 uefi boot

設定

  • EFI/BOOT/grub.cfg
  • EFI/BOOT/BOOT.conf      # 與 grub.cfg 相同內容
### BEGIN /etc/grub.d/10_linux ###
menuentry 'Install CentOS Linux 8' --class fedora --class gnu-linux --class gnu --class os {
        linuxefi /images/pxeboot/vmlinuz inst.stage2=hd:LABEL=CentOS-8-2-2004-x86_64-dvd quiet
        initrdefi /images/pxeboot/initrd.img
}

 


Scripts

 

%post

--nochroot

The post-install script is run in a chroot environment, therefore, performing tasks such as copying scripts or

RPM packages from the installation media do not work by default.

Path

  • CD 的 '/'     =   /run/install/repo
  • SYS 的 '/'   =    /mnt/sysimage

--log

%post --log=/root/ks-post.log

Or

%post --nochroot --log=/mnt/sysimage/root/ks-post.log

--interpreter

Default: bash

%post --interpreter=/usr/bin/python
--- Python script omitted --
%end

--erroronfail

Display an error and halt the installation if the script fails.

The error message will direct you to where the cause of the failure is logged.

在 script 內 echo 的 msg 也在那裡

ie.

%pre --erroronfail --log=/tmp/my-pre-log
...
%end

Copy file to new system

%post --nochroot --erroronfail
echo
echo "#### Post Script ####"
echo "#### copy config file ####"

cd /mnt/sysimage
cp /run/install/repo/MyFiles/.screenrc   root/
cp /run/install/repo/MyFiles/.vimrc      root/
cp -a /run/install/repo/Myfiles/scripts  root/
%end

 * /run/install/repo 係 ISO 的 "/"

%pre

# Determine disk type for clearpart on kickstarts (sda / sdb)

%pre --erroronfail
exec < /dev/tty3 > /dev/tty3 2> /dev/tty3; chvt 3
echo "#### PRE Script ####"

######## lookup HDD
echo "#### lookup HDD ####"
# Unit: GB
MIN_SIZE=9
MAX_SIZE=21
# Code
ROOTDRIVE=""
for DEV in sda vda; do
  bdev=/sys/block/$DEV
  if [ -d "${bdev}" ] && [ "$(cat ${bdev}/removable)" == "0" ]; then
    # /sys/block/*/size is in 512 byte chunks
    devsize=$(($(cat ${bdev}/size)/2**21))
    echo "check size for ${DEV}: $devsize GB"
    if [ "${devsize}" -gt ${MIN_SIZE} ] && [ "${devsize}" -lt ${MAX_SIZE} ]; then
      if [ -z "$(blkid ${bdev})" ]; then
        # fisrt 100 M empty
        DskMd5=$(dd if=/dev/${DEV} bs=10M count=10 2> /dev/null | md5sum -b | cut -d' ' -f 1)
        if [ "$DskMd5" == "2f282b84e7e608d5852449ed940bfc51" ]; then
          ROOTDRIVE=${DEV}
          echo "Install on $ROOTDRIVE" && break
        else
          echo "$DEV is not a empty disk"
        fi
      else
        echo "$DEV has partition"
      fi
    fi
  fi
done
if [ -z "${ROOTDRIVE}" ]; then
  echo "No ROOTDRIVE" && sleep 10 && exit 1
fi
######## END lookup HDD


######## partitioning logic below
# /tmp/drive-selection 的內容
cat <<EOF>/tmp/drive-selection
ignoredisk --only-use=${ROOTDRIVE}
EOF
######## END partitioning logic

%end

# 引用 %pre 內的 drive-selection 的設定
#ignoredisk --only-use=vda
%include /tmp/drive-selection

 


Consoles and logging during installation

 

The CentOS installer uses the tmux terminal multiplexer to display and

control several windows you can use in addition to the main interface.

Softkey: Ctrl+Alt+F1 = Ctrl+b 1

Logging %pre and %post

When using a %pre or %post script you can simply log the output to a file by using --log=/path/to/file

[方法 1]

%post --log=/tmp/my-post-log
echo 'Hello, World!'

[方法 2]

%post
exec < /dev/tty3 > /dev/tty3
chvt 3
echo
echo "################################"
echo "# Running Post Configuration   #"
echo "################################"
(
echo 'Hello, World!'
) 2>&1 | /usr/bin/tee /var/log/post_install.log

sleep 10
chvt 1

* 按 Ctrl + F3 跳過 tty3 去查看時螢幕會清空

 


Remote Installation

 

  • 方法1: SSH
  • 方法2: VNC

SSH

Enable ssh service

During the installation, you can interact with the installation program and monitor its progress over an SSH connection.

By default, the ssh server is not started during the installation. To make ssh available during the installation,

boot the system with the kernel boot option inst.sshd  (isolinux/isolinux.cfg)

append initrd=initrd.img ... inst.sshd

creates a separate account that exists only in the installation environment.

( These accounts are not transferred to the installed system. )

sshpw(ks.cfg)

 * During installation, the root account has no password by default.

sshpw --username=name [options] password

ie.

shpw --username=example_username example_password
sshpw --username=root example_password --lock

VNC

會用 GUI mode Install ("text" setting 無效)

[方法1] By boot options

inst.vnc                                                   # VNC Direct Mode
inst.vncpassword=PASSWORD
inst.vnc  inst.vncconnect=HOST:PORT           # VNC Connect Mode (Admin: vncviewer -listen PORT)

[方法2] By ks.cfg Setting

this command starts a VNC server on the installation system with no password and displays the details required to connect to it.

vnc [--host=host_name] [--port=port] [--password=password]

--host=? Connect to the VNC viewer process listening on the given host name.

--port=? Provide a port that the remote VNC viewer process is listening on.

           If not provided, Anaconda uses the VNC default port of 5900.

--password= - Set a password which must be provided to connect to the VNC session. This is optional, but recommended.

 


Debug

 

[1]

# 放 VT 轉到另一個, Default 是在 "1:main"

# 1:main, 2:shell, 3:log, 4:storage-log, 5:program-log

%pre
exec < /dev/tty3 > /dev/tty3 2> /dev/tty3
chvt 3
...
sleep 5
chvt 1
%end

[2]

%pre --erroronfail --log=/tmp/my-pre-log
...
%end

 


kickstart run script after reboot

 

# By cron job

/etc/crontab

...
@reboot /root/firstboot > /var/log/firstboot.log 2>&1

/root/firstboot

# Cleanup job
grep -v firstboot /etc/crontab > /etc/crontab.tmp
mv -f /etc/crontab.tmp /etc/crontab
service cron restart

# do something
...

# By Service

在 ks.cfg 的 %post Section 加入以下設定

Prior to Red Hat Enterprise Linux 7:

touch /tmp/runonce
cat << EOF >> /etc/rc.local
#!/bin/bash
if [ -e /tmp/runonce ]
then
   rm /tmp/runonce
   exec > /root/runonce.log 2>&1
   /path/to/my/script      # 此 script 要做 cleanup jobs, 比如清 /etc/rc.local
fi
EOF

Red Hat Enterprise Linux 7 and later:

cat << EOF > /etc/systemd/system/runonce.service
[Unit]
Description=Run once
Requires=network-online.target
After=network-online.target

[Service]
ExecStart=/root/runonce.sh

[Install]
WantedBy=multi-user.target
EOF

chmod 664 /etc/systemd/system/runonce.service

systemctl enable runonce

 


Cleanup CD

 

#!/bin/bash

MyRootPath=/home/kickstart/myiso

rm $MyRootPath/EFI -rf
find $MyRootPath/BaseOS/Packages -name "*i686.rpm" -delete
find $MyRootPath/BaseOS/Packages -name "*-devel-*" -delete
find $MyRootPath/BaseOS/Packages -name "*-debug-*" -delete
find $MyRootPath/BaseOS/Packages -name "glibc-langpack-*" -delete

find $MyRootPath/BaseOS/Packages -name "kernel-doc-*" -delete
find $MyRootPath/BaseOS/Packages -name "kernel-headers-*" -delete
find $MyRootPath/BaseOS/Packages -name "kernel-cross-headers-*" -delete
find $MyRootPath/BaseOS/Packages -name "kernel-abi-stablelists-*" -delete

 


Sample kickstarts and snippets

 

https://github.com/CentOS/Community-Kickstarts

 


Troubleshoot

 

[1]

Rocky 8.5 System hang after output "Reached target Basic System."

原因:

isolinux/isolinux.cfg 內 append 的 LABEL 錯了

label kickstart
 menu label Kickstart
 menu default
 kernel vmlinuz
 append initrd=initrd.img inst.stage2=hd:LABEL=Rocky_x86_64 inst.ks=cdrom:/dev/cdrom:/ks.cfg ...