Skip to content

Kickstart + 内网源 + Ansible:48 节点版本一致性的批量交付 ​

48 台机器逐台手工装系统、装驱动、调参数,结局必然是"每台机器都不一样"。版本漂移是中小集群交付里最隐蔽的债务——它在第 3 个月的性能对比、第 6 个月的故障排查时一次性爆发。本文记录 384 卡 L40S IB 集群如何用 Kickstart + 内网源 + Ansible 把 48 节点钉在同一个软件版本上。

1. 为什么"版本一致性"是交付的核心目标 ​

交付方式节点间差异可复现性故障排查
逐台手工安装高(路径、版本、参数随手改)无每台都要重新对账
共享镜像克隆中(镜像更新后新旧混杂)弱不知道哪台是哪版
Kickstart + 统一源 + Ansible低(同一答案文件 + 同一源)强全节点对账 = 对一份配置

判断:版本一致性买的不只是"省事",是可复现性——出问题时能确定"这台机器跑的是什么",性能不达标时能排除"环境差异"这个变量。

2. Kickstart:把"装系统"变成声明式 ​

  • 一份 ks.cfg 覆盖分区、时区、软件包组、root 策略、SSH 配置;
  • 内网 PXE/DHCP 引导:48 节点批量装机,全程无人工干预;
  • 系统盘 RAID1(2×480G SATA)在 Kickstart 里用 %pre 脚本预配置(storcli 建卷、写缓存 Enabled),避免装完才发现 RAID 没组好。

踩坑点:

  1. %pre 里组 RAID 的脚本要幂等——重复装机时卷已存在,先删卷再建;
  2. 固件/BIOS 差异会导致同型号机器盘序不同,用盘符而不是序号做 RAID 成员;
  3. Kickstart 装完第一件事就是拉内网源刷新,别让节点从公网装包。

3. 内网源:版本一致性的地基 ​

  • 统一 YUM 源:openEuler 24.03 基础源 + EPOL 镜像到内网,全部节点 baseurl 指向内网;
  • 统一 pip 源:训练依赖(PyTorch、NCCL 相关 Python 包)从内网 PyPI 镜像装,锁版本号;
  • 关键包锁定:内核、驱动、CUDA 栈、NCCL 的版本在构建清单里写死,不是"装最新"。

判断:内网源不是为了"快",是为了把公网漂移从交付里拿走——公网源今天和明天给的包可能不一样,内网源是冻结的。

4. Ansible:配置下发,禁止手工漂移 ​

  • 所有配置(内核参数、中断亲和、sysctl、NCCL 环境、MPI 环境)以 Ansible role 统一下发;
  • 禁止单机手工改:凡是"先改这台试试"的,最终都要回流成 role;
  • 幂等性:role 重跑 N 次结果一致,交付时全节点跑一遍 playbook 就是对账。

验证命令:

bash
# 全节点软件栈对账:跑同一 playbook + 比对关键包版本
ansible-playbook -i hosts.ini site.yml --check
ansible all -m shell -a "rpm -q kernel mlx5_objs cuda-12-x" | sort | uniq -c | wc -l
# 输出 1 行 = 48 台版本完全一致

5. 验收:一致性怎么证明 ​

检查项判定
关键包版本48 台 rpm -q 输出完全一致(去重后 1 条)
内核参数/proc/cmdline 与 sysctl 关键项全节点一致
配置文件 hash/etc/ 关键文件 sha256 一致(Ansible --check 0 变更)
随机抽查任选 2 台跑同一基准(STREAM/NCCL),结果在噪声内

6. 交付清单 ​

  1. Kickstart:RAID 预配置幂等脚本 + 内网引导,48 台批量装机;
  2. 内网源:YUM + pip 全部指向内网,关键版本锁进构建清单;
  3. Ansible:全部配置 role 化,--check 零变更;
  4. 一致性验收:包版本、内核参数、配置 hash 三查全过;
  5. 记录基线镜像 tag,作为后续变更的 diff 基准。

本文基于 384 卡 L40S IB 集群交付实测整理;具体版本号与命令以现场实测为准。

AI-HPC 智算超算专家 · Contact: openaihpc@gmail.com