news 2026/5/28 1:10:58

UDS 正式发布:从“手动维护 200 个配置文件“到“一条命令生成全集群 PXE 配置

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UDS 正式发布:从“手动维护 200 个配置文件“到“一条命令生成全集群 PXE 配置

两个月前,我们还在用文本编辑器逐个维护每台裸金属节点的grub.cfg菜单项和user-data文件。那时完成一个 50 节点的上架批次,运维同事需要复制粘贴、修改 IP、检查 YAML 缩进三小时以上。

今天,这个过程被压缩到了30 秒

上一次的痛点,为什么手动方案走不远

如果你读过上篇关于 PXE + Ubuntu Autoinstall 的基础方案,应该记得结尾我们预告了 UDS 并列出几个硬伤:

  • 菜单爆炸:每换一种 OS 版本或分区策略,就得在grub.cfg里新增一组菜单项。
  • User-Data 碎片化:每台机器一个user-data,文件名靠 MAC 地址区分,改一个全局参数(比如 DNS)要批量 sed。
  • 网卡名称踩坑:Ubuntu 20.04 识别为ens17f0,升级到 22.04 HWE 内核变成ens17f0np0,Netplan 配置直接失效。
  • 装机后二次配置:IP 地址虽然在装机时通过 DHCP 获取,但业务 Bond 网络还是得 SSH 进去手动改 Netplan 再重启。

这些问题在节点量少的时候还能忍,但当你的集群要从 50 台扩展到 200 台、横跨两个 IDC、涉及 A100 和 4090 两种异构机型时,手动维护就是一颗定时炸弹。

我们需要一个配置即代码的渲染引擎,而不是一堆需要手工缝合的静态文件。


UDS 是什么:一个约定优于配置的 PXE 配置生成器

UDS(Unified Deployment System)是我们针对异构 GPU 数据中心开发的自动化部署配置引擎。它不替代你的 DHCP、TFTP 或 Nginx,而是坐在这些基础设施之上,把"节点清单"翻译成"可执行的 PXE 配置"。

核心设计哲学只有一条:约定优于配置(Convention over Configuration)

你不需要记住某台机器的网卡叫ens111f0np0还是ens13f0np0。只要它的 hostname 是XJ-DC1-R4090-106,UDS 就知道它是一期机房的一台 4090,默认使用 G13 网卡模型,存储布局是sda+sdb,NVLink 关闭。

# conf/nodes.yaml —— 你只需维护这一份清单nodes:-mac:"68:91:D0:70:17:97"hostname:"XJ-DC1-R4090-106"os:version:"ubuntu24043"filesystem:"ext4"network:bond0:ip:"10.2.23.11"netmask:"255.255.255.192"gateway:"10.2.23.62"

UDS 会基于这 10 行配置,自动生成:

  1. 该节点的完整user-data(含 Netplan、存储分区、late-commands)
  2. TFTP 目录下grub.cfg中对应的引导菜单项
  3. 按 MAC 地址隔离的节点配置目录结构

运行方式只有一行:

python bin/uds.py\--output-res-dir /usr/share/nginx/html/res\--output-tftp-dir /var/lib/tftpboot\--server-ip10.1.8.5

运行后,TFTP 目录下的grub.cfg会自动生成按节点区分的引导菜单,PXE 启动时可直接选择目标节点:

关键技术决策:我们是怎么做到的

1. Hostname 作为唯一事实来源

在多机型、多 IDC 环境中,最容易出错的不是配置语法,而是把 A 机型的网络模板套到了 B 机型上

UDS 的解决方案是把 hostname 当作唯一标识,通过模式匹配推断所有硬件参数:

Hostname 模式推断结果影响
包含DC1一期机房单 Bond 网络、直连存储策略
包含DC2二期机房双 Bond 网络、需配置静态路由
包含A100训练节点开启 NVLink、加载 Fabric Manager
包含R4090推理节点关闭 NVLink、标准 CUDA 安装
variant: g12旧款网卡网卡映射为ens111f0np0/ens121f0np0

这意味着运维同学只需要按照命名规范填写 hostname,系统就会自动拉取正确的网络 Profile 和存储布局,不需要去查 wiki 里的"某机型网卡对照表"。

2. 网络拓扑完全外置:profiles.yaml

把网络配置写死在代码里是 many IaC 工具的早期陷阱。UDS 把网络拓扑定义完全剥离到conf/profiles.yaml

idc2-4090:ethernets:-ens17f0-ens20f0-ens17f1-ens20f1bonds:bond0:interfaces:[ens17f0,ens20f0]parameters:{mode:802.3ad,lacp-rate:fast}bond1:interfaces:[ens17f1,ens20f1]parameters:{mode:802.3ad,lacp-rate:fast}

