GPU 在 Kubernetes 中的使用与管理 | 社区征文
前言
随着人工智能与机器学习技术的快速发展,在 Kubernetes 上运行模型训练、图像处理类程序的需求日益增加,而实现这类需求的基础,就是 Kubernetes 对 GPU 等硬件加速设备的支持与管理。在本文中我们就说一下在 Kubernetes 中启动并运行 GPU 程序的注意事项。
Kubernetes 对 GPU 支持的不足之处
我们知道 Kubernetes 可以实现对宿主机的 CPU、内存、网络实现精细化的控制,但是到本文书写为止,Kubernetes 尚未实现像管理 CPU 那样来管理 GPU,比如有如下限制:
对于 GPU 资源只能设置
limit
,这意味着requests
不可以单独使用,要么只设置limit
、要么同时设置二者,但二者值必须相等,不可以只设置request
而不设置limit
。pod 及容器之间,不可以共享 GPU,且 GPU 也不可以过量分配(所以我们线上的程序采用
daemonSet
方式运行)。不允许以小数请求 GPU 资源分配。
Kubernetes 如何管理 GPU 资源
扩展资源(Extended Resources)
和 CPU 资源不同的是,硬件加速设备类型有多种,比如说 GPUs、NICs、FPGAs,而且它们的厂商也不止一家,Kubernetes 要想挨个支持是不现实的,所以 Kubernetes 就把这些硬件加速设备统一当做扩展资源
来处理。
Kubernetes 在 Pod 的 API 对象里并没有提供像 CPU 那样的资源类型,它使用我们刚说到的扩展资源
资源字段来传递 GPU 信息,下面是官方给出的声明使用 nvidia 硬件的示例:
要想使用上面 yaml 文件声明使用 GPU 设备,那么需要先在 Node 节点上安装设备插件Device Plugin
。
设备插件(Device Plugin)
设备插件与设备厂商绑定,这里使用 nvidia 提供的 Device Plugin。
官方的 NVIDIA GPU 设备插件 有以下要求:
Kubernetes 的节点必须预先安装了 NVIDIA 驱动
Kubernetes 的节点必须预先安装 nvidia-docker 2.0
Docker 的默认运行时必须设置为 nvidia-container-runtime,而不是 runc
NVIDIA 驱动版本 ~= 384.81
安装过程可以参考上面链接,这里就不在赘述,这里讨论 Device Plugin 做了哪些事及其实现方法。
暴露每个 Node 上的 GPU 个数
在 Kubernetes 上运行可以支持 GPU 的容器
Device Plugin 工作流程图:
第一步:向 kubelet 的 Device plugin Manager 发起注册请求。
第二步:启动 gRPC 服务用于和 kubelet 进行通信。
第三步:kubelet 通过 ListAndWatch 这个 API 定期获取设备信息列表。
第四步:kubelet 将获取到的设备信息发送给 API server。
不管是 nvidia 还是其它类型的硬件,如果要实现用于 Kubernetes 的自己的设备插件,都需要遵守 Device Plugin 的规范来实现如下代码中所示的 ListAndWatch
和 Allocate
API。
总结
总的来讲,以 Device Plugin 方式来管理 GPU 等硬件设备,目前的控制还不够精细,粒度较大。所以很多情况下要把 GPU 用起来好像也不是非 Device Plugin 不可。我发现很多公司在使用时,并没有在 YAML 文件中指定 GPU 的个数,也没有在 Kubernetes 集群中安装 Device Plugin 插件,因为他们的程序以 DaemonSet 的方式运行,且每台机器上只有一块 GPU,这样相当于一个程序独占一个 GPU,至于把 GPU 设备及驱动加载到 Docker 容器内,可以通过在 YAML 文件中指定NVIDIA_DRIVER_CAPABILITIES
环境变量来实现:
版权声明: 本文为 InfoQ 作者【大菠萝】的原创文章。
原文链接:【http://xie.infoq.cn/article/360e3286b7670358825081446】。文章转载请联系作者。
评论