K8S调度管理GPU资源

引言:GPU 管理的核心挑战

与 CPU 和内存这些“可分割”的资源不同,GPU 资源管理面临三大核心挑战:

  1. 硬件强依赖性: GPU 驱动与硬件型号、CUDA 版本紧密耦合,管理复杂。
  2. 资源不可分割性 (传统上): 一张物理 GPU 卡在默认情况下是一个整体,无法像 CPU 那样被多个容器轻易地共享,容易造成资源浪费。
  3. 异构性与拓扑: 一个节点上可能有多张不同型号的 GPU,它们之间的通信拓扑(如 NVLink)对分布式训练性能至关重要,但 Kubernetes 原生对此一无所知。

Kubernetes 的 GPU 管理架构就是为了解决这三大挑战而不断演进的。

第一阶段:原生基础支持 - Device Plugin 框架

这是 Kubernetes GPU 管理的基石,也是理解一切后续技术的前提。

  • 技术方案: Kubernetes Device Plugin Framework (设备插件框架)。
  • 解决的问题: 解决了“有”和“无”的问题,让 Kubernetes 能够发现、上报并调度 GPU 资源。
  • 底层原理:
    1. 发现与上报 (Discovery & Reporting):
      • NVIDIA 会提供一个专门的 Device Plugin Pod(通常以 DaemonSet 形式部署在每个 GPU 节点上)。
      • 这个 Pod 启动后,会调用 GPU 驱动(如 NVML 库)来扫描节点上有多少张物理 GPU。
      • 然后,它通过 gRPC 与节点上的 kubelet 进行通信,注册自己并上报发现的 GPU 列表。例如,它会告诉 kubelet:“我发现了 2 个资源,名称是 nvidia.com/gpu”。
      • kubelet 收到后,会将这个“可扩展资源” (nvidia.com/gpu: 2) 更新到该 Node 对象的 status.allocatable 字段中。
    2. 调度 (Scheduling):
      • 当用户提交一个请求了 nvidia.com/gpu: 1 的 Pod 时,kube-scheduler 在调度时就像处理 CPU/内存一样,寻找 status.allocatable 中 nvidia.com/gpu 数量大于等于 1 的节点。
    3. 分配与暴露 (Allocation & Exposure):
      • Pod 被调度到某个节点后,kubelet 会调用 Device Plugin 的 Allocate gRPC 接口,告诉它:“请为这个 Pod 分配一张 GPU”。
      • Device Plugin 收到请求后,会返回需要挂载到容器中的设备文件路径(如 /dev/nvidia0)和环境变量(如 NVIDIA_VISIBLE_DEVICES=0)。
      • kubelet 拿到这些信息后,在创建容器时(通过 CRI 调用 containerd 或 docker),将这些设备和环境变量注入到容器的运行时规范中。
    4. 容器内使用: 容器启动后,由于有了正确的设备文件和环境变量,容器内的 CUDA 应用就能像在物理机上一样,找到并使用这张被分配的 GPU。
  • 局限性:
    1. 资源浪费: 即使一个推理任务只用了 10% 的 GPU 算力和 5% 的显存,它也独占了一整张卡,其他 Pod 无法使用剩下的 90%。
    2. 缺乏精细化控制: 无法指定需要的 GPU 型号、显存大小或算力。

第二阶段:虚拟化与共享 - GPU Sharing & MIG

为了解决资源浪费问题,业界演进出了两条主流技术路线:软件层的时间片共享和硬件层的物理分区。

方案一:基于时间片的 GPU 共享(软件虚拟化)

  • 代表技术: NVIDIA GPU Sharing (由阿里云贡献给社区)。
  • 技术方案: 修改 NVIDIA Device Plugin,使其向上层“欺骗性”地暴露更多的 GPU 资源。例如,一张物理卡可以被虚拟成 10 个 aliyun.com/gpu-mem: 1 (表示1GiB显存) 的虚拟 GPU。
  • 底层原理:
    1. 虚拟化上报: Device Plugin 不再上报 nvidia.com/gpu: 1,而是根据显存大小,上报多个自定义的虚拟资源,如 aliyun.com/gpu-mem: 10
    2. 共享调度: 多个 Pod 可以请求这些虚拟资源,并被调度到同一张物理卡上。
    3. 运行时隔离: 当容器启动时,Device Plugin 会通过修改环境变量 NVIDIA_VISIBLE_DEVICES 让所有容器都看到同一张物理卡。
    4. 显存隔离: 核心技术。它通过拦截容器内的 CUDA API 调用(使用 LD_PRELOAD 动态库注入),来控制每个容器可以分配的显存量。当一个容器申请的显存超过其配额时,注入的库会返回 out-of-memory 错误,从而实现了显存的软件隔离
    5. 算力共享: 算力是通过 GPU 硬件自身的时间片机制在多个进程间共享的,没有硬性隔离。
  • 优点: 灵活,适用于任何支持的 NVIDIA GPU。
  • 缺点: 算力没有隔离,一个高负载任务会影响其他任务;可能存在驱动兼容性问题;需要代码注入。

方案二:NVIDIA MIG (Multi-Instance GPU) (硬件虚拟化)

