28. 自动化部署与镜像管理
本章介绍 RHEL 9 的两种自动化部署技术:Kickstart(无人值守网络批量安装)和 Image Builder / osbuild-composer(构建自定义系统镜像)。大规模数据中心场景中,手动安装不可扩展,这两种工具是实现标准化、可重复部署的核心手段。
28.1 前提条件
- 已完成第五阶段前序配置(第 27 章)。
- 通过 SecureCRT(SSH 端口 2222)以
ops用户、密钥认证方式登录192.168.1.100,执行sudo -i切换至 root 环境。 - Apache(httpd)已安装并运行(第 20 章),作为 Kickstart 文件的 HTTP 分发服务端。
- RHEL 9 ISO 文件已上传至服务器(存储于
/root/目录)。 - 官方仓库已启用(第 7 章)。
本章全局参数
| 参数 | 值 |
|---|---|
| 主机名 / IP | linuxdc / 192.168.1.100 |
| Kickstart 文件 URL | http://192.168.1.100/ks.cfg |
| PXE TFTP 目录 | /var/lib/tftpboot/ |
| DHCP 分配范围 | 192.168.1.150 – 192.168.1.200 |
| Image Builder Blueprint | linuxdc-base |
28.2 Kickstart 自动化安装
Kickstart 是 Red Hat 的无人值守安装技术,通过一个文本配置文件定义完整的安装流程,支持 PXE 网络引导或 ISO 内嵌两种触发方式。
28.2.1 编写 Kickstart 配置文件
将 Kickstart 文件托管在 Apache Web 根目录,供安装程序通过 HTTP 获取:
tee /var/www/html/ks.cfg << 'EOF'
# ============================================================
# Kickstart 配置 - RHEL 9 企业基线无人值守安装
# 部署目标: linuxdc | IP: 192.168.1.100
# ============================================================
# 安装源(使用 Red Hat CDN,需有效订阅;或替换为本地 ISO 地址)
url --url="https://cdn.redhat.com/content/dist/rhel9/9/x86_64/baseos/os"
# 区域与键盘
lang en_US.UTF-8
keyboard us
timezone Asia/Shanghai --utc
# 账户配置
# 生产环境:root 账户锁定,仅通过 ops 用户搭配 sudo 操作
rootpw --lock
# 用户密码使用 python3 -c "import crypt; print(crypt.crypt('密码','$6$salt'))" 生成哈希
user --name=ops --groups=wheel \
--password='$6$rounds=4096$salt$hashedpassword'
# 网络配置(根据实际环境修改 IP 参数)
network --bootproto=static \
--ip=192.168.1.100 \
--netmask=255.255.255.0 \
--gateway=192.168.1.1 \
--nameserver=8.8.8.8 \
--hostname=linuxdc \
--activate
# 磁盘分区(企业级 GPT 分区方案)
zerombr
clearpart --all --initlabel --disklabel=gpt
part /boot/efi --fstype=efi --size=512
part /boot --fstype=xfs --size=1024
part swap --fstype=swap --size=4096
part / --fstype=xfs --size=20480 --grow
# 引导加载程序
bootloader --location=mbr
# 软件包选择
%packages
@^minimal-environment
@core
chrony
openssh-server
vim-enhanced
bash-completion
net-tools
bind-utils
policycoreutils-python-utils
%end
# 安装前脚本(运行在 RAM disk 环境中)
%pre
echo "Kickstart 开始: $(date)" > /tmp/ks-install.log
%end
# 安装后脚本(运行在已安装的系统 chroot 中)
%post
set -euo pipefail
# SSH 安全配置:修改端口并禁止 root 直接登录
sed -i 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config
sed -i 's/^#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
# SELinux 放行自定义 SSH 端口
semanage port -a -t ssh_port_t -p tcp 2222
# 防火墙:放行 2222,移除默认 22
firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --permanent --remove-service=ssh
# 时间同步
systemctl enable --now chronyd
echo "安装完成: $(date)" >> /tmp/ks-install.log
%end
EOF
# 修复 SELinux 上下文,确保 Apache 可读取
restorecon -v /var/www/html/ks.cfg
# 验证 Kickstart 文件可通过 HTTP 访问
curl -s http://192.168.1.100/ks.cfg | head -5
验证 Kickstart 语法:
dnf install -y pykickstart
ksvalidator /var/www/html/ks.cfg
echo "语法检查退出码: $?"
检查点
ksvalidator 无报错输出;curl http://192.168.1.100/ks.cfg 返回文件内容。
28.2.2 配置 PXE 网络引导服务器
PXE(Preboot Execution Environment)允许无操作系统的裸机通过网络引导并自动安装,需要 DHCP、TFTP、HTTP 三个服务协同工作。
# 安装所需服务组件
dnf install -y tftp-server dhcp-server syslinux syslinux-tftpboot
# 从 RHEL ISO 提取内核和 initrd(PXE 引导所需)
mkdir -p /var/lib/tftpboot/pxelinux.cfg
mkdir -p /var/lib/tftpboot/images/rhel9
mount -o loop,ro /root/rhel-9.x-x86_64-dvd.iso /mnt/rhel-iso
cp /mnt/rhel-iso/isolinux/vmlinuz /var/lib/tftpboot/images/rhel9/
cp /mnt/rhel-iso/isolinux/initrd.img /var/lib/tftpboot/images/rhel9/
cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
cp /usr/share/syslinux/ldlinux.c32 /var/lib/tftpboot/
umount /mnt/rhel-iso
配置 PXE 引导菜单:
tee /var/lib/tftpboot/pxelinux.cfg/default << 'EOF'
DEFAULT rhel9-auto
PROMPT 0
TIMEOUT 100
LABEL rhel9-auto
MENU LABEL Auto Install RHEL 9 (Kickstart)
KERNEL images/rhel9/vmlinuz
APPEND initrd=images/rhel9/initrd.img \
inst.repo=http://192.168.1.100 \
inst.ks=http://192.168.1.100/ks.cfg \
console=ttyS0,115200n8 quiet
LABEL rhel9-manual
MENU LABEL Manual Install RHEL 9
KERNEL images/rhel9/vmlinuz
APPEND initrd=images/rhel9/initrd.img \
inst.repo=http://192.168.1.100
EOF
配置 DHCP 服务(按实际网络环境调整):
tee /etc/dhcp/dhcpd.conf << 'EOF'
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.150 192.168.1.200;
option routers 192.168.1.1;
option domain-name-servers 8.8.8.8;
# PXE 引导参数
filename "pxelinux.0";
next-server 192.168.1.100;
}
EOF
systemctl enable --now tftp.socket dhcpd
firewall-cmd --permanent --add-service=dhcp
firewall-cmd --permanent --add-service=tftp
firewall-cmd --reload
28.3 Image Builder 自定义镜像构建
Image Builder(osbuild-composer)是 Red Hat 官方的镜像构建工具,以 Blueprint(TOML 格式蓝图)描述目标系统内容,输出 ISO、QCOW2、AMI、容器镜像等多种格式,适合云和虚拟化环境的标准化部署。
28.3.1 安装与启动
dnf install -y osbuild-composer composer-cli cockpit-composer
systemctl enable --now osbuild-composer.socket
systemctl enable --now cockpit.socket
# 将 ops 用户加入 weldr 组(无需 root 即可使用 composer-cli)
usermod -aG weldr ops
# 需重新登录使组权限生效
# 验证服务状态
composer-cli status show
28.3.2 创建 Blueprint(镜像蓝图)
Blueprint 使用 TOML 格式描述镜像包含的软件包、用户配置和系统服务:
tee ~/custom-rhel9.toml << 'EOF'
name = "linuxdc-base"
description = "linuxdc 企业基线镜像 - 含安全加固与运维工具"
version = "1.0.0"
[[packages]]
name = "vim-enhanced"
version = "*"
[[packages]]
name = "bash-completion"
version = "*"
[[packages]]
name = "chrony"
version = "*"
[[packages]]
name = "openssh-server"
version = "*"
[[packages]]
name = "podman"
version = "*"
[[packages]]
name = "ansible-core"
version = "*"
# 预置运维账户
[[customizations.user]]
name = "ops"
groups = ["wheel"]
key = "ssh-ed25519 AAAA... ops@linuxdc"
# 默认启用 / 禁用的服务
[customizations.services]
enabled = ["sshd", "chronyd", "firewalld"]
disabled = ["telnet"]
# 防火墙预置规则
[customizations.firewall]
ports = ["2222:tcp"]
EOF
# 推送 Blueprint 到 Image Builder
composer-cli blueprints push ~/custom-rhel9.toml
# 验证 Blueprint 已成功注册
composer-cli blueprints list
composer-cli blueprints show linuxdc-base
28.3.3 执行镜像构建
# 查看支持的输出格式
composer-cli compose types
# 启动构建(ISO 格式,适合物理机和 VMware 部署)
composer-cli compose start linuxdc-base iso
# 监控构建状态(WAITING → RUNNING → FINISHED)
watch -n 30 composer-cli compose status
构建时间参考
首次构建 ISO 通常需要 10–30 分钟(取决于网络速度和硬件性能),过程中会拉取所需 RPM 包并组装镜像。
# 构建完成后下载镜像(替换实际 UUID)
BUILD_UUID=$(composer-cli compose status | grep FINISHED | awk '{print $1}' | head -1)
composer-cli compose image "${BUILD_UUID}"
# 将镜像移至 Web 目录供网络分发
mv "${BUILD_UUID}-disk.iso" /var/www/html/linuxdc-base.iso
restorecon -v /var/www/html/linuxdc-base.iso
# 验证可通过 HTTP 访问(返回 200 即正常)
curl -I http://192.168.1.100/linuxdc-base.iso
检查点
composer-cli compose status 显示 FINISHED;curl -I http://192.168.1.100/linuxdc-base.iso 返回 HTTP 200。
28.3.4 Blueprint 版本管理
# 更新 Blueprint 版本号后重新推送
sed -i 's/version = "1.0.0"/version = "1.1.0"/' ~/custom-rhel9.toml
composer-cli blueprints push ~/custom-rhel9.toml
# 查看 Blueprint 变更历史
composer-cli blueprints changes linuxdc-base
# 删除旧构建结果(释放磁盘空间)
composer-cli compose list
composer-cli compose delete <UUID>
28.4 常见问题与排查
| 问题现象 | 排查步骤 |
|---|---|
ksvalidator 报语法错误 |
检查错误行号;确认 %packages/%post/%pre 节均以 %end 结尾 |
| PXE 客户端未获取 IP | journalctl -u dhcpd -n 20;确认 subnet 与实际网段一致;检查 DHCP 防火墙规则 |
| TFTP 文件下载失败 | firewall-cmd --list-services | grep tftp;ausearch -m avc -ts recent 检查 SELinux |
| Image Builder 构建失败 | composer-cli compose log <UUID>;journalctl -u osbuild-composer -n 50 |
| 构建报磁盘空间不足 | df -h /var/cache/osbuild-composer;删除旧构建结果后重试 |
# Image Builder 综合诊断
journalctl -u osbuild-composer -f
composer-cli compose info <UUID>
28.5 实践任务
- 登录
linuxdc(SecureCRT 端口 2222,ops用户,密钥认证,sudo -i切换 root)。 - 编写
/var/www/html/ks.cfg,安装pykickstart,执行ksvalidator验证语法,curl确认可 HTTP 访问。 - 安装
tftp-server和dhcp-server,完成 PXE 服务配置,启动服务并验证防火墙规则。 -
安装 Image Builder,创建并推送
linuxdc-baseBlueprint,验证:composer-cli blueprints list composer-cli blueprints show linuxdc-base -
启动 ISO 构建,监控状态至少 5 分钟,查看构建日志。
28.6 自测问题
Q1:Kickstart 的 %pre 和 %post 脚本分别在什么阶段执行,各有什么典型用途?
%pre:在安装程序解析 Kickstart 文件之后、开始实际安装之前执行,运行在 RAM disk 临时环境中,目标磁盘尚未分区,常用于动态检测硬件(如磁盘名称)并生成分区配置,或执行自定义前置检查。%post:在所有软件包安装完成后执行,默认 chroot 进入已安装系统,用于配置服务(SSH 端口、防火墙)、生成 SSH 主机密钥、注册订阅、安装额外软件包等安装后配置任务。
Q2:PXE 引导需要哪三个关键服务协同工作?
DHCP:为 PXE 客户端分配临时 IP,并通过 next-server(TFTP 服务器地址)和 filename(引导文件路径)告知客户端去哪里获取引导程序;TFTP:提供 pxelinux.0 引导加载程序、Linux 内核(vmlinuz)和初始 RAM disk(initrd.img)文件的传输;HTTP(或 NFS/FTP):提供安装树(inst.repo)和 Kickstart 配置文件(inst.ks)。三者各司其职,缺一不可。
Q3:Image Builder 的 Blueprint 与 Kickstart 在定位上有什么根本区别?
Kickstart 描述的是安装过程(分区方案、网络配置、安装前后脚本等),最终产物是需要在目标机器上执行的"安装指令",目标机必须经历完整的安装流程才能就绪;Image Builder 的 Blueprint 描述的是目标系统的期望状态(包含哪些包、哪些用户、哪些服务),产物是可直接部署的完整磁盘镜像文件(ISO/QCOW2/AMI),导入即可运行,无需安装过程,更适合云实例、容器和不可变基础设施(Immutable Infrastructure)场景。
28.7 章节总结
本章完成了 RHEL 9 自动化部署的两条技术路线:Kickstart(PXE 网络引导批量无人值守安装,含企业级 GPT 分区方案和安装后 SSH/防火墙安全配置)和 Image Builder(Blueprint 驱动的自定义系统镜像构建,支持 ISO/QCOW2/AMI 多种输出格式)。两者互补:Kickstart 适合物理机和本地虚拟化场景,Image Builder 适合云端和不可变基础设施场景。