在 Kubernetes 上搭建 AI 工厂:让 GPU 资源服务多个团队

2026-08-27 42 预计阅读时间: 1 分钟
来源: cncf.io AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

AI 工厂不只是一个模型,也不只是一个 Kubernetes 集群。它更像一条共享生产线:一组 GPU 同时被多个团队使用,有人进行微调,有人提供在线推理,有人运行评测,还有人提交临时实验。真正的难点不在于把一个 Pod 调度到 GPU 节点,而在于让这组昂贵资源能够被隔离、排队、观测和持续交付。

Kubernetes 提供了统一的资源编排基础,但 GPU 集群要成为可用的 AI 工厂,还需要补上资源治理、工作负载分类和运行数据这几层能力。

从“GPU 集群”转向“共享资源池”

单一团队使用 GPU 时,节点标签加上 nvidia.com/gpu 请求通常就能启动工作负载。但当多个团队同时提交任务,几个问题会迅速出现:

  • 微调任务可能长时间占满 GPU,在线推理无法及时扩容。
  • 评测任务和交互式实验没有明确优先级,资源争抢变成随机排队。
  • 团队之间缺少配额边界,一个 namespace 就可能消耗整个集群。
  • GPU 利用率、显存占用和排队时间没有统一视图,管理员只能凭感觉扩容。

因此,AI 工厂的基本抽象应当是“多租户 GPU 资源池”。团队提交的是带有资源需求和服务等级的工作负载,平台负责将它们放到合适的 GPU 节点,并限制每个团队能够消耗的上限。

一个可行的分层方式是:

工作负载 典型特征 调度策略
在线推理 需要稳定延迟和快速扩容 高优先级、保留容量
模型微调 运行时间长、吞吐优先 可排队、允许抢占或暂停
评测 批处理、可重试 使用空闲容量
交互式实验 规模小、变化快 设置较低的单任务上限

这不是 Kubernetes 自动提供的业务策略,而是平台团队需要明确设计的资源产品。

Kubernetes 负责哪些边界

GPU 节点通常通过 NVIDIA device plugin 向 Kubernetes 暴露 nvidia.com/gpu 资源。Pod 只要在 resources.limits 中请求 GPU,调度器就会把它视为不可超卖的整块资源。可以这样实践:为每个团队创建独立 namespace,并通过 ResourceQuota 设置 GPU、CPU 和内存上限。

下面的示例假设集群已经安装 NVIDIA device plugin,并且节点能够暴露 nvidia.com/gpu。将 team-a 替换成实际团队名称后即可改造使用。

apiVersion: v1
kind: Namespace
metadata:
  name: team-a
  labels:
    ai-factory.example.com/team: team-a
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-compute
  namespace: team-a
spec:
  hard:
    requests.nvidia.com/gpu: "4"
    requests.cpu: "32"
    requests.memory: 256Gi
    limits.cpu: "64"
    limits.memory: 512Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: inference-api
  namespace: team-a
spec:
  replicas: 1
  selector:
    matchLabels:
      app: inference-api
  template:
    metadata:
      labels:
        app: inference-api
    spec:
      containers:
        - name: server
          image: example.com/ai/inference-server:2025-01
          ports:
            - name: http
              containerPort: 8000
          resources:
            requests:
              cpu: "4"
              memory: 16Gi
              nvidia.com/gpu: "1"
            limits:
              cpu: "8"
              memory: 32Gi
              nvidia.com/gpu: "1"

应用配置:

kubectl apply -f team-a-gpu.yaml
kubectl -n team-a get resourcequota
kubectl -n team-a describe resourcequota team-a-compute
kubectl -n team-a get pods -o wide

这里有一个容易忽略的细节:GPU 资源通常同时写在 requestslimits 中,且两者数值保持一致。具体行为仍取决于设备插件、GPU 驱动和集群版本,生产环境应使用一份已验证的 GPU runtime 配置进行测试。

调度不能只看“有没有 GPU”

不同 GPU 的显存、计算能力和互联拓扑差异很大。一个需要大显存的微调任务,不应被随意安排到小显存卡上;需要多卡通信的训练任务,也不应只按 GPU 数量进行调度。

