Nvidia GPU如何在Kubernetes 里工作

Nvidia GPU如何在Kubernetes 里工作

本文介绍Nvidia GPU设备如何在Kubernetes中管理调度。 整个工作流程分为以下两个方面:

  • 如何在容器中使用GPU
  • Kubernetes 如何调度GPU

如何在容器中使用GPU

想要在容器中的应用可以操作GPU, 需要实两个目标

  1. 容器中可以查看GPU设备
  2. 容器中运行的应用,可以通过Nvidia驱动操作GPU显卡

详细介绍可见: https://devblogs.nvidia.com/gpu-containers-runtime/

Nvidia-docker

GitHub: https://github.com/NVIDIA/nvidia-docker
Nvidia提供Nvidia-docker项目,它是通过修改Docker的Runtime为nvidia runtime工作,当我们执行 nvidia-docker create 或者 nvidia-docker run    时,它会默认加上 --runtime=nvidia 参数。将runtime指定为nvidia。
当然,为了方便使用,可以直接修改Docker daemon 的启动参数,修改默认的 Runtime为 nvidia-container-runtime 

cat /etc/docker/daemon.json
{"default-runtime": "nvidia","runtimes": {"nvidia": {"path": "/usr/bin/nvidia-container-runtime","runtimeArgs": []}}
}

gpu-containers-runtime

GitHub:  https://github.com/NVIDIA/nvidia-container-runtime
gpu-containers-runtime  是一个NVIDIA维护的容器 Runtime,它在runc的基础上,维护了一份 Patch, 我们可以看到这个patch的内容非常简单, 唯一做的一件事情就是在容器启动前,注入一个 prestart  的hook 到容器的Spec中(hook的定义可以查看 OCI规范 )。这个hook 的执行时机是在容器启动后(Namespace已创建完成),容器自定义命令(Entrypoint)启动前。nvidia-containers-runtime 定义的 prestart 的命令很简单,只有一句  nvidia-container-runtime-hook prestart  

gpu-containers-runtime-hook

GitHub: https://github.com/NVIDIA/nvidia-container-runtime/tree/master/hook/nvidia-container-runtime-hook 
gpu-containers-runtime-hook  是一个简单的二进制包,定义在Nvidia container runtime的hook中执行。 目的是将当前容器中的信息收集并处理,转换为参数调用 nvidia-container-cli  。
主要处理以下参数:

  • 根据环境变量 NVIDIA_VISIBLE_DEVICES 判断是否会分配GPU设备,以及挂载的设备ID。如果是未指定或者是 void ,则认为是非GPU容器,不做任何处理。   否则调用 nvidia-container-cli , GPU设备作为 --devices  参数传入
  •  环境环境变量 NVIDIA_DRIVER_CAPABILITIES 判断容器需要被映射的 Nvidia 驱动库。
  • 环境变量 NVIDIA_REQUIRE_*  判断GPU的约束条件。 例如 cuda>=9.0 等。 作为 --require= 参数传入
  • 传入容器进程的Pid

gpu-containers-runtime-hook  做的事情,就是将必要的信息整理为参数,传给 nvidia-container-cli configure 并执行。

nvidia-container-cli

nvidia-container-cli 是一个命令行工具,用于配置Linux容器对GPU 硬件的使用。支持

  • list:  打印 nvidia 驱动库及路径
  • info:  打印所有Nvidia GPU设备
  • configure: 进入给定进程的命名空间,执行必要操作保证容器内可以使用被指定的GPU以及对应能力(指定 Nvidia 驱动库)。 configure是我们使用到的主要命令,它将Nvidia 驱动库的so文件 和 GPU设备信息, 通过文件挂载的方式映射到容器中。

代码如下: https://github.com/NVIDIA/libnvidia-container/blob/master/src/cli/configure.c#L272

        /* Mount the driver and visible devices. */if (perm_set_capabilities(&err, CAP_EFFECTIVE, ecaps[NVC_MOUNT], ecaps_size(NVC_MOUNT)) < 0) {warnx("permission error: %s", err.msg);goto fail;}if (nvc_driver_mount(nvc, cnt, drv) < 0) {warnx("mount error: %s", nvc_error(nvc));goto fail;}for (size_t i = 0; i < dev->ngpus; ++i) {if (gpus[i] != NULL && nvc_device_mount(nvc, cnt, gpus[i]) < 0) {warnx("mount error: %s", nvc_error(nvc));goto fail;}}

