从零搭建可分配节点GPU资源至容器的Kubernetes集群(Nvidia版本)_pod指定不同runtime nvidia_T型人小付的博客-程序员秘密

技术标签: Devops - Kubernetes  

最近和AI团队一起做项目,需要将机器学习的项目部署进k8s。因为要使用节点的GPU资源,普通部署的k8s集群不能用了,因为docker只能对CPU和内存而不能对GPU资源进行共享和隔离。这一节我们就一起来看看怎么部署一个能分配GPU资源的k8s集群。

我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

操作环境

  • master(CPU) - ubuntu 18.04
  • gpu-node(GPU) - ubuntu 18.04

利用kubeadm安装

基本上跟着《【Kubernetes 003】Centos7通过Kubeadm安装Kubernetes1.15详解(附一键安装脚本)》进行安装即可成功创建集群。Centos和Ubuntu的命令稍微有些不同,但是大同小异,不影响整体步骤。

但是如果想在GPU节点的pod内使用GPU资源,还得对GPU节点做一些特殊的设定。所以请在将GPU节点加入master之前,对GPU节点完成下述操作

GPU节点安装准备

查看Linux的GPU信息

先更新本地数据库,然后获取GPU的详细信息

sudo update-pciids
sudo lspci | grep VGA -A 10

如果lspci命令没有找到,先通过下面命令安装

sudo yum install pciutils

我这边机器信息如下

[email protected]:~# lspci -v | grep VGA -A 10
01:00.0 VGA compatible controller: NVIDIA Corporation TU104 [GeForce RTX 2070 SUPER] (rev a1) (prog-if 00 [VGA controller])
	Subsystem: Micro-Star International Co., Ltd. [MSI] Device c729
	Flags: bus master, fast devsel, latency 0, IRQ 130
	Memory at a3000000 (32-bit, non-prefetchable) [size=16M]
	Memory at 90000000 (64-bit, prefetchable) [size=256M]
	Memory at a0000000 (64-bit, prefetchable) [size=32M]
	I/O ports at 3000 [size=128]
	[virtual] Expansion ROM at 000c0000 [disabled] [size=128K]
	Capabilities: [60] Power Management version 3
	Capabilities: [68] MSI: Enable+ Count=1/1 Maskable- 64bit+
	Capabilities: [78] Express Legacy Endpoint, MSI 00

如果跟我的机器一样是nvidia的显卡,根据显示的型号去查询支持的最新driver,安装完driver就会有管理工具nvidia-smi

nvidia显卡持续查看使用情况,每秒更新一次

watch -n 1 nvidia-smi

我这边的GPU和driver信息如下

[email protected]:~# nvidia-smi
Tue May 19 10:58:25 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 435.21       Driver Version: 435.21       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce RTX 207...  Off  | 00000000:01:00.0 Off |                  N/A |
| 24%   28C    P8    11W / 215W |     19MiB /  7982MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1765      G   /usr/lib/xorg/Xorg                             9MiB |
|    0      1799      G   /usr/bin/gnome-shell                           8MiB |
+-----------------------------------------------------------------------------+
  • Nvidia GeForce RTX 2070 SUPER
  • Driver版本 435.21
  • 显存大小 7982MiB

安装nvidia-docker2

下面对原生docker进行改进,使其能使用GPU资源。不同厂商有自己的解决方法,Nvidia官方推出了nvidia-docker来对原生进行改善,目前是2.x版本,说明看这里

首先确保安装了nvidia driver以及原生docker,然后跟着这里的方法安装repo,命令如下

curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
  sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update

之后就可以搜索到了,这里是2.3版本

[email protected]:~# apt search nvidia-docker
Sorting... Done
Full Text Search... Done
nvidia-docker2/bionic 2.3.0-1 all
  nvidia-docker CLI wrapper

因为后面还要安装别的插件,有兼容性问题,请确保版本在2.0以上

然后安装nvidia-docker2

sudo apt-get install -y nvidia-docker2

在最后会问你要如何操作/etc/docker/daemon.json这个文件

Configuration file '/etc/docker/daemon.json'
 ==> File on system created by you or by a script.
 ==> File also in package provided by package maintainer.
   What would you like to do about it ?  Your options are:
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version
      D     : show the differences between the versions
      Z     : start a shell to examine the situation
 The default action is to keep your current version.
*** daemon.json (Y/I/N/O/D/Z) [default=N] ?

