CentOS 7.9 自动化批量装机实战:基于 PXE + Kickstart

📌 实验目的

通过在 VMware Workstation 平台模拟真实裸机批量安装操作系统,实现在大规模真实场景下批量自动化安装操作系统的应用需求,极大提升运维效率。

image

⚠️ 避坑指南:VMware 网络环境准备

在 VMware Workstation 中做 PXE 实验,最大的坑是 VMware 自带的 DHCP 服务会与你将要搭建的 DHCP 服务冲突,导致裸机无法获取正确的引导文件。在开始配置之前,请严格按照以下步骤调整:

  1. 打开 VMware Workstation。
  2. 点击顶部菜单栏的 “编辑 (Edit)” -> “虚拟网络编辑器 (Virtual Network Editor)”
  3. 点击右下角的 “更改设置 (Change Settings)” 获取管理员权限。
  4. 选中你当前虚拟机使用的网络(通常是 VMnet8 NAT模式)。
  5. 取消勾选 “使用本地 DHCP 服务将 IP 地址分配给虚拟机 (Use local DHCP service to distribute IP address to VMs)”。
  6. 点击 “确定” 保存。
  7. 确保你的模板机(PXE 服务器)已经配置了静态 IP(本实验假设为 192.168.108.10),并且能够正常上网或访问你的本地 YUM 源。

🚀 详细操作步骤

Step 1. 安装核心服务

首先,在 PXE 服务器上安装所需的底层服务:DHCP(分配 IP)、TFTP(传输引导文件)、HTTP(传输系统镜像和应答文件)以及 Syslinux(提供引导程序)。

[root@localhost ~]# yum install -y dhcp tftp-server httpd syslinux

Step 2. 配置 DHCP 服务

编辑 DHCP 配置文件,指定分配给裸机的 IP 范围、网关、DNS,最重要的是指明 PXE 引导文件及 TFTP 服务器地址。

[root@localhost ~]# cat /etc/dhcp/dhcpd.conf
# 定义子网、子网掩码
subnet 192.168.108.0 netmask 255.255.255.0 {
  range 192.168.108.200 192.168.100.210;      # 分配给裸机的 IP 范围
  option routers 192.168.108.2;               # 网关 (VMware NAT默认网关通常是.2)
  option domain-name-servers 114.114.114.114; # DNS
  default-lease-time 21600;
  max-lease-time 43200;
  
  # PXE 核心配置
  next-server 192.168.108.10;                 # TFTP 服务器的 IP 地址 (你的模板机IP)
  filename "pxelinux.0";                      # PXE 引导文件名称
}

Step 3. 配置 TFTP 服务及引导文件

TFTP 的默认根目录在 /var/lib/tftpboot/,我们需要将引导所需的各种文件放入该目录。

1. 复制引导程序

[root@localhost ~]# cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/

2. 挂载 CentOS 7.9 光盘
将 CentOS 7.9 光盘连接到虚拟机的光驱,并进行挂载:

[root@localhost ~]# mount -o loop CentOS-7-x86_64-DVD-2009.iso /mnt/cdrom
[root@localhost ~]# df -h /mnt/cdrom
文件系统        容量  已用  可用 已用% 挂载点
/dev/loop0      4.4G  4.4G     0  100% /mnt/cdrom

3. 复制内核、镜像及菜单文件

# 复制内核文件和镜像文件到 tftp 根目录
[root@localhost ~]# cp /mnt/cdrom/images/pxeboot/vmlinuz /var/lib/tftpboot/
[root@localhost ~]# cp /mnt/cdrom/images/pxeboot/initrd.img /var/lib/tftpboot/

# 复制菜单背景文件和引导菜单模块(可选,为了界面好看)
[root@localhost ~]# cp /mnt/cdrom/isolinux/vesamenu.c32 /var/lib/tftpboot/
[root@localhost ~]# cp /mnt/cdrom/isolinux/boot.msg /var/lib/tftpboot/

4. 创建 PXE 引导菜单配置文件

[root@localhost ~]# mkdir /var/lib/tftpboot/pxelinux.cfg
[root@localhost ~]# cat /var/lib/tftpboot/pxelinux.cfg/default
default vesamenu.c32
timeout 60    # 停留时间,60表示6秒后自动执行默认选项
display boot.msg