这是 NVIDIA 在 Ampere (A100) 及更新架构上推出的硬件级虚拟化技术

  • 技术方案: 将一张物理 GPU 卡在硬件层面物理分割成最多 7 个独立的 GPU 实例 (GPU Instance, GI)。每个 GI 都有自己独立的计算单元、显存和内存总线。
  • 底层原理:
    1. 物理分区: 管理员使用 nvidia-smi 命令,预先将一张 A100 卡配置成多种 MIG Profile 的组合。例如,可以划分为 1个 3g.20gb 和 4个 1g.5gb 的 GI。
    2. MIG 感知的 Device Plugin: NVIDIA 官方的 Device Plugin 能够感知到 MIG 的配置。它不再上报 nvidia.com/gpu,而是上报具体的 MIG 设备资源,如 nvidia.com/mig-1g.5gb: 4 和 nvidia.com/mig-3g.20gb: 1
    3. 精确调度: 用户可以在 Pod 的 resources.limits 中精确请求特定类型的 GI,例如 nvidia.com/mig-1g.5gb: 1。调度器会进行精确匹配。
    4. 硬件隔离: 当 Pod 被调度后,Device Plugin 会将对应的 GI 设备(如 /dev/nvidia-caps/...)暴露给容器。由于是硬件级别的隔离,不同 GI 之间的算力和显存完全独立,互不干扰,提供了可预测的性能。
  • 优点: 硬件级隔离,性能稳定无干扰,安全性高。
  • 缺点: 只支持 Ampere 及以上架构的特定高端 GPU(如 A100, H100),不如软件方案灵活。

第三阶段(最新):动态资源分配与容器设备接口 (DRA & CDI)

这是 Kubernetes 社区和硬件厂商正在大力推进的最新架构,旨在解决 Device Plugin 模型的根本性局限。

  • 技术方案: 动态资源分配 (Dynamic Resource Allocation, DRA) 和 容器设备接口 (Container Device Interface, CDI)
  • 解决的问题:
    • Device Plugin 的参数传递过于简单(只能是设备路径和环境变量)。
    • 资源在 Pod 创建时就被静态决定,不够灵活。
    • 对复杂的、带参数的资源(如“我需要一个支持特定编解码能力的MIG实例”)描述能力不足。
  • 底层原理 (DRA & CDI):
    • 资源定义 (ResourceClass): 集群管理员可以创建一个 ResourceClass 对象,来定义一种“带参数的”资源,例如一个名为 my-mig-gpus 的 Class,其参数可能包括 MIG 的类型、显存要求等。
    • 资源声明 (ResourceClaim): 用户不再直接在 Pod Spec 中请求资源,而是创建一个 ResourceClaim 对象,引用 ResourceClass 并填写具体参数,声明“我需要一个符合 my-mig-gpus 定义的资源实例”。
    • 动态分配: 一个DRA 驱动(新一代的 Device Plugin)会监视这些 ResourceClaim。当发现未被满足的 Claim 时,它会检查物理资源,并动态地为这个 Claim 分配一个具体的设备,然后更新 Claim 的状态,表示“分配完成,设备ID是XXX”。
    • Pod 调度: Pod Spec 中引用 ResourceClaim 的名称。调度器在调度时,会检查 Claim 是否已被成功分配,并根据 Claim 的信息(如拓扑信息)来选择最佳节点。
    • 设备注入 (CDI): 这是关键一步。当 kubelet 在节点上启动 Pod 时,它不再直接从 DRA 驱动获取设备信息,而是通过一个标准化的 CDI 机制。DRA 驱动会根据分配结果,在主机上生成一个符合 CDI 规范的 JSON 文件。这个文件详细描述了要注入到容器中的所有内容(设备、钩子、环境变量、库挂载等)。containerd 等容器运行时能够读取这个 JSON 文件,并精确地完成容器的设备配置。
  • 优势:
    • 表达能力极强: 可以传递任意复杂的参数和配置。
    • 生命周期解耦: 资源的分配和 Pod 的生命周期可以解耦。
    • 标准化: CDI 为容器运行时如何消费设备提供了一个统一的标准,摆脱了对 kubelet 的强依赖。

演进阶段:

阶段

核心技术

解决的关键问题

优点

缺点/局限

1.0 基础

Device Plugin

从 0 到 1,让 K8s 能管理 GPU

简单、直接、官方标准

独占模式,资源浪费严重

2.0 共享

GPU Sharing (软件)

资源超卖,提高利用率

灵活,通用性强

算力无隔离,性能不稳定

MIG (硬件)

硬件级资源隔离

性能可预测,安全可靠

仅限高端卡,配置不灵活

3.0 动态 (最新)

DRA + CDI

解决 Device Plugin 的根本局限

表达能力强,生命周期解耦,标准化

较新,生态正在建设中

截止2025.08,MIG 是高端卡的首选方案,因为它提供了最强的隔离保证。对于不支持 MIG 的卡,GPU Sharing 是提高利用率的成熟方案。而 DRA/CDI 代表了未来的方向,随着生态的成熟,它将最终取代现有的 Device Plugin 模型,为包括 GPU 在内的所有复杂异构资源提供更强大、更灵活的管理框架。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值