如果对其他模块感兴趣,可以在 https://github.com/NVIDIA/libnvidia-container  阅读代码。

以上就是一个nvidia-docker的容器启动的所有步骤。

当我们安装了nvidia-docker, 我们可以通过以下方式启动容器

docker run --rm -it -e NVIDIA_VISIBLE_DEVICES=all ubuntu:18.04

在容器中执行 mount  命令,可以看到名为 libnvidia-xxx.so 和 /proc/driver/nvidia/gpus/xxx  映射到容器中。 以及 nvidia-smi 和 nvidia-debugdump 等nvidia工具。

# mount 
##  ....
/dev/vda1 on /usr/bin/nvidia-smi type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/vda1 on /usr/bin/nvidia-debugdump type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/vda1 on /usr/bin/nvidia-persistenced type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/vda1 on /usr/bin/nvidia-cuda-mps-control type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/vda1 on /usr/bin/nvidia-cuda-mps-server type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/vda1 on /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.396.37 type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/vda1 on /usr/lib/x86_64-linux-gnu/libnvidia-cfg.so.396.37 type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/vda1 on /usr/lib/x86_64-linux-gnu/libcuda.so.396.37 type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/vda1 on /usr/lib/x86_64-linux-gnu/libnvidia-opencl.so.396.37 type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/vda1 on /usr/lib/x86_64-linux-gnu/libnvidia-ptxjitcompiler.so.396.37 type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/vda1 on /usr/lib/x86_64-linux-gnu/libnvidia-fatbinaryloader.so.396.37 type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/vda1 on /usr/lib/x86_64-linux-gnu/libnvidia-compiler.so.396.37 type ext4 (ro,nosuid,nodev,relatime,data=ordered)
devtmpfs on /dev/nvidiactl type devtmpfs (ro,nosuid,noexec,relatime,size=247574324k,nr_inodes=61893581,mode=755)
devtmpfs on /dev/nvidia-uvm type devtmpfs (ro,nosuid,noexec,relatime,size=247574324k,nr_inodes=61893581,mode=755)
devtmpfs on /dev/nvidia-uvm-tools type devtmpfs (ro,nosuid,noexec,relatime,size=247574324k,nr_inodes=61893581,mode=755)
devtmpfs on /dev/nvidia4 type devtmpfs (ro,nosuid,noexec,relatime,size=247574324k,nr_inodes=61893581,mode=755)
proc on /proc/driver/nvidia/gpus/0000:00:0e.0 type proc (ro,nosuid,nodev,noexec,relatime)

我们可以执行nvidia-smi查看容器中被映射的GPU卡

Kubernetes 如何调度GPU

之前我们介绍了如何在容器中使用Nvidia GPU卡。 那么当一个集群中有成百上千个节点以及GPU卡,我们的问题变成了如何管理和调度这些GPU。

Device plugin

Kubernetes 提供了Device Plugin 的机制,用于异构设备的管理场景。原理是会为每个特殊节点上启动一个针对某个设备的DevicePlugin pod, 这个pod需要启动grpc服务, 给kubelet提供一系列接口。

type DevicePluginClient interface {// GetDevicePluginOptions returns options to be communicated with Device// ManagerGetDevicePluginOptions(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*DevicePluginOptions, error)// ListAndWatch returns a stream of List of Devices// Whenever a Device state change or a Device disapears, ListAndWatch// returns the new listListAndWatch(ctx context.Context, in *Empty, opts ...grpc.CallOption) (DevicePlugin_ListAndWatchClient, 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(ctx context.Context, in *AllocateRequest, opts ...grpc.CallOption) (*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(ctx context.Context, in *PreStartContainerRequest, opts ...grpc.CallOption) (*PreStartContainerResponse, error)
}