可以给节点增加可被调度器识别的标签,例如:

kubectl label node gpu-node-01 \
  ai-factory.example.com/gpu-class=h100 \
  ai-factory.example.com/zone=az-a

kubectl label node gpu-node-02 \
  ai-factory.example.com/gpu-class=a100 \
  ai-factory.example.com/zone=az-b

工作负载通过节点亲和性选择 GPU 类型:

apiVersion: batch/v1
kind: Job
metadata:
  name: evaluate-model
  namespace: team-a
spec:
  backoffLimit: 2
  template:
    spec:
      restartPolicy: Never
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: ai-factory.example.com/gpu-class
                    operator: In
                    values:
                      - a100
                      - h100
      containers:
        - name: evaluator
          image: example.com/ai/evaluator:2025-01
          command: ["python", "evaluate.py"]
          resources:
            requests:
              cpu: "8"
              memory: 32Gi
              nvidia.com/gpu: "1"
            limits:
              cpu: "8"
              memory: 32Gi
              nvidia.com/gpu: "1"

在更复杂的集群中,可以继续引入节点污点与容忍度、Pod 优先级、队列调度器、MIG 或 GPU 时间切分。选择哪种方案要看任务形态:在线服务更关心延迟和稳定性,批处理更关心吞吐和总体成本,交互式任务则更关心启动速度。

需要注意,GPU 时间切分或显存切分并不等于完全隔离。它们可能带来性能抖动、故障影响范围扩大和调试困难。对延迟敏感的生产推理服务,通常应保留专用或强隔离的 GPU 容量。

把模型交付纳入同一条生产线

AI 工厂的另一部分是交付流程。训练或微调作业产生模型文件后,模型需要经过评测、登记、部署和回滚,而不是停留在某个共享目录中。

一个可操作的流程可以是:

  1. 代码和数据版本固定,提交训练或微调 Job。
  2. Job 将模型制品写入对象存储或模型仓库,并记录 commit、数据集版本和超参数。
  3. 评测 Job 使用固定测试集生成质量、延迟和资源消耗指标。
  4. 只有通过门禁的模型才更新推理 Deployment。
  5. 推理服务保留上一版本,出现错误时可以回滚。

Kubernetes 适合承载这些工作负载,但不应该把模型元数据、实验指标和业务审计信息全部塞进 Pod 注释。可以将 Kubernetes 资源作为运行载体,把模型仓库、实验跟踪系统和指标系统作为独立的事实来源。

对平台运营而言,至少应采集以下数据:

  • 每个团队的 GPU 分配量、实际利用率和使用时长。
  • Job 从提交到启动的排队时间。
  • 推理服务的 GPU 利用率、显存使用、延迟和错误率。
  • 训练失败原因、重试次数以及节点故障记录。
  • 模型版本与部署版本之间的对应关系。

这些数据决定了下一步应该优化调度、改进模型服务,还是增加 GPU 容量。只有看到排队时间和利用率,资源池才不会变成一个只能靠人工协调的共享机器房。

落地时的检查清单

可以按下面的顺序建设,而不是一次性引入所有组件:

  • 先确认 GPU 驱动、容器运行时和 device plugin 在每类节点上稳定工作。
  • 为团队建立 namespace、ResourceQuota 和访问权限边界。
  • 统一训练、推理、评测 Job 的资源声明和标签。
  • 为不同 GPU 型号建立节点标签,并验证亲和性规则。
  • 为在线服务和批处理任务定义明确的优先级与容量策略。
  • 建立 GPU 利用率、排队时间、服务延迟和模型版本监控。
  • 用小规模工作负载验证抢占、重试、节点故障和回滚行为。

AI 工厂的核心不是“把更多 GPU 接入 Kubernetes”,而是把 GPU 变成一种可申请、可调度、可观测、可回收的共享平台能力。Kubernetes 解决了统一编排问题,平台团队还需要补上多租户治理、队列策略和模型交付流程。只有这几层共同工作,多个团队才能在同一组 GPU 上并行推进,而不会互相拖慢。


相关推荐