# 菜单标题
menu title CentOS 7.9 PXE Installation

label linux
  menu label ^Install CentOS 7.9 (Automated)
  menu default
  kernel vmlinuz
  # 注意:这里的 IP 需要改成你的模板机 IP。inst.ks 指向 kickstart 文件,inst.repo 指向安装源
  append initrd=initrd.img inst.repo=http://192.168.108.10/centos7 inst.ks=http://192.168.108.10/ks/ks.cfg

Step 4. 配置 HTTP 服务 (提供镜像源和 Kickstart 文件)

利用 Apache (httpd) 对外提供操作系统的安装包资源和自动应答文件。

1. 创建目录并挂载镜像

# 创建系统镜像目录和 ks 文件目录
[root@localhost ~]# mkdir -p /var/www/html/centos7
[root@localhost ~]# mkdir -p /var/www/html/ks

# 挂载光驱到 web 目录
[root@localhost ~]# mount /dev/cdrom /var/www/html/centos7/
mount: /dev/sr0 写保护,将以只读方式挂载

2. 配置永久挂载
为了防止服务器重启后失效,写入 /etc/fstab

[root@localhost ~]# cat /etc/fstab | grep cdrom
/dev/cdrom /var/www/html/centos7 iso9660 defaults 0 0

Step 5. 编写 Kickstart (ks.cfg) 自动应答文件

Kickstart 是实现“无人值守”安装的核心。将以下配置写入 /var/www/html/ks/ks.cfg

[root@localhost ~]# cat /var/www/html/ks/ks.cfg
#version=DEVEL

# 系统认证配置:启用影子密码 + 密码加密算法 SHA512
auth --enableshadow --passalgo=sha512

# 网络安装源(必须指向你的HTTP仓库)
url --url="http://192.168.108.10/centos7"

# 安装模式:图形化安装(可改成 text 文本模式更稳定)
graphical

# 首次启动不运行初始化向导
firstboot --disable

# 只使用指定硬盘 sda
ignoredisk --only-use=sda

# 键盘布局:中文
keyboard --vckeymap=cn --xlayouts='cn'

# 系统语言:中文
lang zh_CN.UTF-8

# 网络配置 DHCP自动获取 + 网卡开机自启 + IPv6自动
network --bootproto=dhcp --device=ens33 --onboot=yes --ipv6=auto

# 设置主机名
network --hostname=localhost.localdomain

# root 密码(已加密,保持不变)
rootpw --iscrypted $6$mkNUmmwyJDr0tj.Y$Wg9mU7X8bNZQEK1a72uWUX.FFEdoAl8WEoQDh3G.zkbSvtq3rijHYrgXxdZEpHEKLdbVCOtw8VJiRlGQJfx2k.

# 开机自动启用时间同步
services --enabled="chronyd"

# 时区:上海(东八区),硬件时钟使用UTC
timezone Asia/Shanghai --isUtc

# 安装GRUB引导程序到MBR,使用硬盘sda
bootloader --append="crashkernel=auto" --location=mbr --boot-drive=sda

# 清空所有磁盘分区(必须!无人值守装机核心)
clearpart --all --initlabel

# 自动分区,使用LVM格式(支持后期扩容,生产标准)
autopart --type=lvm

# 安装的软件包组
%packages
@^infrastructure-server-environment
@base
@core
@development
@file-server
@java-platform
chrony
kexec-tools
%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

# 安装完自动重启(关键!)
reboot

Step 6. 环境安全配置与服务启动

为确保网络传输不受拦截,关闭防火墙和 SELinux,并启动所有服务。

1. 关闭防火墙与 SELinux

# 关闭防火墙
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl disable firewalld

