尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

基于 Kubernetes 的 GPU 资源调度与成本优化系统实践

基于 Kubernetes 的 GPU 资源调度与成本优化系统实践
📅 发布时间:2026/7/10 7:31:52

最近做了一个Kubernetes 方向的小项目:GPU 资源调度与成本优化系统。

项目地址:https://github.com/ycx666994/gpu-k8s-scheduler

然后这个项目的目标呢,不是训练模型,也不是写一个复杂的调度器,而是围绕 Kubernetes 原生能力,做一个可以演示 GPU 资源隔离、配额控制、节点亲和性、优先级调度和成本可视化的 MVP。

主要是我想去验证几个问题:

1.多个团队共用 GPU 集群时,怎么避免互相抢资源?
2.GPU 配额超了以后,Kubernetes 是怎么处理的?
3.训练任务和推理任务能不能调度到不同类型的 GPU 节点?
4.没有真实 GPU 的本地 kind 集群,能不能模拟出调度现象?
5.能不能把这些状态导出来,用一个简单 Dashboard 展示?

最终做出来的效果是:用 Namespace、ResourceQuota、Node Affinity、PriorityClass 搭了一套 GPU 调度实验环境,并写了一个本地 Web 仪表盘展示当前集群状态。

那么下面开始整个项目的讲解。

一、项目整体架构

项目整体分成三层:

1. 控制层
使用 Kubernetes YAML 定义 Namespace、ResourceQuota、LimitRange、PriorityClass 和 GPU workload。

2. 集群层
Kubernetes 负责 admission 和 scheduling。这里能观察到两类关键现象:
FailedScheduling:Pod 已创建,但调度器找不到合适节点。
FailedCreate:Pod 还没创建出来,就被 ResourceQuota 拒绝。

3. 可观测层
用 PowerShell 脚本调用 kubectl 导出当前集群状态,再由本地 Web Dashboard 读取 JSON/JS 文件展示。

我画了个架构图,如下图所示:

二、项目目录

项目目录如下图所示:

其中:

k8s/ 放 Kubernetes 资源清单。
scripts/ 放状态查看、导出和清理脚本。
web/ 是本地仪表盘。
docs/ 放报告、架构图和截图。

三、Namespace 隔离设计

项目里设计了三个 Namespace,对应三类 GPU 使用场景:

示例 YAML:

apiVersion: v1
kind: Namespace
metadata:
name: ai-training
labels:
gpu.platform/team: training

这样做的好处是后续所有资源管理都可以按 Namespace 维度展开,包括 GPU 配额、Pod 数量、CPU、内存等。

四、ResourceQuota:限制每个团队能用多少 GPU

GPU 资源比较贵,所以不能让某一个团队无限制申请。

所以我给三个 Namespace 分别设置了 GPU 配额:

以 ai-inference 为例:

apiVersion: v1
kind: ResourceQuota
metadata:
name: inference-gpu-quota
namespace: ai-inference
spec:
hard:
requests.cpu: "32"
requests.memory: 128Gi
limits.cpu: "64"
limits.memory: 192Gi
requests.nvidia.com/gpu: "4"
limits.nvidia.com/gpu: "4"
pods: "40"

这里最关键的是:requests.nvidia.com/gpu: "4"

它表示这个 Namespace最多只能申请 4 张 GPU。

五、PriorityClass:区分推理和训练优先级

GPU 集群里,不同任务的重要性是不一样的。
在线推理一般比离线训练更敏感。如果资源紧张,生产推理应该优先保证。

所以项目里定义了三个 PriorityClass:

示例:

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: gpu-critical-inference
value: 100000
globalDefault: false
preemptionPolicy: PreemptLowerPriority
description: "Production GPU inference workloads that should win during contention."

在 Pod 里使用时,只需要指定:

priorityClassName: gpu-critical-inference

六、Node Affinity:训练和推理调度到不同节点池