DevicePlugin 注册一个 socket 文件到 /var/lib/kubelet/device-plugins/ 目录下,kubelet 通过这个目录下的socket文件向对应的 Device plugin 发送grpc请求。
本文不过多介绍Device Plugin 的设计, 感兴趣可以阅读这篇文章: https://yq.aliyun.com/articles/498185

Nvidia plugin

Github: https://github.com/NVIDIA/k8s-device-plugin
为了能够在Kubernetes中管理和调度GPU, Nvidia提供了Nvidia GPU的Device Plugin。 主要功能如下

  • 支持ListAndWatch 接口,上报节点上的GPU数量
  • 支持Allocate接口, 支持分配GPU的行为。 

Allocate 接口只做了一件事情,就是给容器加上 NVIDIA_VISIBLE_DEVICES  环境变量。 https://github.com/NVIDIA/k8s-device-plugin/blob/v1.11/server.go#L153

// Allocate which return list of devices.
func (m *NvidiaDevicePlugin) Allocate(ctx context.Context, reqs *pluginapi.AllocateRequest) (*pluginapi.AllocateResponse, error) {devs := m.devsresponses := pluginapi.AllocateResponse{}for _, req := range reqs.ContainerRequests {response := pluginapi.ContainerAllocateResponse{Envs: map[string]string{"NVIDIA_VISIBLE_DEVICES": strings.Join(req.DevicesIDs, ","),},}for _, id := range req.DevicesIDs {if !deviceExists(devs, id) {return nil, fmt.Errorf("invalid allocation request: unknown device: %s", id)}}responses.ContainerResponses = append(responses.ContainerResponses, &response)}return &responses, nil
}

前面我们提到, Nvidia的 gpu-container-runtime  根据容器的 NVIDIA_VISIBLE_DEVICES 环境变量,会决定这个容器是否为GPU容器,并且可以使用哪些GPU设备。 而Nvidia GPU device plugin做的事情,就是根据kubelet 请求中的GPU DeviceId, 转换为 NVIDIA_VISIBLE_DEVICES 环境变量返回给kubelet, kubelet收到返回内容后,会自动将返回的环境变量注入到容器中。当容器中包含环境变量,启动时 gpu-container-runtime  会根据 NVIDIA_VISIBLE_DEVICES 里声明的设备信息,将设备映射到容器中,并将对应的Nvidia Driver Lib 也映射到容器中。

总体流程

整个Kubernetes调度GPU的过程如下:

  • GPU Device plugin 部署到GPU节点上,通过 ListAndWatch  接口,上报注册节点的GPU信息和对应的DeviceID。 
  • 当有声明 nvidia.com/gpu  的GPU Pod创建出现,调度器会综合考虑GPU设备的空闲情况,将Pod调度到有充足GPU设备的节点上。
  • 节点上的kubelet 启动Pod时,根据request中的声明调用各个Device plugin 的 allocate接口, 由于容器声明了GPU。 kubelet 根据之前 ListAndWatch 接口收到的Device信息,选取合适的设备,DeviceID 作为参数,调用GPU DevicePlugin的 Allocate 接口
  • GPU DevicePlugin ,接收到调用,将DeviceID 转换为 NVIDIA_VISIBLE_DEVICES 环境变量,返回kubelet
  • kubelet将环境变量注入到Pod, 启动容器
  • 容器启动时, gpu-container-runtime 调用 gpu-containers-runtime-hook 
  • gpu-containers-runtime-hook  根据容器的 NVIDIA_VISIBLE_DEVICES 环境变量,转换为 --devices 参数,调用 nvidia-container-cli prestart  
  • nvidia-container-cli 根据 --devices ,将GPU设备映射到容器中。 并且将宿主机的Nvidia Driver Lib 的so文件也映射到容器中。 此时容器可以通过这些so文件,调用宿主机的Nvidia Driver。


原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/519562.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql的每隔1分钟定时_简单易用,spring boot集成quartz,实现分布式定时任务

