场景

最近在工作中经常使用到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功能彻底移除?

  1. Kubernetes有一个核心理念:OutOfTree是一个很好的理念,简单来讲就是专注于自身核心和通用能力 将像GPU,InfiniBand,FPGA和公共云能力的工作完全交给社区和领域专家。这样一方面可以降低软件自身使用的复杂度,减小稳定性风险,另外OutOfTree分开迭代也能够更灵活实现的功能升级。

Device Plugin的设计:

实际上Device plugins实际上是简单的grpc server,需要实现以下两个方法 ListAndWatchAllocate,并监听在/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设计解读相关推荐

  1. Kubernetes的Device Plugin设计解读

    摘要: Kubernetes的生态地位已经确立,可扩展性将是其发力的主战场.异构计算作为非常重要的新战场,Kubernetes非常重视.而异构计算需要强大的计算力和高性能网络,需要提供一种统一的方式与 ...

  2. 谈 Kubernetes 的架构设计与实现原理

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 本文转载于公众号:真没什么逻辑 Kubernetes 基本上是这两年最热门.最被人熟知的技术了,它 ...

  3. rs结果集可以传递给另一个jsp吗_从未如此高调 宝骏RS-5独家设计解读

    [汽车之家 设计解码] 尽管宝骏多款"神车"已经用非常漂亮的销量数据打消了大家的疑虑,可事实上,它的车型就用途而言大多还是偏商用的,厂商也低调表示自己在乘用车方面还只是小学生.如今 ...

  4. Volcano 监控设计解读,一看就懂

    摘要:Volcano 方便AI,大数据,基因,渲染等诸多行业通用计算框架介入,提供高性能任务调度引擎,高性能异构芯片管理,高性能任务运行管理等能力. Volcano 是一个 Kubernetes 云原 ...

  5. Kubernetes 架构与设计

    什么是kubernetes? 官方说明: Kubernetes is an open-source system for automating deployment, scaling, and man ...

  6. Kubernetes v1.17 版本解读 | 云原生生态周报 Vol. 31

    作者 | 徐迪.李传云.黄珂.汪萌海.张晓宇.何淋波 .陈有坤.李鹏 审核 | 陈俊 上游重要进展 1. Kubernetes v1.17 版本发布 功能稳定性是第一要务.v1.17 包含 22 个增 ...

  7. Kubernetes滚动更新速率控制解读

    女主宣言 利用kubernetes的滚动更新时,可能经常遇到发布"太快不稳定"或"太慢体验差"的情况.本文将介绍kubernetes滚动更新控制速率的特性. P ...

  8. 干货|以产品要素设计解读线上小微信贷

    小微信贷市场中经常收到客户的一些反馈,如:没有房子抵押.额度不够.利率太高.期限短等等,这些反馈的声音主要集中在产品要素上,客户拿到的贷款就是这些产品要素的组合,换句话讲,这些要素也正是一款产品的卖点 ...

  9. Kubernetes 一指禅,文章集锦(实时更新)

    Kubernetes不简单,阿里云容器服务团队希望能通过这篇集锦助你一臂之力~ 你还有哪些学习和使用的困惑?请留言给我们哦~ Kubernetes 的ABC与解读 Kubernetes与Docker基 ...

最新文章

  1. 解决“SSL handshake failed“问题
  2. 将Sublime Text 2搭建成一个好用的IDE
  3. CSDN编程挑战——《交替字符串》
  4. 谁来理解外来工的孩子的心理健康?
  5. 飞鸽传书的这一新的通信方式采用云技术
  6. APACHE 403 FORBIDDEN错误的解决办法之一
  7. HTML5标准有缺陷 手机电池信息可泄露上网活动
  8. 【赶紧收藏】平面设计必备字体,广告设计常用字体
  9. 计算机的正确使用方法,电脑开关机的正确的操作步骤顺序(不会对电脑造成任何损坏)...
  10. node.js+cocoscreator自研斗地主游戏
  11. 《高绩效成果教练》课程笔记及思考
  12. vue使用LayIM组件接入第三方通讯平台:融云
  13. 什么是集成测试?集成测试方法有哪些?
  14. 运维常用工具命令/知识总结
  15. Xilinx 7系列FPGA收发器架构之硬件设计指导(一)
  16. 2021国防科技大学计算机学院无军籍考研409分经验贴(数一+英一+834)
  17. 手撕python_手撕编译器(一)——编译原理简介
  18. 关于宿舍熄灯问题的调研
  19. 女学霸考692分想当“程序媛”,女生到底要不要学计算机?
  20. 最新版ser2net移植到ARM板上,交叉编译

热门文章

  1. C#学生管理系统 -【部分代码2】
  2. ios解锁动态图片_iPhone不越狱如何设置酷炫的动态锁屏壁纸
  3. 2021年广西艺术高考成绩查询,2021广西艺术类统考成绩查询
  4. 臻和科技与依莫纳医疗共同开发mRNA肿瘤疫苗;赛多利斯中国应用与服务中心落地上海张江 | 医药健闻...
  5. java web前端攻城狮 学习路线图
  6. 推荐几本对于Python初学者比较好的书籍(内含PDF)
  7. 画好爆炸效果有哪些技巧?
  8. VLAN 0的作用说明
  9. php加解密易语言源码,易语言PHP加密源码
  10. org.yaml.snakeyaml.scanner.ScannerException: while scanning a simple key