真实 GPU 集群里,通常会有不同类型的 GPU 节点,比如:

A100/H100 更适合训练
低延迟节点更适合在线推理
便宜卡可以跑实验或 batch 任务

我在 kind 节点上用 label 模拟 GPU 节点池:

kubectl label node llm-platform-control-plane accelerator=nvidia-a100 --overwrite
kubectl label node llm-platform-control-plane gpu.platform/pool=inference --overwrite
kubectl label node llm-platform-control-plane topology.kubernetes.io/zone=local-a --overwrite

训练任务要求:

affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: gpu.platform/pool
operator: In
values:
- training

推理任务要求:

affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: gpu.platform/pool
operator: In
values:
- inference

这样就可以模拟训练池和推理池的隔离效果。

七、本地 kind 没有 GPU,为什么还能做实验?

这个项目是在本地 kind 集群上做的,没有真实 GPU。开始我也考虑过这个问题:没有 GPU,是不是就没法做 GPU 调度实验?实际做下来发现,还是可以做出很多有价值的现象。

原因是Kubernetes 调度链路里有多个阶段:

1. Namespace 是否存在
2. ResourceQuota 是否允许
3. Node Affinity 是否匹配
4. 节点是否有足够 CPU/内存/GPU
5. Pod 是否能最终调度

即使没有真实 GPU,也可以观察到:

0/1 nodes are available: 1 Insufficient nvidia.com/gpu.

这说明 Pod 已经通过了前面的约束,最后卡在节点没有 GPU 可分配资源。

八、实验一:Node Affinity 不匹配

当训练 Pod 要求 gpu.platform/pool=training,但节点是 pool=inference 时,会看到:

0/1 nodes are available: 1 node(s) didn't match Pod's node affinity/selector.

这说明调度器首先会检查节点标签是否匹配。

如果标签不匹配,Pod 根本不会进入后续 GPU 资源检查。

九、实验二:节点标签匹配,但没有 GPU

当我把节点标签改成符合推理任务要求后:

kubectl label node llm-platform-control-plane gpu.platform/pool=inference --overwrite

推理 Pod 的失败原因变成:

0/1 nodes are available: 1 Insufficient nvidia.com/gpu.

这就说明 Node Affinity 已经通过了,剩下的问题是 kind 节点没有可分配的 GPU。

这是一个很清晰的调度链路:

Node Affinity 不匹配
↓
修改节点标签
↓
Node Affinity 通过
↓
Insufficient nvidia.com/gpu

十、实验三:ResourceQuota 超限

这个实验比较关键。

当前 ai-inference 已经申请了 3 张 GPU,配额是 4 张:

requests.nvidia.com/gpu: 3/4

然后我再提交一个请求 2 张 GPU 的 Deployment:

resources:
requests:
nvidia.com/gpu: "2"
limits:
nvidia.com/gpu: "2"

结果不是 Pending,而是直接被拒绝:

exceeded quota: inference-gpu-quota,
requested: requests.nvidia.com/gpu=2,
used: requests.nvidia.com/gpu=3,
limited: requests.nvidia.com/gpu=4

这里可以看到 ResourceQuota 和调度器的区别:

这也是我觉得这个项目最有价值的地方之一:它能把 Kubernetes 不同控制点的行为区分清楚。

十一、导出集群状态

为了让项目不只是命令行输出,我写了一个导出脚本:

.\scripts\export-cluster-status.ps1

它会调用 kubectl 收集:

Namespace
ResourceQuota
Pod
Node
Event

然后生成:

web/data/cluster-status.json
web/data/cluster-status.js

仪表盘直接读取 cluster-status.js,这样不需要后端服务,也不用部署数据库。

导出的数据大概长这样:

{
"context": "kind-llm-platform",
"summary": {
"gpuRequested": 5,
"gpuQuota": 12,
"pendingPods": 5,
"estimatedIdleCostPerHour": 12
}
}