这样做有两个好处。一是新机型上架时,不需要改 Python 代码,加一段 YAML 即可。二是网络团队可以直接维护这份文件,无需了解生成器的内部逻辑。

3. 网卡名称兼容性:Match & Rename 机制

这是我们踩过最多的坑。同一个硬件平台,Ubuntu 20.04.6 的内核识别网卡为ens17f0,而 24.04.3 的内核识别为ens17f0np0。如果 Netplan 里写死了名称,装机后直接失联。

UDS 的解决方式是在生成的 Netplan 配置中自动注入match/set-name规则:

ethernets:ens17f0:match:name:"ens17f0*"set-name:ens17f0

无论底层实际名称是ens17f0还是ens17f0np0,Netplan 都会将其统一重命名为ens17f0,确保 Bond 配置始终生效。

这个功能通过network_unified_naming参数控制,默认关闭(显式优于隐式),仅在你确认需要跨内核版本兼容时开启。

4. 无锚点 YAML 生成策略

Cloud-init 对 YAML 的解析器比较挑剔,YAML 锚点(&id001)和别名(*id001)在某些版本下会导致解析失败。

UDS 的 YAML 生成器强制继承yaml.SafeDumper并重写ignore_aliases方法,确保输出的user-data100% 是无锚点的扁平结构。这是我们从早期测试中不断试错后加上的防御性设计。

classNoAliasDumper(yaml.SafeDumper):defignore_aliases(self,data):returnTrue

5. 动态 URL 路径计算:支持多期项目共存

在真实生产环境中,一期项目和二期项目可能共用同一台 PXE 服务器,但静态资源放在不同子目录下。UDS 根据--output-res-dir参数动态计算user-data的 HTTP URL:

  • 输出到/usr/share/nginx/html/res→ URL 指向/res/nodes/<mac>/
  • 输出到/usr/share/nginx/html/res/cxn→ URL 指向/res/cxn/nodes/<mac>/

这不需要你在代码里写 if-else,生成器会自动根据路径的相对位置拼接出正确的 URL。


Excel 导入:从采购清单到 nodes.yaml

对于批量上架场景,手动编辑 YAML 仍然不够快。UDS 提供了excel_to_nodes.py工具,允许你从采购部门提供的 Excel 表格直接生成配置。

# 1. 生成标准模板python bin/excel_to_nodes.py--template# 2. 采购部填完 MAC、IP、Hostname 后发回# 3. 一键转换python bin/excel_to_nodes.py-iinventory.xlsx-oconf/nodes.yaml

模板中包含智能默认值:OS 版本默认ubuntu22044,文件系统默认xfs,NVIDIA 驱动默认575。你只需要填写关键列(MAC、Hostname、IP),其余留空即可。


生成器内部架构

UDS 的架构刻意保持极简,没有数据库、没有守护进程、没有 Web UI,只有三个核心组件:

  • uds.py:主生成逻辑,负责推断、渲染、输出。
  • user-data.template:Jinja2 模板,定义了 Autoinstall 的完整结构。
  • profiles.yaml:网络拓扑定义,纯数据无逻辑。

我们尝试过但没走的路

在决定自研 UDS 之前,我们评估过 MAAS 和 Ironic:

维度UDSMAASIronic
架构复杂度无状态脚本PostgreSQL + Region/Rack 控制器依赖 OpenStack 组件群
网络管控依赖外部 DHCP,专注配置生成内置 DHCP/DNS/IPAM依赖 Neutron
上手成本5 分钟数小时到数天数周

MAAS 的功能确实更全,但在我们的场景里,网络基础设施(交换机、DHCP Relay)已经由网络团队维护好了,我们只需要一个"把操作系统和驱动装上去"的工具。引入 MAAS 意味着多一套需要监控和排错的分布式系统,收益不成正比。

如果你的需求是"从零构建一个完整的数据中心网络",MAAS 是合理的选择。但如果你已经有网络,只想快速批量装机,UDS 这种轻量级配置引擎更划算。


从手动到自动:效率对比

过去维护 50 个节点需要:

  • 手动编辑 50 个user-data文件
  • 手动维护grub.cfg中的 50 个菜单项
  • 每次改全局参数都要批量 sed

现在只需要维护一份nodes.yaml或一个 Excel 表格,一条命令生成全部配置。改 DNS、换 ISO 镜像、调整 Bond 参数,都只需要改一处。


已知限制和后续规划

