3. kickstart自动安装
- pxe服务器
- 硬件基本信息
- CPU大于4核
- 内存大于4G
- 硬盘大于50G
- 系统基本信息
- 系统版本:centos7.4
- selinux:关闭
- Firewalld:关闭
- yum源:阿里云的yum源
- 硬件基本信息
- client服务器
- 硬件基本信息
- CPU大于4核
- 内存大于4G
- 硬盘大于50G
- 支持网络启动
- 硬件基本信息
3.1. 定义安装参数
通过配置文件的参数,来配置系统的一些选项。
sn | hostname | 根大小 | 磁盘剩余空间挂载点 | swap分区大小 | 文件系统格式 | 是否做bond | ip地址 | 掩码 | 网关 | 系统版本 |
---|---|---|---|---|---|---|---|---|---|---|
VMware-564da23a647f0edd-a62ca6791920304a | client.test.com | 50 | /data | 8 | xfs | bondno | 192.168.17.129 | 255.255.255.0 | 192.168.17.2 | centos-8.1-x86_64 |
文件路径:/var/www/html/install/server.conf。示例:
[root@pxe01 ~]# cat /var/www/html/install/server.conf
#sn hostname 根大小 剩余空间挂载点 swap分区大小 文件系统格式 ip地址 掩码 网关 系统版本
VMware-564da23a647f0edd-a62ca6791920304a client.test.com 50 /data 8 xfs bondno 192.168.17.129 255.255.255.0 192.168.17.2 centos-8.1-x86_64
VMware-564da23a647f0edd-a62ca6791920304b client.test.com all --- 0 ext4 bondno 192.168.17.130 255.255.255.0 192.168.17.2 centos-8.0-x86_64
3.2. KS文件和脚本
- kickstart文件路径:/var/www/html/centos8-pxe/ks/centos8.ks
#version=RHEL8
#ignoredisk --only-use=sdm
%include "/tmp/os_disk"
# Clear the Master Boot Record
zerombr
# Partition clearing information
clearpart --all --initlabel
# Use graphical install
graphical
%include /tmp/tarball
#repo --name="AppStream" --baseurl="http://192.168.17.128/iso/centos8u1/AppStream"
# SELinux configuration
selinux --disabled
# Firewall configuration
firewall --disabled
# Reboot after installation
reboot
# Use network installation
#url --url="http://192.168.17.128/iso/centos8u1"
# Keyboard layouts
keyboard --vckeymap=us --xlayouts='us'
# System language
lang en_US.UTF-8
# Network information
#network --hostname=localhost.localdomain
%include "/tmp/hostname"
# Root password
rootpw "123456"
# Do not configure the X Window System
skipx
# Run the Setup Agent on first boot
firstboot --disabled
# Installation logging level
logging --level=info
# System services
services --disabled="chronyd"
# System timezone
timezone Asia/Shanghai --isUtc --nontp
# System bootloader configuration
bootloader --append="net.ifnames=0 biosdevname=0 rd.driver.pre=mlx5_core,i40e,ixgbe"
# Disk partitioning information
%include "/tmp/part_info"
%packages
%include "/tmp/packages"
kexec-tools
#@^server-product-environment
#@^infrastructure-server-environment
%end
%addon com_redhat_kdump --enable --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
%pre
echo "pre script" |tee /tmp/pre.txt
wget -O pre_script.sh http://192.168.17.128/centos8-pxe/scripts/pre_script.sh
bash pre_script.sh |tee -a /tmp/pre.txt
%end
%post
echo "post script" |tee /tmp/post.txt
wget -O post_script.sh http://192.168.17.128/centos8-pxe/scripts/post_script.sh
bash post_script.sh |tee -a /tmp/post.txt
%end
- pre_script文件路径:/var/www/html/centos8-pxe/scripts/pre_script.sh
#!/bin/bash
function get_install_info()
{
export sn=$(dmidecode -t1 |grep 'Serial Number:' |awk -F ':' '{print $NF}' |tr -d ' ')
if [ ! -f "/tmp/server.conf" ]; then
wget -O /tmp/server.conf http://192.168.17.128/install/server.conf
fi
return 0
}
function set_hostname()
{
local thisconf=$(cat /tmp/server.conf |grep -v ^# |grep $sn |tail -n1)
if [ -z "$thisconf" ]; then
echo "not find $sn"
exit 0;
fi
local hostname_info=$(echo $thisconf |awk '{print $2}')
echo "network --hostname=$hostname_info" >/tmp/hostname
return 0
}
function set_tarball()
{
local thisconf=$(cat /tmp/server.conf |grep -v ^# |grep $sn |tail -n1)
if [ -z "$thisconf" ]; then
echo "not find $sn"
exit 0;
fi
local tarball=$(echo $thisconf |awk '{print $11}')
if [ "$tarball" == "centos-8.1-x86_64" ]; then
echo "repo --name=\"AppStream\" --baseurl=\"http://192.168.17.128/iso/centos8u1/AppStream\"" >/tmp/tarball
echo "url --url=\"http://192.168.17.128/iso/centos8u1\"" >>/tmp/tarball
echo "@^server-product-environment" >/tmp/packages
elif [ "$tarball" == "centos-8.0-x86_64" ]; then
echo "repo --name=\"AppStream\" --baseurl=\"http://192.168.17.128/iso/centos8u0/AppStream\"" >/tmp/tarball
echo "url --url=\"http://192.168.17.128/iso/centos8u0\"" >>/tmp/tarball
echo "@^server-product-environment" >/tmp/packages
elif [ "$tarball" == "centos-7.4-x86_64" ]; then
echo "url --url=\"http://192.168.17.128/iso/centos7u4\"" >/tmp/tarball
echo "@^infrastructure-server-environment" >/tmp/packages
fi
return 0
}
OS_DEV=""
OS_DEV_NAME=""
#获取最小磁盘作为系统盘,大于50G,小鱼1000G
function get_os_disk()
{
fdisk -l &>disk.txt
local disk_os_size=""
local disk_os_label=""
if [ $(cat disk.txt |grep 'Disk /dev/' |wc -l) -eq 1 ]
then
disk_os_label=$(cat disk.txt |grep 'Disk /dev/' |egrep -o '/dev/sd[a-z]{1,2}')
else
for disk_min in $(cat disk.txt |grep 'Disk /dev/' |awk '{print $5}' |sort -un)
do
if [[ $disk_min -gt 50022480896 ]] && [[ $disk -lt 1000592982016 ]]
then
disk_os_size=$disk_min
break
fi
done
disk_os_label=$(cat disk.txt |grep $disk_os_size |egrep -o '/dev/sd[a-z]{1,2}' |sort |head -n1)
fi
if [ -z "$disk_os_label" ]
then
disk_os_label="/dev/sda"
fi
export OS_DEV="$disk_os_label"
echo "$disk_os_label" >/tmp/os_disk.txt\
local os_disk=$(echo "$OS_DEV" |cut -d '/' -f3)
export OS_DEV_NAME="$os_disk"
echo "ignoredisk --only-use=$os_disk" >/tmp/os_disk
}
function std_disk_part()
{
parted -s "$OS_DEV" mklabel gpt
local thisconf=$(cat /tmp/server.conf |grep -v ^# |grep $sn |tail -n1)
if [ -z "$thisconf" ]; then
echo "not find $sn"
exit 0;
fi
local root_space=$(echo $thisconf |awk '{print $3}')
local data_space=$(echo $thisconf |awk '{print $4}')
local swap_space=$(echo $thisconf |awk '{print $5}')
local file_format=$(echo $thisconf |awk '{print $6}')
# 如果根大小的参数为all,那么不创建剩余空间挂载点
if [ "$root_space" == "all" ]; then
local root_mount="part / --fstype=\"$file_format\" --ondisk=$OS_DEV_NAME --grow --size=1"
local data_mount=""
else
root_space=$[ $root_space * 1024 ]
local root_mount="part / --fstype=\"$file_format\" --ondisk=$OS_DEV_NAME --maxsize=$root_space --size=1 --grow"
local data_mount="part $data_space --fstype=\"$file_format\" --ondisk=$OS_DEV_NAME --size=1 --grow"
fi
# 如果swap的参数为0,则不创建swap分区,否则创建
if [ "$swap_space" == "0" ]; then
local swap_mount=""
else
swap_space=$[ $swap_space * 1024 ]
local swap_mount="part swap --fstype=\"swap\" --ondisk=$OS_DEV_NAME --size=$swap_space"
fi
cat << EOF >/tmp/part_info
part biosboot --fstype="biosboot" --ondisk=$OS_DEV_NAME --size=2
part /boot --fstype="$file_format" --ondisk=$OS_DEV_NAME --size=1536
$swap_mount
$root_mount
$data_mount
EOF
return 0
}
function efi_disk_part()
{
#parted -s /dev/sda mklabel gpt
parted -s "$OS_DEV" mklabel gpt
local thisconf=$(cat /tmp/server.conf |grep -v ^# |grep $sn |tail -n1)
local root_space=$(echo $thisconf |awk '{print $3}')
local data_space=$(echo $thisconf |awk '{print $4}')
local swap_space=$(echo $thisconf |awk '{print $5}')
local file_format=$(echo $thisconf |awk '{print $6}')
if [ "$root_space" == "all" ]; then
local root_mount="part / --asprimary --fstype=\"$file_format\" --grow --size=1"
local data_mount=""
else
root_space=$[ $root_space * 1024 ]
local root_mount="part / --asprimary --fstype=\"$file_format\" --maxsize=$root_space --size=1 --grow"
local data_mount="part /$data_space --asprimary --fstype=\"$file_format\" --grow --size=1"
fi
# 如果swap的参数为0,则不创建swap分区,否则创建
if [ "$swap_space" == "0" ]; then
local swap_mount=""
else
swap_space=$[ $swap_space * 1024 ]
local swap_mount="part swap --fstype=\"swap\" --ondisk=$OS_DEV_NAME --size=$swap_space"
fi
cat << EOF >/tmp/part_info
part /boot/efi --asprimary --fstype="efi" --size=500 --fsoptions="umask=0077,shortname=winnt"
part /boot --asprimary --fstype="$file_format" --size=1536
$swap_mount
$root_mount
$data_mount
EOF
return 0
}
function main()
{
get_install_info
set_hostname
set_tarball
get_os_disk
if [ -e "/sys/firmware/efi" ]; then
efi_disk_part
return 0
else
std_disk_part
return 0
fi
return 0
}
#------------------
main
- post_script文件路径:/var/www/html/centos8-pxe/scripts/post_script.sh
#!/bin/bash
function get_net_info()
{
export sn=$(dmidecode -t1 |grep 'Serial Number:' |awk -F ':' '{print $NF}' |tr -d ' ')
if [ ! -f "/tmp/server.conf" ]; then
wget -O /tmp/server.conf http://192.168.17.128/install/server.conf
fi
local thisconf=$(cat /tmp/server.conf |grep $sn |tail -n1)
export bondyes=$(echo $thisconf |awk '{print $7}')
export ip=$(echo $thisconf |awk '{print $8}')
export mask=$(echo $thisconf |awk '{print $9}')
export default_gw=$(echo $thisconf |awk '{print $10}')
return 0
}
function set_eth0()
{
local eth="eth0"
cat << EOF > /etc/sysconfig/network-scripts/ifcfg-$eth
TYPE=Ethernet
DEVICE=$eth
ONBOOT=yes
BOOTPROTO=none
IPADDR=$ip
NETMASK=$mask
EOF
echo "GATEWAY=$default_gw" >>/etc/sysconfig/network
return 0
}
function set_bond0()
{
local eth0="eth0"
local eth1="eth1"
local bondname="bond0"
cat << EOF > /etc/sysconfig/network-scripts/ifcfg-$eth0
DEVICE=$eth0
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=none
MASTER=$bondname
SLAVE=yes
HOTPLUG=no
EOF
cat << EOF > /etc/sysconfig/network-scripts/ifcfg-$eth1
DEVICE=$eth1
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=none
MASTER=$bondname
SLAVE=yes
HOTPLUG=no
EOF
cat << EOF > /etc/sysconfig/network-scripts/ifcfg-$bondname
DEVICE=$bondname
TYPE=bond
ONBOOT=yes
BOOTPROTO=none
USERCTL=no
BONDING_OPTS="mode=4 miimon=100 xmit_hash_policy=layer2+3"
IPADDR=$ip
NETMASK=$mask
EOF
echo "GATEWAY=$default_gw" >>/etc/sysconfig/network
return 0
}
function main()
{
get_net_info
if [ "$bondyes" == "bondyes" ]; then
set_bond0
else
set_eth0
fi
return 0
}
#--------------------------
main
- 向default文件添加ks参数
default vesamenu.c32
#prompt 1
timeout 600
#display boot.msg
menu background splash.jpg
menu title Welcome to CentOS 8.X!
menu color border 0 #ffffffff #00000000
menu color sel 7 #ffffffff #ff000000
menu color title 0 #ffffffff #00000000
menu color tabmsg 0 #ffffffff #00000000
menu color unsel 0 #ffffffff #00000000
menu color hotsel 0 #ff000000 #ffffffff
menu color hotkey 7 #ffffffff #ff000000
menu color scrollbar 0 #ffffffff #00000000
label local
menu label Boot from local drive
localboot 0xffff
label linux
menu label CentOS 8.X
menu default
kernel http://192.168.17.128/centos8-pxe/vmlinuz
append initrd=http://192.168.17.128/centos8-pxe/initrd.img net.ifnames=0 biosdevname=0 rd.driver.pre=mlx5_core,i40e,ixgbe ksdevice=bootif inst.gpt inst.stage2=http://192.168.17.128/centos8-pxe
inst.ks=http://192.168.17.128/centos8-pxe/ks/centos8.ks
ipappend 2
3.3. 自动安装测试
成功
3.4. 解决的问题
- 多台服务器同时安装系统的问题
不同的操作系统,不同的分区 - 安装centos7的时候,文件系统格式要选ext4,否则不成功