k8s GPU设备插件

发布时间 2023-08-03 15:48:18作者: 滴滴滴

设备插件

特性状态: Kubernetes v1.26 [stable]

Kubernetes 提供了一个 设备插件框架, 你可以用它来将系统硬件资源发布到 Kubelet

供应商可以实现设备插件,由你手动部署或作为 DaemonSet 来部署,而不必定制 Kubernetes 本身的代码。目标设备包括 GPU、高性能 NIC、FPGA、 InfiniBand 适配器以及其他类似的、可能需要特定于供应商的初始化和设置的计算资源。

注册设备插件

kubelet 提供了一个 Registration 的 gRPC 服务:

service Registration {
	rpc Register(RegisterRequest) returns (Empty) {}
}

设备插件可以通过此 gRPC 服务在 kubelet 进行注册。在注册期间,设备插件需要发送下面几样内容:

  • 设备插件的 Unix 套接字。
  • 设备插件的 API 版本。
  • ResourceName 是需要公布的。这里 ResourceName 需要遵循扩展资源命名方案, 类似于 vendor-domain/resourcetype。(比如 NVIDIA GPU 就被公布为 nvidia.com/gpu。)

成功注册后,设备插件就向 kubelet 发送它所管理的设备列表,然后 kubelet 负责将这些资源发布到 API 服务器,作为 kubelet 节点状态更新的一部分。

比如,设备插件在 kubelet 中注册了 hardware-vendor.example/foo 并报告了节点上的两个运行状况良好的设备后,节点状态将更新以通告该节点已安装 2 个 "Foo" 设备并且是可用的。

然后,用户可以请求设备作为 Pod 规范的一部分, 参见 Container。 请求扩展资源类似于管理请求和限制的方式, 其他资源,有以下区别:

  • 扩展资源仅可作为整数资源使用,并且不能被过量使用
  • 设备不能在容器之间共享

示例

假设 Kubernetes 集群正在运行一个设备插件,该插件在一些节点上公布的资源为 hardware-vendor.example/foo。 下面就是一个 Pod 示例,请求此资源以运行一个工作负载的示例:

 

 

 

Kubernetes 实现了设备插件(Device Plugin),让 Pod 可以访问类似 GPU 这类特殊的硬件功能特性。

说明: 本部分链接到提供 Kubernetes 所需功能的第三方项目。Kubernetes 项目作者不负责这些项目。此页面遵循CNCF 网站指南,按字母顺序列出项目。要将项目添加到此列表中,请在提交更改之前阅读内容指南

作为集群管理员,你要在节点上安装来自对应硬件厂商的 GPU 驱动程序,并运行来自 GPU 厂商的对应设备插件。以下是一些厂商说明的链接:

一旦你安装了插件,你的集群就会暴露一个自定义可调度的资源,例如 amd.com/gpu 或 nvidia.com/gpu

你可以通过请求这个自定义的 GPU 资源在你的容器中使用这些 GPU,其请求方式与请求 cpu 或 memory 时相同。 不过,在如何指定自定义设备的资源请求方面存在一些限制。

GPU 只能在 limits 部分指定,这意味着:

  • 你可以指定 GPU 的 limits 而不指定其 requests,因为 Kubernetes 将默认使用限制值作为请求值。
  • 你可以同时指定 limits 和 requests,不过这两个值必须相等。
  • 你不可以仅指定 requests 而不指定 limits

以下是一个 Pod 请求 GPU 的示例清单:

apiVersion: v1
kind: Pod
metadata:
  name: example-vector-add
spec:
  restartPolicy: OnFailure
  containers:
    - name: example-vector-add
      image: "registry.example/example-vector-add:v42"
      resources:
        limits:
          gpu-vendor.example/example-gpu: 1 # 请求 1 个 GPU

集群内存在不同类型的 GPU 

如果集群内部的不同节点上有不同类型的 NVIDIA GPU, 那么你可以使用节点标签和节点选择器来将 Pod 调度到合适的节点上。

例如:

# 为你的节点加上它们所拥有的加速器类型的标签
kubectl label nodes node1 accelerator=example-gpu-x100
kubectl label nodes node2 accelerator=other-gpu-k915