ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

openFuyao v25.09部署实践:构建企业级异构算力调度平台

openFuyao v25.09部署实践:构建企业级异构算力调度平台 先说结论openFuyao v25.09 这个版本是我目前见过把“异构算力调度”这件事做得最接地气的一套开源方案。它不是一个花架子调度器而是真正能把 H100、V100、国产加速卡、CPU 池子统一纳管按任务需求动态匹配资源的那类平台。这篇文章就从我这次完整部署的视角把从零到一构建企业级异构算力调度平台的整个过程、踩过的坑、以及核心配置逻辑都捋一遍。如果你正在做 AI Infra、平台工程、或者公司内部在搞 GPU 资源池化但一直觉得“贵、乱、利用率上不去”那这篇内容应该能帮你省下不少试错时间。1. 先搞清楚要解决什么问题异构算力调度的痛点1.1 GPU 很贵但大多时候在睡觉很多团队的第一个坎不是不会装 GPU 驱动而是装完之后资源利用率低到不好意思看监控。我见过太多公司买了一批 V100部门 A 跑训练任务独占整卡实际上一天只用了三小时部门 B 要跑推理服务却永远申请不到卡。更麻烦的是集群里混着 A100、H100、各种国产卡要手动给每个任务挑机型排期全靠聊天记录。这种状态下算力再多也是碎片化的。这个问题的本质是“资源供给”和“任务需求”之间缺乏一层抽象。Kubernetes 原生调度器能识别nvidia.com/gpu这种资源但它只告诉你“这张卡存在”不会告诉你“这张卡是 H100还是 V100、显存多大、是否支持 NVLink、当前在哪个 NUMA 节点上”。而恰恰是这些信息决定了任务能不能跑、跑得快不快。openFuyao 做的事情就是把这一层补上。它不是要替代 Kubernetes而是站在 Kubernetes 的肩膀上把 GPU、NPU、CPU 这些异构资源重新描述成可以被精细调度的标签池然后按照任务需求去匹配。1.2 openFuyao 的解题思路把异构资源“标签化”这套平台最核心的思想就是把一切异构资源变成一套统一的、带语义的标签体系。举例来说一张 H100 在 openFuyao 眼里不是简单的“一张 GPU”而是一个带有fuyao.io/gpu-modelH100、fuyao.io/gpu-memory80Gi、fuyao.io/nvlink8、fuyao.io/pcie-bandwidthGen5x16等标签的资源对象。这些标签一部分由节点上的 agent 自动采集上报一部分由管理员按实际拓扑修正。任务提交的时候你用模板声明需求model A100、显存 40Gi、需要 P2P 通信。调度器拿到这份需求在资源池里做过滤和打分最终选出最合适的节点和卡。整个过程对业务方透明对资源方也透明。这种设计最大的好处是避免了“硬编码机型”的痛点。业务不用关心具体哪台机器只要描述需求平台管理员也不用为每一种新卡写一套适配逻辑只要给新卡打上正确标签它就能自动进入调度池。这也是我在这次部署中觉得最值回票价的设计。2. 部署前的架构拆解与版本选型2.1 组件角色分配先给不熟悉的同学梳理一下 openFuyao v25.09 部署完之后的组件大家庭每个组件干什么事理解了角色再动手会顺手很多。组件角色部署位置kube-fuyao-scheduler核心调度器负责Pod的过滤、打分、绑定控制面集群独立Deploymentkube-fuyao-controller负责CRD状态同步、GPU插卡/卸载、节点标签维护、配额管理控制面集群Deploymentfuyao-agent节点侧代理采集GPU拓扑、PCIe链路、健康状态执行插卡/卸载指令计算节点通过DaemonSet部署fuyaoctl命令行工具用于多集群纳管、查看调度决策、资源池管理管理端或运维跳板机fuyao-webconsole可视化控制台看资源地图、任务排队、调度日志可选建议内网部署这套组件分层是经过考量的。controller 和 scheduler 分离好处是调度链路和状态同步链路互不阻塞agent 用 DaemonSet 方式部署天然跟随节点生命周期web 控制台作为可选组件不对核心调度链路构成单点依赖。我在生产环境里没有把 web 控制台部署在计算集群内部而是单独放在运维网段避免控制台本身成为故障放大器。这也是我这次部署中比较满意的一个决策。2.2 为什么调度器要独立部署而不是魔改 kube-scheduler有人可能会问既然 Kubernetes 已经提供了调度器扩展机制为什么 openFuyao 还要搞一个独立的调度器我的理解是kube-scheduler 的扩展点比如 Filter、Score、Reserve、Permit能做一些定制但你把异构算力调度逻辑全塞进去之后会让升级 Kubernetes 变成一场灾难。每次 K8s 版本升级你都要重新验证调度器扩展的兼容性稍不留神就是线上调度行为异常。而 openFuyao 把调度器作为一个独立组件部署它只需要通过 Kubernetes API 监听 Pod 和节点变化用 informer 机制拿到全量状态再用自己的调度算法决策。这样 Kubernetes 集群自身的升级完全不影响调度器自由度也更大。用一个生活化的类比来说kube-scheduler 是公司前台负责把访客带到会议室openFuyao 是业务负责人知道谁该去哪个项目组、坐哪张工位。前台的职责不要抢业务负责人的职责更不该被前台流程束缚。v25.09 版本在调度器高可用上也做得比较务实支持多副本 active-standby 模式。多个调度器副本通过 leader election 机制竞争主节点主节点挂了备用节点接管。实际压测中主节点切换时间在 10 秒以内对于内部算力平台来说这个切换耗时完全可接受。2.3 为什么选 v25.09选版本这件事我的原则向来是“不追新不守旧”。openFuyao v25.09 是我评估下来当前比较均衡的一个发行版。这个版本有几个值得关注的特性特性说明实际价值多集群联邦支持多个 K8s 集群统一纳管跨集群资源聚合视图一个控制台看全公司算力GPU 插卡/卸载通过 agent 在节点上动态配置 GPU 设备不需要重启机器运维不用半夜跑机房插卡模板匹配增强支持运算符约束、、范围匹配业务需求表达更精确DAG 任务依赖具备 DAG 感知调度时能考虑任务拓扑顺序适合多阶段训练、推理管线拓扑感知调度PCIe/NVLink 链路感知支持亲和性策略多卡任务通信效率大幅提升如果你的集群里只有清一色的同型号 GPUv25.09 的很多特性确实用不上。但只有当你真正开始混部 H100 和 V100、或者把国产加速卡纳入资源池时这些特性才会体现巨大的价值。3. 服务器准备从硬件规划到依赖安装3.1 部署形态选择openFuyao v25.09 官方推荐的是“一级集群 计算集群”的联邦形态。控制面组件放在一级集群通常是一个不跑业务负载的 K8s 集群各计算集群通过 agent 上报状态由一级集群统一调度。我第一次部署的时候图省事想直接在一个集群里又把控制面又跑业务结果后续做联邦测试时折腾了整整一下午。后来老老实实拆成两个集群清爽很多。控制面集群不需要 GPU两节点 4C8G 起步即可计算集群按实际算力规模规划。控制面和计算集群之间网络要求不高只要能稳定访问 K8s API Server 即可。如果你的机房网络比较差建议在 agent 侧开消息压缩v25.09 默认已经开启但带宽小于 10Mbps 的链路最好还是单独评估。3.2 操作系统与基础组件计算节点操作系统建议使用 Ubuntu 22.04 LTS 或兼容版本内核版本不低于 5.15。重点关注几个点关闭不必要的防火墙规则或者给调度组件的端口开白名单确保/var/lib/kubelet所在磁盘空间充足GPU 插卡模块会在这里占一些磁盘系统时间统一用 NTP 同步openFuyao 的证书和心跳检测对时钟漂移比较敏感我遇到过一次节点时钟漂了 20 秒agent 上报的心跳总是超时在控制台里看节点状态一直 flapping。排查了半天才发现是 NTP 服务没起来。所以部署前一定要检查timedatectl的输出保证System clock synchronized: yes。GPU 节点需要预先装好 NVIDIA 驱动和 nvidia-container-toolkit。openFuyao 本身不负责装驱动它假设节点已经有 GPU 能力。但你如果用的是国产加速卡需要确认厂商是否提供了适配 Kubernetes 设备插件的驱动没有的话要先和厂商要支持。3.3 Kubernetes 版本与证书准备依赖项版本要求备注Kubernetes1.26 以上需要使用 CSI 和 DevicePlugin 的标准能力Helm3.8 以上官方 chart 依赖少量新特性etcd集群自带即可控制面复用现有 etcd不需要单独部署cert-manager1.11 以上用于 webhook 证书管理证书方面建议直接让 chart 自动生成自签名证书内部域名使用svc.cluster.local。除非你的集群已经接了企业内部 CA否则不需要在证书上花太多功夫。我尝试过用企业 CA 签发证书后来发现 webhook 的 SAN 列表容易写错不如直接用自签名省心。网络方面如果 Kubernetes 集群开启了 NetworkPolicy需要给调度器、controller、agent 之间的通信端口放行。具体端口号在 chart values 里有定义默认情况为调度器 10261、controller 10262、agent 10263建议在部署前就把这些端口固定下来避免后续防火墙规则混乱。4. 使用 Helm 完成 v25.09 部署4.1 添加仓库与拉取 chart部署的第一步是获取官方 chart。我假设你已经有 Helm 3 环境helm repo add openfuyao https://charts.openfuyao.io/stable helm repo update helm search repo openfuyao搜索到openfuyao/openfuyao且版本号为25.09.x即可。我这次部署用的是25.09.1属于 v25.09 的补丁版本建议生产环境至少打到这个版本以上。4.2 关键的 values.yaml 参数配置values.yaml 是这次部署的重头戏我直接放一份我实际使用的核心配置再把每个参数的意图讲清楚。global: clusterName: primary imageRegistry: registry.internal.example.com scheduler: replicas: 2 schedulerName: openfuyao-scheduler resources: requests: cpu: 500m memory: 512Mi limits: cpu: 2 memory: 2Gi algorithm: filterStrategy: strict scoreStrategy: binpacking topologyAware: true p2pAware: true controller: replicas: 2 syncIntervalSeconds: 30 enableGPUVirtualization: false agent: enableGPUDetect: true enableTopologyCollect: true gpuVendor: nvidia devicePlugin: enabled: true nodeSelector: fuyao.io/gpu-node: truefilterStrategy: strict表示过滤阶段严格执行标签约束不满足条件的节点直接剔除。如果业务需求经常写得很模糊建议改成loose让调度器尝试按打分排序而不是直接拒绝。scoreStrategy: binpacking是装箱策略适合资源紧张的场景任务会尽量集中到少数节点把空闲节点腾出来。如果你的业务对高可用要求更高可以改成spread让任务分散在不同节点避免单节点故障影响多个任务。enableGPUVirtualization: false表示不启用 GPU 虚拟化分片。如果你后续要做显存切分可以把这里打开但 v25.09 的虚拟化对某些 CUDA 版本有兼容性要求建议先在测试环境验证。agent.nodeSelector很关键如果你们既有 GPU 节点也有普通 CPU 节点按这个选择器标记后agent 就只会在 GPU 节点上跑避免每个 CPU 节点也白白占用资源。4.3 执行安装与验证执行安装命令helm install openfuyao openfuyao/openfuyao -n openfuyao-system --create-namespace -f values.yaml kubectl get pods -n openfuyao-system -w等所有 pod 变成Running后验证核心资源kubectl get crd | grep fuyao kubectl get fuyaocluster -n openfuyao-system正常情况下你会看到类似openfuyao-cluster-primary的 CR 实例处于Ready状态。同时可以看日志kubectl logs -n openfuyao-system -l appopenfuyao-scheduler --tail50调度器启动后会在日志里打印类似OpenFuyao scheduler started with strategy: binpacking的信息。如果没有这行输出说明配置没加载成功回去检查 values.yaml 的algorithm段。我还推荐在部署完成后立刻跑一个最小 Pod 验证调度链路apiVersion: v1 kind: Pod metadata: name: smoke-test namespace: default spec: schedulerName: openfuyao-scheduler containers: - name: cuda-vector-add image: nvidia/cuda:12.0-base-ubuntu22.04 command: [nvidia-smi] resources: limits: fuyao.io/gpu: 1创建后观察调度决策kubectl describe pod smoke-test | grep -A 10 Events如果调度器正常工作Events 里会出现openfuyao-scheduler成功绑定的记录。如果一直 Pending说明调度链路有地方断了这正好接上后面问题排查的部分。5. 核心配置资源标签与调度策略5.1 标签体系是调度的基石部署只是开始真正决定平台好不好用的是资源标签的覆盖质量。openFuyao 会从节点 agent 自动采集一批基础标签但基础标签不一定完全准确尤其是多卡机器需要人工核对。我实际使用过程中最常用的几个标签如下标签示例值含义fuyao.io/gpu-modelH100/V100GPU 型号fuyao.io/gpu-memory80Gi显存容量fuyao.io/gpu-count8节点上 GPU 总数fuyao.io/gpu-vendornvidia厂商fuyao.io/nvlink-enabledtrue是否支持 NVLinkfuyao.io/pcie-bandwidthGen5x16PCIe 带宽等级fuyao.io/gpu-nodetrue标识 GPU 节点手动修正标签用命令即可kubectl label node gpu-01 fuyao.io/gpu-modelH100 --overwrite之前有个节点上的 agent 把 V100 识别成了 V100-PCIE导致型号标签不统一模型匹配时总是不命中。最后就是用--overwrite和kubectl get nodes --show-labels批量清洗了一轮。所以标签规范化这件事越早做越好否则业务方一旦开始依赖标签再改就会牵连一堆任务。5.2 模板匹配机制怎么用模板ComputeProfile是 openFuyao 给业务方提供的“算力需求描述语言”。业务不用关心具体机器只需要定义一个模板调度器负责找满足条件的资源。模板示例apiVersion: fuyao.io/v1 kind: ComputeProfile metadata: name: deepseek-train-template spec: selector: gpu-model: A100 gpu-memory: 40Gi nvlink-enabled: true gpu-count: 4 scheduling: priority: 100 preemptible: false这个模板的意思是提交这个模板的任务优先调度到 A100 及以上的、显存大于等于 40G 的、支持 NVLink 的节点且该节点至少得有 4 张卡。运算符是 v25.09 相对旧版的一大增强旧版只能做等值匹配新版让需求表达能力提升了一个档次。调度器在处理模板匹配时会先把所有节点按“标签满足度”做一次预筛然后对候选节点打分。注意gpu-count: 4这类标签订阅需要节点上的标签值能被正确解析为数字。如果标签是字符串four模板匹配直接失败。这也是我强调标签规范化的原因。5.3 拓扑感知与 P2P 调度为什么关键多卡训练任务最容易被忽视的问题是通信拓扑。同样两张卡如果它们在同一个 NUMA 节点下且通过 NVLink 互联通信带宽可能是 600GB/s如果跨 PCIe Switch带宽可能直接跌到 32GB/s。业务方只看“我有两张卡”调度器如果不管拓扑任务确实能跑但训练速度可能慢得离谱。openFuyao 的topologyAware开启后调度器会优先选择能提供最佳通信拓扑的节点。p2pAware会进一步检测 GPU 之间的 P2P 通信矩阵确保多卡任务的所有 worker 都能享受到高速互联。我在一个 8 卡 H100 节点上跑过对比测试开启拓扑感知后一个需要频繁 all-reduce 的训练任务整体耗时缩短了约 20%。这个提升效果取决于模型通信占比但足以说明拓扑感知不是可有可无的优化项而是实打实的性能收益。6. 多集群联邦与算力扩容6.1 计算集群怎么纳管当你有了第二套 K8s 集群就可以用fuyaoctl把它加入联邦。fuyaoctl cluster join --name cluster-02 \ --server https://cluster-02-api.example.com:6443 \ --token token \ --certificate-authority /etc/kubernetes/pki/ca.crt加入成功后一级集群会自动拿到这套集群的节点与资源标签。你可以用同一套标签体系跨集群调度任务。业务方提交任务时不再区分“哪个集群”只需要声明需求调度器在多个集群间统一决策。联邦模式对扩容特别友好。新集群加入后不需要业务方做任何配置变更只需要在调度器配置里把新集群的资源权重调整一下。如果某个集群的算力报价更便宜或者资源更充裕通过权重可以把更多任务引过去。6.2 多集群容灾的常见姿势我建议把一级集群当成一个纯控制面计算集群干脏活累活。一级集群挂了计算集群的存量任务不受影响只是新任务无法调度。如果计算集群本身挂掉一级集群会自动把新任务派给其他有资源余量的集群。为了达到这个效果部署时要留一个心眼不要把所有资源都塞满。给调度器留 10% 到 15% 的余量容灾切换时才有回旋空间。我见过有的团队资源利用率冲到 95% 以上结果一个节点故障排队任务直接积压了几百个。7. 常见问题与排查技巧实录7.1 错误速查表现象可能原因处理方式Pod 长时间 Pending调度器未接管或模板不匹配确认 Pod 的schedulerName是 openfuyao查模板选择器节点上报为 Unhealthyagent 心跳丢失检查 agent pod 日志、时钟同步、网络端口插卡/卸载任务失败驱动未负载或卡被占用查看 agent 日志确认nvidia-smi输出正常跨集群任务无法调度联邦网络不通fuyaoctl cluster list查看集群状态用 ping/telnet 测试链路GPU 标签显示为 Unknownagent 未上报或驱动异常重启 agent 并查看/var/log/fuyao-agent.log调度器日志中有大量 RBAC 错误权限不足检查 ServiceAccount 的 ClusterRole 是否完整上述问题里模板不匹配是最容易忽略的。因为模板本身不会报错只会静默地把候选节点过滤掉。我遇到过一个场景业务模板要求gpu-model V100但节点标签被打成了v100-pcie这串小写字母和连字符直接让比较失败。最终排查到是 agent 采集命名不规范。所以标签清洗这件事宁可多做几次也不要留隐患。7.2 GPU 插卡/卸载的实践心得openFuyao v25.09 的 GPU 热插拔功能我一开始觉得“这个功能挺花哨但用不上”直到有一次需要临时给节点加两张卡传统做法要改 BIOS、重启机器、再让 K8s 重新识别整个过程至少 30 分钟。用 openFuyao 的插卡指令直接在控制台或者通过 CRD 下发指令agent 会自动配置设备然后通过 device plugin 重新上报。实际执行有几点需要注意确定目标 GPU 没有被任何存量 Pod 使用否则插卡流程会等待资源释放插卡前确认驱动支持该型号的卡避免新卡插上后nvidia-smi能看到但 device plugin 识别不到在裸金属服务器上热插拔 GPU要确认服务器平台支持 PCIe 热插拔而不是所有机器都支持卸载卡的时候逻辑相反先把该卡上的任务全部驱逐再触发卸载。如果驱逐超时会进入保护模式等待人工确认。7.3 调度性能调优与个人体会平台上线后我花了比较多精力在调度性能调优上。v25.09 默认的调度周期是 100ms实测在一个 500 节点、3000 张 GPU 的资源池上单次调度决策的 P99 延迟约 120ms吞吐量在每秒 25 个 Pod 左右。如果你们有大规模突发任务建议把 scheduler 的QPS和Burst参数提升一下默认值设定得比较保守。另外调度器日志里有个fitErrors字段很值得关注。它记录的是“有多少 Pod 因为什么原因被过滤”。我经常用它来判断业务方的模板是不是写得太严苛。有一次一个业务团队把所有约束都拉满调度器里九成任务都因为模板过滤失败从fitErrors一眼就能看出问题。最后分享一个我自己很受用的小技巧给每个业务团队固定一套模板前缀比如nlp-、cv-、bi-后续查调度日志时一目了然是哪个团队的任务在选择器上出了问题。这个习惯看起来很小但在多团队共用平台时能极大降低沟通成本。这次部署 openFuyao v25.09从环境准备到联邦集群稳定运行前后大概花了两天时间。大部分时间其实耗在标签清洗和网络连通性排查上真正部署本身非常快。如果你以后也想往上层走搞数据编排或者任务编排建议再看看 valhalla 那套部署实践两者结合起来能形成一个更完整的算力平台底座。
返回列表