十二、本地 Dashboard

项目里有一个简单的 Web Dashboard:

web/index.html

打开后可以看到:

GPU Requested / Quota
Pending Pods
Estimated Idle Cost
Namespace GPU 使用情况
调度失败事件
Quota 拒绝事件

截图如下:

还有一张专门整理实验结果的证据页:

十三、GitHub Actions 校验

项目上传 GitHub 后,我又加了一个简单的 CI:

name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

它主要用来检查:

1.JavaScript 语法
2.JSON 格式
3.Kubernetes YAML 语法
4.PowerShell 脚本语法

我其实踩了一个小坑:Windows PowerShell 默认写 UTF-8 时可能带 BOM,所以GitHub Actions 里的 Python 解析 JSON 会报:Unexpected UTF-8 BOM

最后我改成无 BOM 写入:

$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllText($jsonPath, $json, $utf8NoBom)

这个问题不大,但挺真实。很多跨平台项目都会遇到类似编码问题。

十四、当前项目的进度

目前这个项目算是一个比较完整的 MVP。

目前大概做了:

Namespace 隔离
ResourceQuota / LimitRange
PriorityClass
Node Affinity 训练池实验
Node Affinity 推理池实验
Quota 超限实验
kubectl 状态导出
本地 Dashboard
项目报告和截图
GitHub Actions CI

我之后打算补充的:

接入真实 GPU 节点
安装 NVIDIA device plugin
接入 DCGM Exporter
接入 Prometheus
展示真实 GPU 利用率
更精确的 GPU 成本计算模型

十五、总结

这个项目最大的收获是:GPU 调度不一定一开始就要写复杂调度器,Kubernetes 原生能力已经能做很多事情。通过 Namespace、ResourceQuota、PriorityClass 和 Node Affinity,可以先搭出一套可解释、可复现的 GPU 资源管理机制。

即使本地没有真实 GPU,也可以用 kind 做出很多关键实验,比如说:

1.节点亲和性不匹配
2.GPU 资源不足
3.Quota 超限拒绝
4.Pending 和 FailedCreate 的区别

总而言之,对学习 Kubernetes 调度、平台工程和 AI Infra 来说,这个项目比较适合作为入门级但有完整链路的实践项目。

项目地址:

https://github.com/ycx666994/gpu-k8s-scheduler

后面我会继续尝试把它接到 Prometheus 和 DCGM Exporter 上,做成一个更接近真实生产环境的 GPU 资源监控和成本优化系统。

欢迎大家评论留言以及欢迎大家来我仓库做开源贡献。谢谢!

相关新闻

  • 5分钟解锁专业图表制作:drawio-libs图标库完全指南
  • 技术、业务、管理:一个30岁前端的十字路口
  • 智能体平台有哪些监控仪表盘?企业级AI Agent全链路可视化与合规监控深度解析

最新新闻

  • Anthropic拟全面封禁地下通道
  • 实用AI教程:从RAG构建到模型部署的工程实践指南
  • CTF实战:ECDSA随机数重用漏洞分析与私钥破解
  • vLLM 与 SGLang 推理框架性能横评:吞吐、延迟与成本深度剖析
  • Cocos Creator入门:从零构建首个2D游戏项目实践指南
  • Windows智能体开发实战:从API调用到能力集成的系统级Agent构建

日新闻

  • OpenClaw本地化部署:xParse文档解析引擎实战指南
  • 蓝牙 5.4 协议栈深度解析:从 HCI 到 L2CAP 的 7 层数据流
  • PyTorch nn.CrossEntropyLoss 实战:3种权重设置与标签平滑对比(附代码)

周新闻

  • 基于YOLOv12的番茄成熟度智能检测系统开发
  • 终极RimWorld模组管理指南:用RimSort告别模组冲突烦恼
  • AI Agent框架开发:从理论到实践的完整指南

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号