随着人工智能(AI)和机器学习(ML)的快速发展,GPU 已成为 Kubernetes 中不可或缺的资源。然而,Kubernetes 最初设计的调度机制主要针对 CPU 和内存等常规资源,未对异构硬件(如 GPU)提供原生支持。

为了高效管理和调度 GPU 以及其他硬件资源,Kubernetes 引入了一系列扩展机制,包括 Device PluginContainer Device Interface (CDI)Node Feature Discovery (NFD)GPU Operator

本文将以 GPU 调度为例,概述这些扩展机制的工作原理和应用。

Device Plugin

Device Plugin 是 Kubernetes 用于管理特殊硬件资源的插件机制。它通过将设备(如 GPUFPGANICInfiniBand 等)抽象为 Kubernetes 可识别的资源,实现设备的发现、分配和调度。

Device Plugin API 使用 gRPC 协议,定义了 kubelet 与设备插件之间的交互方式,包含两个 service:

  • Registration service:设备插件通过 Register 方法向 kubelet 注册自己。
  • DevicePlugin service 包括五个方法:

    • GetDevicePluginOptions:查询设备插件的可选项。
    • ListAndWatch:kubelet 通过此接口监听设备状态的变化。
    • GetPreferredAllocation:kubelet 可能会调用该接口来询问设备插件最优的分配方案(如多 GPU 任务如何选择最佳的 GPU 组合)。
    • Allocate:kubelet 调用此接口为容器分配设备。
    • PreStartContainer:可以调用此接口让设备插件在容器启动前做一些操作。

以使用 NVIDIA GPU 为例:

  1. 设备插件通过 Register 向 kubelet 注册自己。kubelet 通过 ListAndWatch 监听设备状态,并将设备信息上报给 kube-apiserver,随后控制平面才能知道节点的 GPU 资源情况。
  2. 用户创建了一个使用 GPU 资源的 pod,调度器将 pod 分配到有空闲 GPU 资源的节点上。
  3. 节点上的 kubelet 监听到有 pod 被调度至此,开始后续容器的创建工作:

    • kubelet 通过 Allocate 接口请求设备插件分配硬件资源。
    • kubelet 通过 CRI gRPC 接口与容器运行时组件(如 containerdcri-o)进行交互。
    • CRI 组件(如 containerdcri-o)调用更底层的运行时,一般是 runckata-container,但此时必须要使用 nvidia-container-runtime,由 nvidia-container-runtime 与 GPU 驱动交互,然后才能使用 GPU 资源。nvidia-container-runtime 其实就是在 runc 的基础上注入了 NVIDIA 的特定代码。

这个流程完整展示了 Kubernetes 如何管理和调度 GPU 资源。

Container Device Interface

由于缺乏第三方设备标准,设备供应商通常必须为不同的运行时编写和维护多个插件,甚至直接在运行时中注入特定于供应商的代码(如 nvidia-container-runtimerunc 的基础上魔改)。

因此,社区提出了 Container Device Interface(CDI),希望解耦并标准化容器运行时与设备插件的交互。

CDI 是容器运行时支持第三方设备的规范。它定义了设备的描述文件(JSON 格式),该文件用于描述特定设备的属性、环境变量、挂载点等等信息。

CDI 的工作流大致如下:

  1. 设备插件或供应商提供 CDI 描述文件。
  2. 设备名称被传递给容器运行时。
  3. 容器运行时按照 CDI 文件内容更新容器配置。

CDI 并不是对 Device Plugin 的替代,而是协同工作。容器运行时就像使用 CNI 一样使用 CDI

(感兴趣可以阅读我的往期文章《Kubernetes 之 kubelet 与 CRI、CNI 的交互过程》)

Node Feature Discovery

在某些场景中,应用可能需要节点具有特定的硬件特性。例如:需要使用特定的 CPU 指令集(如 AVX、SSE)来加速某些计算工作;依赖硬件加速器(如 GPU、FPGA);需要在特定的硬件架构(如 ARM、x86)上运行。

默认的 Kubernetes 调度器对这些特性并不了解,因此无法做出相应的调度决策。Node Feature Discovery 旨在通过自动化检测和标签机制填补这一空白。

Node Feature Discovery (NFD) 的工作流程如下:

  1. 节点特性检测:NFDDaemonSet 的形式运行在每个节点上,自动检测节点的硬件和软件特性。
  2. 特性标签化:检测到的特性会以 Labels / Annotations 的形式添加到节点上。
  3. 基于节点标签调度 Pod:用户可以利用已有的标签选择(如 nodeSelector 或 nodeAffinity)调度 Pod。

NFD 只是负责发现节点的特性,具体如何利用这些标签或注解则由用户决定。

GPU Operator

在上文 Device Plugin 一节中可以看到,为了使用 GPU,需要 GPU driverdevice pluginnvidia-container-runtime、以及监控等等工具。手动管理这些组件非常复杂、容易出错。GPU Operator 的目的就是自动化这一过程,通过 Operator 模式统一管理和配置 GPU 相关的组件。

Operator 也是 Kubernetes 的一种扩展机制,用户可以自定义资源和控制器,从而覆盖更多的使用场景。

总结

通过 Device PluginCDINFDOperator 机制,Kubernetes 实现了对 GPU 等特殊硬件资源的自动化管理与高效调度。然而,特定厂商的硬件仍然存在差异化的部署与配置,使用时需要额外关注。

(关注我,无广告,专注技术,不煽动情绪,也欢迎与我交流)


参考资料:


凌虚
3.8k 声望1.3k 粉丝