UDS 目前不是万能药,有几个明确的边界:

  1. 无状态管理:UDS 只负责生成配置,不追踪节点的装机进度或健康状态。装机后的监控仍需配合现有监控系统。
  2. 无 Web UI:所有操作通过命令行和 YAML 完成。如果需要图形界面,目前得自己包一层。
  3. DHCP 外部依赖:UDS 不替代 DHCP 服务,你需要确保网络侧的 DHCP Relay 已经指向 PXE 服务器。

后续我们计划在 UDS 的基础上增加:

  • GPU 交付验收报告:装机完成后自动检查 GPU 拓扑、CUDA 版本、驱动状态,输出 HTML 报告。
  • 批量巡检脚本:跨节点的配置一致性校验。

如何开始

项目已开源,核心代码只有约 700 行 Python。

gitclone https://gitee.com/path_fly/unified-deployment-system.gitcdunified-deployment-system python-mvenv .venvsource.venv/bin/activate pipinstall-rrequirements.txt# 编辑 conf/nodes.yaml,填入你的节点信息# 运行生成器python bin/uds.py\--output-res-dir /usr/share/nginx/html/res\--output-tftp-dir /var/lib/tftpboot\--server-ip YOUR_PXE_IP

详见项目中的 QUICKSTART.md 获取完整操作指南,包括 Excel 工具的使用方法和多机型场景的进阶配置。


FAQ

Q: UDS 能管理装机后的节点状态吗?
A: 不能。UDS 只生成配置,不监控装机进度。装机完成后建议配合现有监控系统使用。

Q: 支持 Red Hat / CentOS 吗?
A: 目前只支持 Ubuntu Autoinstall。如果要支持 Kickstart,需要新增一套模板和渲染逻辑。

Q: 新机型上架需要改代码吗?
A: 不需要。只要新机型遵循 hostname 命名规范,在conf/profiles.yaml中新增一段网络拓扑定义即可。

Q: 为什么默认关闭network_unified_naming
A: 显式优于隐式。如果你的 Profile 已经精确匹配了硬件网卡名称,不需要额外的 match 规则。只有在跨内核版本出现命名不一致时才建议开启。


相关阅读

  • 上篇:PXE + Ubuntu Autoinstall 基础方案详解(DHCP / TFTP / Nginx 手动配置全流程)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 1:10:04

C64 BASIC 游戏地图“相机视角”实现:从初稿到优化,性能提升有妙招!

Retro Game Coders 社区介绍Retro Game Coders 是一个复古电脑/游戏机游戏 开发社区&#xff0c;提供了丰富的复古资源&#xff0c;如复古游戏时间线、在线复古 IDE、复古像素艺术编辑器等。C64 BASIC 游戏地图“相机视角”问题提出关于如何创建《创世纪》风格地图视图的解释&…

作者头像 李华
网站建设 2026/5/28 1:08:42

从实验室到产线:摄像头模组TV Line测试全流程实操与验收标准详解

从实验室到产线&#xff1a;摄像头模组TV Line测试全流程实操与验收标准详解在消费电子领域&#xff0c;摄像头模组的成像质量直接影响用户体验&#xff0c;而分辨率作为核心指标之一&#xff0c;其测试方法的科学性与可重复性尤为重要。TV Line测试作为行业广泛采用的主观评估…

作者头像 李华
网站建设 2026/5/28 1:05:05

java复习笔记(2)

一、抽象类与抽象方法 抽象类用 abstract 关键字修饰&#xff0c;它不能被直接实例化&#xff08;不能用 new 创建对象&#xff09;&#xff0c;核心作用是作为父类&#xff0c;让子类继承。抽象类里可以包含普通方法&#xff0c;也可以包含抽象方法——也就是只有方法声明…

作者头像 李华
网站建设 2026/5/28 1:03:26

如何快速搭建英雄联盟客户端工具箱:LeagueAkari完整配置指南

如何快速搭建英雄联盟客户端工具箱&#xff1a;LeagueAkari完整配置指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power &#x1f680;. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit LeagueAkari是一款基于…

作者头像 李华
网站建设 2026/5/28 1:02:21

Sumatra PDF进阶指南——自定义快捷键与高效配置

1. 为什么需要自定义Sumatra PDF快捷键&#xff1f; 第一次接触Sumatra PDF时&#xff0c;我就被它极简的设计和飞快的启动速度吸引了。但用久了发现&#xff0c;默认的快捷键布局并不完全符合我的工作习惯。作为一名经常需要同时处理多个PDF文档的技术写作者&#xff0c;我发现…

作者头像 李华