# 关闭 SELinux
[root@localhost ~]# setenforce 0
[root@localhost ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

2. 启动服务并设置开机自启

# 启动 DHCP、TFTP、HTTP 服务并加入开机自启
[root@localhost ~]# systemctl start dhcpd tftp httpd
[root@localhost ~]# systemctl enable dhcpd tftp httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/dhcpd.service to /usr/lib/systemd/system/dhcpd.service.
Created symlink from /etc/systemd/system/sockets.target.wants/tftp.socket to /usr/lib/systemd/system/tftp.socket.
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.

Step 7. 检查服务状态

使用 curl 测试 HTTP 服务是否正常对外提供系统镜像源的目录结构:

[root@localhost ~]# curl http://192.168.108.10/centos7/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
 <head>
  <title>Index of /centos7</title>
 </head>
 <body>
<h1>Index of /centos7</h1>
  <table>
   <tr><th valign="top"><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr>
   <tr><th colspan="5"><hr></th></tr>
<tr><td valign="top"><img src="/icons/back.gif" alt="[PARENTDIR]"></td><td><a href="/">Parent Directory</a>       </td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="CentOS_BuildTag">CentOS_BuildTag</a>        </td><td align="right">2020-10-30 05:14  </td><td align="right"> 14 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="EFI/">EFI/</a>                   </td><td align="right">2020-10-27 00:25  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/text.gif" alt="[TXT]"></td><td><a href="EULA">EULA</a>                   </td><td align="right">2017-08-30 22:33  </td><td align="right">227 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/text.gif" alt="[TXT]"></td><td><a href="GPL">GPL</a>                    </td><td align="right">2015-12-10 06:35  </td><td align="right"> 18K</td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="LiveOS/">LiveOS/</a>                </td><td align="right">2020-10-27 00:25  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="Packages/">Packages/</a>              </td><td align="right">2020-11-04 19:30  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="RPM-GPG-KEY-CentOS-7">RPM-GPG-KEY-CentOS-7</a>   </td><td align="right">2015-12-10 06:35  </td><td align="right">1.7K</td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="RPM-GPG-KEY-CentOS-Testing-7">RPM-GPG-KEY-CentOS-T..&gt;</a></td><td align="right">2015-12-10 06:35  </td><td align="right">1.7K</td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="TRANS.TBL">TRANS.TBL</a>              </td><td align="right">2020-11-04 19:36  </td><td align="right">2.8K</td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="images/">images/</a>                </td><td align="right">2020-10-27 00:26  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="isolinux/">isolinux/</a>              </td><td align="right">2020-11-03 00:17  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="repodata/">repodata/</a>              </td><td align="right">2020-11-04 19:35  </td><td align="right">  - </td><td>&nbsp;</td></tr>
   <tr><th colspan="5"><hr></th></tr>
</table>
</body></html>

(如出现上述输出,说明 HTTP 提供系统镜像配置成功)


🖥️ Step 8. 测试裸机批量装机 (客户端操作)

现在服务器端已经全部就绪,可以开启裸机进行测试了。

  1. 在 VMware Workstation 中点击 “文件” -> “新建虚拟机”
  2. 选择 “自定义(高级)”
  3. 硬件兼容性默认即可。
  4. 【关键步骤】 安装客户机操作系统选择 “稍后安装操作系统” (这一步非常重要,这样就是模拟无系统的真实裸机)。
  5. 系统选择 Linux -> CentOS 7 64位
  6. 给虚拟机起个名字。
  7. 分配 CPU 和 内存 (建议 2G 内存以上,防止内存不足导致安装报错)。
  8. 网络类型: 选择 “使用网络地址转换 (NAT)”。(必须与你的 PXE 服务器所在的 VMnet8 处于同一网络中)。
  9. I/O 和磁盘类型默认,创建一个新虚拟磁盘(大小默认 20G 即可),完成创建。
  10. 点击 “开启此虚拟机” (Power on)

2bc8c7447d53e7c4076948eef40c9b67

50eae78435817e2ab1be53f431d1bb5d

af94b0627d09cd3d53ae873eef4f1aea

d7fdee31cee07027a55c938a814b5c79


此时,虚拟机将通过网络启动(PXE Boot),自动获取 IP,加载内核,读取 Kickstart 文件,实现全自动的硬盘分区、格式化及包安装!静待读条完毕,系统即可自动重启进入崭新的 CentOS 7.9!🎉

posted on 2026-03-31 16:24  LeeHang  阅读(8)  评论(0)    收藏  举报