kubernetes-nvidia-plugin设计解读
场景
最近在工作中经常使用到gpu资源,传统环境下我们一般在宿主机上部署算法程序,但是这样无法形成快速交付,并且维护成本会非常高。所以nvidia其实也考虑到这一点 通过docker调用宿主机的gpu资源。一般情况下我们需要部署gpu-container-runtime或者nvidia-docker去调用宿主机的gpu资源。那么既然docker可以使用gpu资源,我们是不是可以在kubernetes环境去使用gpu资源呢?答案是肯定的,接下来我这边会分享在kubernetes如何使用device plugin实现调度gpu资源。
设计
其实在kubernetes1.11版本之前社区给出的解决方案是加入了alpha.kubernetes.io/nvidia-gpu去使用gpu资源但是这个特性在1.11版本之后就已经下线了。取而代之的是通过Extended Resource+ Device Plugin两个Kubernetes的内置模块,外加由设备提供商实现的相应Device Plugin, 完成从设备的集群级别调度至工作节点,到设备与容器的实际绑定。
首先思考的第一个问题是为什么进入alpha.kubernetes.io/nvidia-gpu
主干一年之久的GPU功能彻底移除?
Kubernetes有一个核心理念:OutOfTree是一个很好的理念,简单来讲就是专注于自身核心和通用能力 将像GPU,InfiniBand,FPGA和公共云能力的工作完全交给社区和领域专家。这样一方面可以降低软件自身使用的复杂度,减小稳定性风险,另外OutOfTree分开迭代也能够更灵活实现的功能升级。
Device Plugin的设计:
实际上Device plugins实际上是简单的grpc server,需要实现以下两个方法 ListAndWatch
和Allocate
,并监听在/var/lib/kubelet/device-plugins/
目录下的Unix Socket,比如/var/lib/kubelet/device-plugins/nvidia.sock。
type DevicePluginServer interface {// GetDevicePluginOptions returns options to be communicated with Device// ManagerGetDevicePluginOptions(context.Context, *Empty) (*DevicePluginOptions, error)// ListAndWatch returns a stream of List of Devices// Whenever a Device state change or a Device disapears, ListAndWatch// returns the new listListAndWatch(*Empty, DevicePlugin_ListAndWatchServer) error// Allocate is called during container creation so that the Device// Plugin can run device specific operations and instruct Kubelet// of the steps to make the Device available in the containerAllocate(context.Context, *AllocateRequest) (*AllocateResponse, error)// PreStartContainer is called, if indicated by Device Plugin during // registeration phase,// before each container start. Device plugin can run device specific // operations// such as reseting the device before making devices available to the containerPreStartContainer(context.Context, *PreStartContainerRequest) (*PreStartContainerResponse, error)
}
其中:
- ListAndWatch: Kubelet会调用该API做设备发现和状态更新(比如设备变得不健康)
- Allocate: 当Kubelet创建要使用该设备的容器时, Kubelet会调用该API执行设备相应的操作并且通知Kubelet初始化容器所需的device,volume和环境变量的配置。
ListAndWatch函数(register 时候会调用一次,而且仅仅就这一次,因为 ListAndWatch 是个 GRPC 长连接,DP 可以通过这个长连接不停的反馈。):
func (m *NvidiaDevicePlugin) ListAndWatch(e *pluginapi.Empty, s pluginapi.DevicePlugin_ListAndWatchServer) error {s.Send(&pluginapi.ListAndWatchResponse{Devices: m.devs})for {select {case <-m.stop:return nilcase d := <-m.health:// FIXME: there is no way to recover from the Unhealthy state.d.Health = pluginapi.Unhealthys.Send(&pluginapi.ListAndWatchResponse{Devices: m.devs})}}
}
简阅Allocate函数主要的作用是分配相应的device资源:
// Allocate which return list of devices.
func (m *NvidiaDevicePlugin) Allocate(ctx context.Context,reqs *pluginapi.AllocateRequest) (*pluginapi.AllocateResponse, error) {responses := pluginapi.AllocateResponse{}log.Infoln("----Allocating GPU for gpu mem is started----")var (podReqGPU uintfound boolassumePod *v1.Pod)// podReqGPU = uint(0)for _, req := range reqs.ContainerRequests {podReqGPU += uint(len(req.DevicesIDs))}log.Infof("RequestPodGPUs: %d", podReqGPU)
........
类似阿里云的gpu share基本在这里加入了很多自定义逻辑实现了多卡gpu调度
大致的逻辑就是通过Annotations 标签选择合适的gpu device。这里就不详细说明了 感兴趣的同学可以去看下源码。
之后我们来看下device plugin 工作流程
shareGPUManager ---run()---> NvidiaDevicePlugin ----Serve()----> Start GRPC server and Register
那么整个Kubernetes调度GPU的过程如下:
1. GPU Device plugin 部署到GPU节点上,通过 ListAndWatch 接口,上报注册节点的GPU信息和对应的DeviceID。
2. 当有声明 nvidia.com/gpu 的GPU Pod创建出现,调度器会综合考虑GPU设备的空闲情况,将Pod调度到有充足GPU设备的节点上。
3. 节点上的kubelet 启动Pod时,根据request中的声明调用各个Device plugin 的 allocate接口, 由于容器声明了GPU。 kubelet 根据之前 ListAndWatch 接口收到的Device信息,选取合适的设备,DeviceID 作为参数,调用GPU DevicePlugin的 Allocate 接口,GPU DevicePlugin ,接收到调用,将DeviceID 转换为 NVIDIA_VISIBLE_DEVICES 环境变量,返回kubelet
4. kubelet将环境变量注入到Pod, 启动容器容器启动时, gpu-container-runtime 调用 gpu-containers-runtime-hookgpu-containers-runtime-hook 根据容器的 NVIDIA_VISIBLE_DEVICES 环境变量,转换为 --devices 参数,调用 nvidia-container-cli prestart,nvidia-container-cli 根据 --devices ,将GPU设备映射到容器中。 并且将宿主机的Nvidia Driver Lib 的so文件也映射到容器中。 此时容器可以通过这些so文件,调用宿主机的Nvidia Driver。
整体架构图:
总结
Kubernetes的生态地位已经确立,可扩展性将是其发力的主战场。异构计算作为非常重要的新战场,Kubernetes非常重视。而异构计算需要强大的计算力和高性能网络,需要提供一种统一的方式与GPU、FPGA、NIC、InfiniBand等高性能硬件集成。这也就是为什么淘汰了alpha.kubernetes.io/nvidia-gpu改用了Extended Resource+ Device Plugin的原因。
当然在我司也修改了部分逻辑,我们没有沿用gpu plugin默认device规则,我们在device的基础上新增了逻辑device的概念在逻辑层限制了每个应用可以申请的gpu显存。当然没办法硬性隔离,这部分目前需要依赖device底层实现。
kubernetes-nvidia-plugin设计解读相关推荐
- Kubernetes的Device Plugin设计解读
摘要: Kubernetes的生态地位已经确立,可扩展性将是其发力的主战场.异构计算作为非常重要的新战场,Kubernetes非常重视.而异构计算需要强大的计算力和高性能网络,需要提供一种统一的方式与 ...
- 谈 Kubernetes 的架构设计与实现原理
点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 本文转载于公众号:真没什么逻辑 Kubernetes 基本上是这两年最热门.最被人熟知的技术了,它 ...
- rs结果集可以传递给另一个jsp吗_从未如此高调 宝骏RS-5独家设计解读
[汽车之家 设计解码] 尽管宝骏多款"神车"已经用非常漂亮的销量数据打消了大家的疑虑,可事实上,它的车型就用途而言大多还是偏商用的,厂商也低调表示自己在乘用车方面还只是小学生.如今 ...
- Volcano 监控设计解读,一看就懂
摘要:Volcano 方便AI,大数据,基因,渲染等诸多行业通用计算框架介入,提供高性能任务调度引擎,高性能异构芯片管理,高性能任务运行管理等能力. Volcano 是一个 Kubernetes 云原 ...
- Kubernetes 架构与设计
什么是kubernetes? 官方说明: Kubernetes is an open-source system for automating deployment, scaling, and man ...
- Kubernetes v1.17 版本解读 | 云原生生态周报 Vol. 31
作者 | 徐迪.李传云.黄珂.汪萌海.张晓宇.何淋波 .陈有坤.李鹏 审核 | 陈俊 上游重要进展 1. Kubernetes v1.17 版本发布 功能稳定性是第一要务.v1.17 包含 22 个增 ...
- Kubernetes滚动更新速率控制解读
女主宣言 利用kubernetes的滚动更新时,可能经常遇到发布"太快不稳定"或"太慢体验差"的情况.本文将介绍kubernetes滚动更新控制速率的特性. P ...
- 干货|以产品要素设计解读线上小微信贷
小微信贷市场中经常收到客户的一些反馈,如:没有房子抵押.额度不够.利率太高.期限短等等,这些反馈的声音主要集中在产品要素上,客户拿到的贷款就是这些产品要素的组合,换句话讲,这些要素也正是一款产品的卖点 ...
- Kubernetes 一指禅,文章集锦(实时更新)
Kubernetes不简单,阿里云容器服务团队希望能通过这篇集锦助你一臂之力~ 你还有哪些学习和使用的困惑?请留言给我们哦~ Kubernetes 的ABC与解读 Kubernetes与Docker基 ...
最新文章
- 20155308郝文菲--第三次作业
- 如何在JavaScript中比较数组?
- 世界上最完美的公式 ----欧拉公式
- 下一个排列—leetcode31
- 代码练习中的bug及修改方法
- oracle中enqueue,ORACLE: Enqueue 烂笔头
- Apache JK Tomcat 集群问题
- linux多线程学习(三)——线程属性设置
- php设计要求,《PHP设计模式介绍》第十章 规范模式
- win10中VM15内centos7的安装
- BP神经网络预测(人口)程序(matlab)
- 搭建新环境的准备工作
- CAD卸载/完美解决安装失败/如何彻底卸载清除干净cad各种残留注册表和文件的方法
- CSS的特殊性 (specificity)
- java里面有radix树吗_基数树(radix tree)
- Vue实现 侧边固定定位图标 滑动隐藏
- python要学什么英文歌_Python分析网易云音乐近5年热门歌单
- vscode及typro快捷键
- Linux红帽RHEL 7/8 系统重置root用户密码
- JSONObject.toBean() 把jsonobject转换成实体类
热门文章
- 山外山科创板上市破发:首日下挫19% 公司市值38亿
- Cfree之万能头函数bits\stdc++.h的添加和注意事项
- 极限中0除以常数_用计算器按出来的常数费根鲍姆常数
- 小黑升级记----记ThinkPad470p加装固态盘
- Webix JavaScript UI 9.1.6
- openssl ca(签署和自建CA)
- (附源码)ssm基于微信小程序的恋上诗词设计与实现 毕业设计 011431
- 引水工程 最小生成树
- 操作系统:线程死锁、饥饿、活锁
- CVPR 2022 | “直面真实的世界”