天天看点

k8s调用gpu,nvidia-docker使用gpu

       本来以为这周关于gpu的运行又要搞不定了,结果昨天,也就是周五下午,终于搞定了,内心很开森有木有,一周了,终于over了,下来我来说下我的做法。还有我要说下,没事要多去github上灌灌水,收获还是颇多的,说不定就能解决困扰好久的问题。再次感谢各位大神的分享。

       首先介绍下nvidia-docker,这是一个可以使用gpu的docker,我的理解是nvidia-docker是在docker上做了一层封装,具体还是要看源码的。通过nvidia-docker-plugin,最终还是转回调用到docker上,只不过为docker的启动带了一些必要的参数。这个是同事看nvidia-docker底层源码告诉我的。

k8s调用gpu,nvidia-docker使用gpu

    docker一般都是使用基于cpu的应用,而如果是gpu的话,就需要安装特有的硬件环境,比如需要安装nvidia driver。所以docker容器并不直接支持nvidia gpu。为了解决这个问题,最早的处理办法是在容器内部,全部重新安装nvidia driver,然后通过设置相应的设备参数来启动container,然而这种办法是很脆弱的。因为宿主机的driver的版本必须完全匹配容器内的driver版本,这样导致docker image无法共享,很可能本地机器的不一致导致每台机器都需要去重复操作,这很大的违背了docker的设计之初。

    为了使docker image能很便利的使用nvidia gpu,从而产生了nvidia-docker,由它来制作nvidia driver的image,这就要求在目标机器上启动container时,确保字符设备以及驱动文件已经被挂载。

    nvidia-docker-plugin是一个docker plugin,被用来帮助我们轻松部署container到gpu混合的环境下。类似一个守护进程,发现宿主机驱动文件以及gpu 设备,并且将这些挂载到来自docker守护进程的请求中。以此来支持docker gpu的使用。

    上面简单介绍下nvidia-docker,下面我说下如何通过k8s来调用gpu参与计算,也就是回答我上篇的疑惑。我的具体做法如下:

    我的yaml文件格式如下:

apiVersion: v1
kind: Pod
metadata:
  name: gpu-test
spec:
  volumes:
  - name: nvidia-driver
    hostPath:
      path: /var/lib/nvidia-docker/volumes/nvidia_driver/367.44
  containers:
  - name: tensorflow
    image: tensorflow:0.11.0-gpu
    ports:
    - containerPort: 8000
    resources:
      limits:
        alpha.kubernetes.io/nvidia-gpu: 1
    volumeMounts:
    - name: nvidia-driver
      mountPath: /usr/local/nvidia/
      readOnly: true
           

    注意红色字体,alpha.kubernetes.io/nvidia-gpu: 1   表示只使用1块gpu(目前gpu的调度分配还未完全支持,社区没有正式发布版本,代码据说已经合入)

   path: /var/lib/nvidia-docker/volumes/nvidia_driver/367.44         宿主机driver位置,这个似乎是装了nvidia-docker之后有的,当然需要保证宿主机nvidia driver是已经安装ok的,应该是安装了nvidia-docker之后,会发现宿主机的driver,然后映射到此

   最后一个是container的内部挂载路径,没啥说的。

   我之前是因为进入容器之后,老是报错:could'n open libcuda.so.1, can't open library, no file libucuda.so

   所以应该是我挂载的路径没找对导致,所以如上之后,进入容器,彻底ok,并且运行代码,也是确认跑到了gpu上,所以我的问题就ok了。借助nvidia-docker的映射主机driver,解决container driver的挂载,所以挂载正确,那么底层执行docker同样ok,因为所缺文件都已经找到,所以也就不用烦恼于我上一篇的docker与nvidia-docker如何被k8s调用的一致性问题了。因为我的最终目的是运行gpu,我不想感知底层到底是docker还是nvidia-docker。至此,问题解决。

   后续会关注k8s的新功能,关于gpu的调度以及分配问题。(当然,切记要使用gpu,那么你的kubelet配置参数:--experimental-nvidia-gpu必须配置)

关联:

https://github.com/NVIDIA/nvidia-docker/wiki/Why%20NVIDIA%20Docker

https://github.com/NVIDIA/nvidia-docker/wiki/nvidia-docker-plugin

https://github.com/kubernetes/kubernetes/issues/42146