什么是quartz&#xff1f;Quartz是一个完全由 Java 编写的开源任务调度框架。我们经常会遇到一些问题&#xff1a;想每个月27号&#xff0c;提醒信用卡还款&#xff1b;想每隔1小时&#xff0c;提醒一下&#xff0c;累了&#xff0c;站起来活动一下&#xff1b;想每个月定时发送…

阿里云安全肖力:从RSA2019看安全技术发展的十个机遇

又一年RSA大会归来。每一年参会&#xff0c;总会有一些不同的感悟&#xff0c;或是发现全球安全行业的新趋势&#xff0c;或是找到志同道合的新伙伴&#xff0c;或是看到很多人也相信我们相信的安全技术新方向。今天在回国的航班上提笔写下我的感悟和判断&#xff0c;希望对安全…

华为组织架调整,CloudAI升至第四大BG,打通全球第一款集成5G模组的4K直播编码器网络通信服务;谷歌宣布与IBM合作……...

关注并标星星CSDN云计算 速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周两次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go goIntel 10nm Tiger Lake晶圆首曝&#xff1a;核心面…

flowable DMN部署单独使用_06

文章目录配置规则部署使用项目地址&#xff1a;https://gitee.com/lwj/flowable.git 分支flowable-base视频地址&#xff1a;https://www.bilibili.com/video/av79774697/DMN部署&#xff1a; dmn制定了规则之后&#xff0c;还需要部署好才能用DMN部署&#xff0c;独立使用 配…

SpringBoot使用SOFA-Lookout监控

本文介绍SpringBoot使用蚂蚁金服SOFA-Lookout配合Prometheus进行监控。 1.SOFA-Lookout介绍 上一篇已经介绍使用Prometheus进行暴露SpringBoot的一些指标进行监控&#xff0c;传送门&#xff0c;这一篇介绍如何使用SOFA-Lookout配合Prometheus。 SOFA-Lookout是蚂蚁金服开源的…

python迷宫小游戏大全_Python迷宫小游戏源代码、源程序

Python迷宫小游戏源程序包括两个文件maze.py和mazeGenerator.py&#xff0c;mazeGenerator.py实现迷宫地图的生成&#xff0c;程序运行截图&#xff1a;mazeGenerator.pyimport numpy as npimport randomimport copyclass UnionSet(object): """ 并查集实…

NoSQL最新现状和趋势:云NoSQL数据库将成重要增长引擎

NoSQL最早起源于1998年&#xff0c;但从2009年开始&#xff0c;NoSQL真正开始逐渐兴起和发展。回望历史应该说NoSQL数据库的兴起&#xff0c;完全是十年来伴随互联网技术&#xff0c;大数据数据的兴起和发展&#xff0c;NoSQL在面临大数据场景下相对于关系型数据库运用&#xf…

详谈ARM架构与ARM内核发展史

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 架构师技术联盟责编 | 阿秃1、ARM架构与ARM内核1.1 ARM架构与内核简述目前为止&#xff0c;ARM总共发布8种架构&#xff1a;ARMv1、ARMv2、ARMv3、ARMv4、ARMv5、ARMv6、ARMv7 、ARMv8&#xff0c;这是ARM架构指令集的多个v版…

DMN结合bpmn简化流程_07

项目地址&#xff1a;https://gitee.com/lwj/flowable.git 分支flowable-base 视频地址&#xff1a;https://www.bilibili.com/video/av79774697/ DMN集成到BPMN中使用 简化流程&#xff0c;让我们的BPMN显得更加优雅 * DMN集成bpmn使用 新建决策树模板 注意一定要部署&…

阿里云RPA(机器人流程自动化)干货系列之一:认识RPA(上)

本文是阿里云RPA&#xff08;机器人流程自动化&#xff09;干货系列的开山之作&#xff0c;全面、详细的剖析了RPA的基本概念、给企业带来的价值点以及RPA的优劣势分析。 一、什么是RPA&#xff1f; 人类社会进入21世纪的第一个十年之后&#xff0c;全球企业大都面临着两个严峻…

linux pip3使用清华源_Linux实战016:Ubuntu搭建python开发环境

