跳转至

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 显示 FINISHEDcurl -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 tftpausearch -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 实践任务

  1. 登录 linuxdc(SecureCRT 端口 2222,ops 用户,密钥认证,sudo -i 切换 root)。
  2. 编写 /var/www/html/ks.cfg,安装 pykickstart,执行 ksvalidator 验证语法,curl 确认可 HTTP 访问。
  3. 安装 tftp-serverdhcp-server,完成 PXE 服务配置,启动服务并验证防火墙规则。
  4. 安装 Image Builder,创建并推送 linuxdc-base Blueprint,验证:

    composer-cli blueprints list
    composer-cli blueprints show linuxdc-base
    
  5. 启动 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 适合云端和不可变基础设施场景。