这里我们直接选择Y让安装程序去覆盖现有文件,如下

[email protected]:~# cat /etc/docker/daemon.json
{
    "runtimes": {
        "nvidia": {
            "path": "nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

可以看到为docker添加了一个新的runtime

重启一下docker服务

service docker restart

这样在机器上就多了一个docker的runtime,在跑docker的时候可以指定runtime

docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi

或者用下面的方法一劳永逸直接将nvidia指定为默认的runtime,代替runc

# Update the default configuration and restart
pushd $(mktemp -d)
(sudo cat /etc/docker/daemon.json 2>/dev/null || echo '{}') | \
    jq '. + {"default-runtime": "nvidia"}' | \
    tee tmp.json
sudo mv tmp.json /etc/docker/daemon.json
popd
sudo systemctl restart docker

# No need for nvidia-docker or --engine=nvidia
docker run --rm -it nvidia/cuda nvidia-smi

通过下面的命令查看是否成功

docker info | grep nvidia

如果出现下面的信息表示已经成功将nvidia变为默认的docker runtime,代表容器可以使用GPU资源了

[email protected]:~# docker info | grep nvidia
WARNING: No swap limit support
Runtimes: nvidia runc
Default Runtime: nvidia

GPU节点加入集群

完成上述步骤,按照master的log信息将GPU节点加入集群,之后就会看到有两个node

[email protected]:~# kubectl get node
NAME              STATUS   ROLES    AGE   VERSION
control-plane-1   Ready    master   80m   v1.15.10
gpu-node          Ready    <none>   53m   v1.15.10

我这里对master设置了taint,不允许pod被调度到master上

[email protected]:~# kubectl describe node control-plane-1 | grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule

安装插件

虽然容器可以使用GPU资源了,此时如果试着去跑官方给的GPU的测试deployment,会发现所有pod都在pending状态,查看pod状态会出现如下报错

Events:
  Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning  FailedScheduling  48s (x18 over 24m)  default-scheduler  0/2 nodes are available: 2 Insufficient nvidia.com/gpu.

根据k8s官方文档对于GPU分配的说明,必须要安装另一个第三方的Nvidia插件才可以完成。

官方给出的插件对于GPU的分配不够智能和灵活,我们采用Aliyun的一个extender

自带插件的说明,不建议使用
http://www.podman.cn/?/article/7

阿里云的extender说明,颗粒更细
https://blog.spider.im/post/gpu-share-in-k8s/

步骤有点多,直接按照官方安装指导书一步步来。

部署extender

cd /etc/kubernetes/
curl -O https://raw.githubusercontent.com/AliyunContainerService/gpushare-scheduler-extender/master/config/scheduler-policy-config.json
cd /tmp/
curl -O https://raw.githubusercontent.com/AliyunContainerService/gpushare-scheduler-extender/master/config/gpushare-schd-extender.yaml
kubectl create -f gpushare-schd-extender.yaml

修改scheduler配置

目标是将/etc/kubernetes/scheduler-policy-config.json加入到/etc/kubernetes/manifests/kube-scheduler.yaml配置中。需要注意的是需要先在/etc/kubernetes/manifests/目录外生成配置文件再复制到目录内,触发静态pod的自动更新

首先复制配置文件

sudo cp /etc/kubernetes/manifests/kube-scheduler.yaml /tmp

然后模仿这个示例添加下面的两部分内容

- --policy-config-file=/etc/kubernetes/scheduler-policy-config.json
- mountPath: /etc/kubernetes/scheduler-policy-config.json
  name: scheduler-policy-config
  readOnly: true
- hostPath:
      path: /etc/kubernetes/scheduler-policy-config.json
      type: FileOrCreate
  name: scheduler-policy-config

然后复制回去

sudo cp /tmp/kube-scheduler.yaml /etc/kubernetes/manifests/kube-scheduler.yaml

检查发现shceduler的pod重启了表示修改生效

配置Device Plugin

注意如果这里已经配置了官方的Device Plugin例如nvidia-device-plugin,需要先删除

wget https://raw.githubusercontent.com/AliyunContainerService/gpushare-device-plugin/master/device-plugin-rbac.yaml
kubectl create -f device-plugin-rbac.yaml
wget https://raw.githubusercontent.com/AliyunContainerService/gpushare-device-plugin/master/device-plugin-ds.yaml
kubectl create -f device-plugin-ds.yaml

将GPU节点打上label

kubectl label node <target_node> gpushare=true

安装kubectl的扩展

cd /usr/bin/
wget https://github.com/AliyunContainerService/gpushare-device-plugin/releases/download/v0.3.0/kubectl-inspect-gpushare
chmod u+x /usr/bin/kubectl-inspect-gpushare

之后就可以用下面的命令查看GPU的分配情况了

[email protected]:~# kubectl-inspect-gpushare
NAME      IPADDRESS      GPU0(Allocated/Total)  GPU Memory(GiB)
gpu-node  172.29.57.202  0/7                    0/7
---------------------------------------------------
Allocated/Total GPU Memory In Cluster:
0/7 (0%)  

我这里有7G的显存,所以显示为7。更详细的信息可以查看kubectl-inspect-gpushare -d

GPU分配测试

想要申请GPU,只需要声明aliyun.com/gpu-mem即可,单位是GiB。

例如如下测试文件deployment.yaml起两个pod,每个pod生成1GiB的GPU

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nvidia-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      name: nvidia-gpu-deploy
  template:
    metadata:
      labels:
        name: nvidia-gpu-deploy
    spec:
      containers:
      - name: cuda-container
        image: ubuntu
        command: ["sleep"]
        args: ["100000"]
        resources:
          limits:
            aliyun.com/gpu-mem: 1

等两个pod起来以后查看分配情况

[email protected]:~/nvidia-test# kubectl-inspect-gpushare -d

NAME:       gpu-node
IPADDRESS:  172.29.57.202

NAME                                NAMESPACE  GPU0(Allocated)  
nvidia-deployment-5f4bbd9457-h4rfk  default    1                
nvidia-deployment-5f4bbd9457-wqx8v  default    1                
Allocated :                         2 (28%)    
Total :                             7          
------------------------------------------------------------------------------------------------------


Allocated/Total GPU Memory In Cluster:  2/7 (28%)  

删除kubeadm创建的集群

如果因为某些原因要销毁整个集群也很容易,因为是用kubeadm搭建的,只需要用下面的命令就可以

kubeadm reset

总结

在k8s中部署GPU机器学习程序已经成为一种趋势,虽然原生docker对GPU的支持没跟上,但是厂商的支持还是很多的,可以多去看看Nvidia的文档,很详细。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Victor2code/article/details/106226622

智能推荐

android-Copy and Paste(text and input)_安卓input paste_邓文(desaco)的博客-程序员秘密

Android provides a powerful clipboard-based framework for copying and pasting. It supports both simple and complex data types, including text strings, complex data structures, text and binary stream

Mybatis动态拼接SQL_mybatis中动态拼接sql_StartGala的博客-程序员秘密

MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。MyBatis中用于实现动态SQL的元素主要有: if choose(when,otherwise) trim where set foreach

unity移动游戏优化指南_unity 手游优化_an逞祥的博客-程序员秘密

这里写目录标题简介性能分析CPU Usage Profiler 模块内存自适应性能编程和代码架构项目配置资源图形和GPU优化用户界面音频动画物理工作流程和协作简介优化 iOS 和 Android 应用程序是支撑整个开发周期的重要过程。随着移动硬件的不断发展,移动游戏的优化及其美术、游戏设计、音频和变现策略在塑造玩家体验方面发挥着关键作用。原地址:https://learn.u3d.cn/tutorial/mobile-game-optimization?tab=overview#611644ef7c

十大排序算法C++实现_b_ingram_宁海没有七号公园的博客-程序员秘密

总结整理排序算法:Nothing to say~~正文开始@Assassin目录:总结整理排序算法:排序算法概览:1. 冒泡排序:2. 选择排序:3. 插入排序:4. 快速排序:5. 堆排序:6. 归并排序:7. 希尔排序:8. 计数排序:9. 桶排序:10. 基数排序:see you next blog~~排序算法概览:排序算法平均时间复杂度最差时间复杂度空间复杂度数据对象稳定性冒泡排序O(n2)O(n2)O(1)稳定选择排序O(n2)O(n2)

yolov5中的mosaic实现原理_mosaic原理_龙城肥酱的博客-程序员秘密

yolov5中的mosaic实现原理mosaic图像增强技术基于现有数据极大的丰富了样本的多样性,极大程度降低了模型对于多样性学习的难度本文将对yolov5中mosaic实现的核心源码进行解析并结合自身项目经历谈下其局限性mosaic实现位于datasets.py中的load_mosaic()函数,入参是当前训练的图片序号,出参是一幅经过mosaic图像增强的图片及其label经过如下步骤得到mosaic增强图像:step1. 假设模型输入尺寸为s,生成一幅尺寸为2s * 2s的灰色图

Taro学习手册(三)——单击、双击、长按_taro3长按选中_kelly0721的博客-程序员秘密

这个动作判断比较简单,单击和长按都可以调用相应的API,双击就要做点判断单击:判断是否点击, 通过 onTouchStart 触发双击:判断两次点击的时间间隔,通过 onTouchStart触发+自定义函数实现长按:手指触摸后,超过350ms再离开,通过 onLongPress 触发&lt;View className='col' key={index} onTouchStart=...

随便推点

【电路方案】基于单片机温控电风扇智能调速器设计/单片机出租车打表计价器系统设计/51单片机篮球积分器仿真系统/51单片机超声波模块测距/单片机PID算法的温度控制调节器/单片机炉温温度恒温控制系统设计_adc控制风扇风速电路_BINGHANYULENG的博客-程序员秘密

基于单片机温控电风扇智能调速器的设计749本设计为一种温控风扇系统,具有灵敏的温度感测和显示功能,系统STC89C52单片机作为控制平台对风扇转速进行控制。可由用户设置高、低温度值,测得温度值在高低温度之间时打开风扇弱风档,当温度升高超过所设定的温度时自动切换到大风档,当温度小于所设定的温度时自动关闭风扇,控制状态随外界温度而定。所设高低温值保存在温度传感器DS18B20内部E2ROM中,掉电后仍然能保存上次设定值,性能稳定,控制准确。#include &lt;reg52.h&gt;

CTFshow单身杯 部分wp_musc ctf_FW_Suica的博客-程序员秘密

前言:不会吧不会吧不会有人520521不约会打比赛吧文章目录1、单身杯热身题目2、misc签到3、没大没小的串串4、任性老板5、蛤壳雪茄-16、蛤壳雪茄-27、The Dancing Men8、伪装成RSA的MUSC9、re签到10、magic1、单身杯热身题目应该是后台做了日期相关的验证,反正照常输一个日期不要太离谱的就哦了2、misc签到题目提示:下载附件,ARCHPR爆破所有可打印字符,位数为5位,得到压缩包密码[email protected]打开解压得到的图片可以找到base6.

Aixcode代码自动补全插件的安装和使用_bigbear776的博客-程序员秘密

最近在技术公众号上看到大佬们说到一款代码自动补全的智能插件aixcode,官方是这样宣传的智能代码提示 她用强大的深度学习引擎,能给出更加精确的代码提示; 代码风格检查 她有代码风格智能检查能力,帮助开发者改善代码质量; 编程模式学习 她能自主学习开发者的编程模式,边用边学,越用越强; 为感受下是否真的有这样的魅力,遂体验一波1.首先在官方下载一个安装助手官方地...

【Python】Tkinter图形界面设计(GUI)_木子欢儿的博客-程序员秘密

简介作为 Python 开发者,图形用户界面(GUI)开发是必备技能之一。目前,市面上支持Python 的“GUI 工具包”很多,各有特点,虽然大多数工具包的基础类似,但要学习一个新包并掌握其细节还是非常耗时的,因此,在选用工具包时应仔细权衡。本文将介绍Python 自带的 GUI 工具包 TKinter。TKinterPython 的 GUI 库非常多,之所以选择 Tkint...

端到端深度学习与自动驾驶(含参考文献)_future.video_哀酱的博客-程序员秘密

参考文献见最后。1.自动驾驶系统的分类Rule based system基于规则的系统, 也有论文中将这样的方法叫做Mediated percepiton approach.Fully end-to-end 端到端的系统, 也有论文中叫做behavior reflex approach.Intermediate approach综合1、 2两种的综合性方法,如 Princeton的DeepDr

【Python】Python解释器的几种实现版本_python 如何讲 cpython linux 文件解析成py_王晓斌的博客-程序员秘密

Visualization 模块中部分代码存在 bug,以下修改来自Open Cascade 官方论坛中有人做的patch,及自己修改的(少部分): 1: TKV3d.dll1.1File:Visual3d_TransientManager.cxxFunc:BeginDraw();BeginAddDraw();ClearDr

推荐文章

热门文章

相关标签