我们在安装Ubuntu系统的时候会自带安装python2.7和python3.6版本的Python解释器&#xff0c;直接执行"ptyhon"默认运行的是python2.7&#xff0c;只有执行"python3"时才会运行python3.6版本。Python解释器默认安装在/usr/bin目录下&#xff0c;但是Ubuntu并…

编写一个C程序,实现以下功能:定义一个学生结构体Student(含学号、姓名、年龄、身高)和一个函数sort(struct Student *p),该函数使用选择排序法按年龄由小到大排序。在主函数中

编写一个C程序&#xff0c;实现以下功能&#xff1a; 定义一个学生结构体Student(含学号、姓名、年龄、身高)和一个函数sort(struct Student *p)&#xff0c;该函数使用选择排序法按年龄由小到大排序。在主函数中输入10个学生的学号、姓名、年龄和身高&#xff0c;调用sort函数…

在抖音上刷到AI程序员的工资条后,我笑了,别吹了!

2020年&#xff0c;程序员会怎么样&#xff1f;A与B &#xff0c;薪酬与前景程序员与远方2017年~2018年&#xff0c;是人工智能大火的时候。你会发现&#xff0c;跟朋友聊天不谈人工智能&#xff0c;聊天的bigger都上不去。作为一个前景明朗的朝阳行业&#xff0c;高薪吸引&…

C++面向对象思想 两条直线交点计算

我相信哪怕一点光&#xff0c;也能驱散学习中的迷雾&#xff0c;我在这分享一点自己的挫见 思路&#xff1a; 这题最大的难点就是abc三个常数要怎么去构造&#xff0c;这里需要数学公式去推导&#xff0c;虽然是初中水平&#xff0c;也能体现编程和数学密不可分了。因为我之后…

K8s 实践 | 如何解决多租户集群的安全隔离问题?

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 匡大虎责编 | 阿秃导读&#xff1a;如何解决多租户集群的安全隔离问题是企业上云的一个关键问题&#xff0c;本文主要介绍 Kubernetes 多租户集群的基本概念和常见应用形态&#xff0c;以及在企业内部共享集群的业务场景下&a…

scara机器人dh参数表_两分钟带你了解机器人标定的因素

为什么机器人需要标定&#xff1f;影响机器人本体精度因素分为两大类&#xff1a;运动学因素——加工误差、机械公差/装配误差、减速器精度、减速器空程等&#xff1b;动力学因素——质量、惯性张量、摩擦力、关节柔性、连杆柔性。机器人本体的实际精度和理论设计模型可能会存在…

Git的3大区域

为什么使用git&#xff1f; 为了保存文件的每一个历史记录&#xff0c;以便查看每一个历史节点的文件变动情况和把错误的的历史节点回滚。 git分为3个区域&#xff0c;工作区、暂存区、版本库(本地)。 工作区包括git已经管理的文件区域和新增以及修改的文件区域 暂存区&#x…

python编辑学生分数_python处理excel(04)数据筛选和过滤

源数据&#xff0c;我们最终要找出年龄在18——30岁之间&#xff0c;分数大于85分的学生&#xff0c;为A类学生。在excel里可以使用筛选功能&#xff0c;先筛选age列&#xff0c;大于等于、小于。这两个条件限制。然后选score后边的小三角&#xff0c;条件为大于等于85.最终数据…

如何打通“鱼塘” ?腾讯启动“SaaS技术联盟” 共建技术中台

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 刘丹出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;“SaaS企业迎来了最好的时代。一方面&#xff0c;产业互联网大潮已至&#xff0c;中国企业降本增效的需求提升&#xff1b;另一方面&#xff0c;云计算…

Git 回滚

文章目录1. 简述2. 命令版本3. idea 图形化版本(场景1)4. idea 图形化版本(场景2)1. 简述 Git 回滚&#xff1a;常见的有2种场景&#xff0c;第一种是回滚到之前版本&#xff0c;第二种是回滚到之后的版本。 2. 命令版本 用到的命令&#xff1a; 场景1(回滚之前的版本)&…