K8S中支持GPU任务调度到GPU节点的生产实践

背景

大型互联网企业中,都有大量的AI应用,需要进行算法建模去驱动业务发展,其中肯定会用到深度学习,而深度学习就需要大量的计算资源GPU因为计算速度快成为了必选项,刚开始的时候可以直接在GPU机器上去进行算法训练,当AI模型多了之后这种方式带来很大的问题一个是模型训练效率低下,另外一个就是GPU资源利用率低,通常GPU是比较贵的,在降本增效的大背景下有必要有个统一的平台进行管理,目前大型企业构建基于GPU的深度学习训练平台基本上都是采用的K8S去管理调度GPU任务,这块就涉及到GPU驱动安装、GPU节点初始化、GPU节点纳管到K8S集群,本文就从GPU节点驱动安装开始讲述下如何支持K8S调度GPU。

K8S支持GPU调度实践

这块主要内容包含GPU节点初始化,GPU节点上docker gpu插件安装配置,最终的结果是把GPU节点纳入到K8S集群当中,成为k8S中一个计算节点,具体安装K8S计算节点纳管到K8S集群不在此处概述,不了解的可以查看之前写的一片文章: juejin.cn/post/708448…

显卡驱动安装

通常云厂商购买的GPU机器,需要自己安装相应版本的GPU驱动,我们先登陆机器产看下显卡的型号:这里用一台普通T4机器为例:

lspci | grep -i nvidia
00:08.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1)

对应显卡的驱动下载,推荐去nvidia官网去下载:官方驱动选择

wget https://cn.download.nvidia.com/tesla/450.80.02/NVIDIA-Linux-x86_64-450.80.02.run

驱动安装,直接sh运行相应的脚本:

sh  https://cn.download.nvidia.cNVIDIA-Linux-x86_64-450.80.02.run

Would you like to register the kernel module sources with DKMS? This will allow DKMS to automatically build a new module, if you install a different kernel later.

WARNING: nvidia-installer was forced to guess the X library path '/usr/lib64' and X module path '/usr/lib64/xorg/modules'; these paths were not queryable from the system.  If X fails to find the NVIDIA X
 driver module, please install the `pkg-config` utility and the X.Org SDK/development package for your distribution and reinstall the driver. 

查看是否安装成功

nvidia-smi

image.png 当nvidia-smi能够正常运行,代表GPU驱动安装成功

补充系统信息:

 $gcc --version

gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

 $uname -r

3.10.0-1160.62.1.el7.x86_64

K8S GPU节点操作

NVIDIA GPU 设备插件部署

官方的 NVIDIA GPU 设备插件 有以下要求:

  • Kubernetes 的节点必须预先安装了 NVIDIA 驱动

  • Kubernetes 的节点必须预先安装 nvidia-docker 2.0

  • Docker 的默认运行时必须设置为 nvidia-container-runtime,而不是 runc

  • NVIDIA 驱动版本 ~= 384.81

 安装nvidia-docker2.0工具
 
# 1、set yum安装仓库

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)

curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | \
sudo tee /etc/yum.repos.d/nvidia-docker.repo

# 2 、安装nvidia-docker2软件包并重新加载Docker守护程序配置:

sudo yum install -y nvidia-docker2
sudo pkill -SIGHUP dockerd

 3、重启下docker
 sudo systemctl restart docker

# 4 查看docker nvidia-container-runtime运行时配置
$ cat /etc/docker/daemon.json
{
    "default-runtime": "nvidia",
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}


# 注意因为安装nvidia-docker2覆盖了docker配置,需要重新加入,这里面预知了相关docker镜像仓库源,能够加快镜像的拉取

sudo tee /etc/docker/daemon.json <<EOF

{
"default-runtime": "nvidia",
"registry-mirrors": [ "https://1nj0zren.mirror.aliyuncs.com", "https://docker.mirrors.ustc.edu.cn", "http://f1361db2.m.daocloud.io", "https://registry.docker-cn.com"],
 "log-driver": "json-file",
   "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ],
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}
EOF

集群已经启动满足上述要求的话,接着部署 NVIDIA 设备插件:

kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/1.0.0-beta4/nvidia-device-plugin.yml

测试验证docker能正常挂载使用GPU

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

生产上K8S 多GPU类型管理

生产上GPU节点类型很多,许多计算对GPU的需求不一,有的需要V100、有的需要P40、有的普通的T4就可以了,有的还需要多几多卡,因此需要对其进行统一管理,资源隔离,K8S提供了节点打标的方式对Node进行标记,可以通过这种方式进行简单的处理:

#可以通过配置节点标签去调度GPU,比如为你的节点加上它们所拥有的加速器类型的标签

kubectl label nodes <node-with-k80> accelerator=t4
kubectl label nodes <node-with-p100> accelerator=nvidia-tesla-p100

K8S调度GPU任务运行测试

目的:主要测试tensorflow能够使用gpu 而且需要测试k8s可以调度到gpu节点上进行使用

  • 创建一个测试 pod

yaml文件如下:

在Master节点上创建~/tf-pod.yaml文件,内容如下:
apiVersion: v1
kind: Pod
metadata:
  name: tf-pod
spec:
  containers:
    - name: tf-container
      image: tensorflow/tensorflow:latest-gpu
      command: [ "/bin/sh" ]
      args: [ "-c", "while true; do echo hello; sleep 100;done" ]
      resources:
        limits:
          nvidia.com/gpu: 1 # requesting 1 GPUs
  • 部署到k8s上:
#在k8smaster节点执行
kubectl apply -f gpu.yaml 
  • 参看pod状态
[root@aly-001 house]# kubectl get pods
NAME                                   READY   STATUS    RESTARTS   AGE
tf-pod                                 1/1     Running   0          13m
  • 进入pod内部
kubectl exec tf-pod -it -- bash
  • 执行nvida-smi

  • 运行tf程序
import tensorflow as tf
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
  • 执行结果

  • 测试总结

    pod通过resource使用gpu资源K8S调度器可以根据pod的选择调度到有对应资源的节点上,同时在容器中能够正常的挂载gpu设备。

相关问题

问题一 : kubelet describe nodes aly-gpu-node-001 没有发现有GPU资源

[root@aly-hn1--001 house]# kubelet logs -f nvidia-device-plugin-daemonset-9fzwz 

2022/04/24 10:00:06 Loading NVML
2022/04/24 10:00:06 Failed to initialize NVML: could not load NVML library.
2022/04/24 10:00:06 If this is a GPU node, did you set the docker default runtime to `nvidia`?

2022/04/24 10:00:06 You can check the prerequisites at: https://github.com/NVIDIA/k8s-device-plugin#prerequisites
2022/04/24 10:00:06 You can learn how to set the runtime at: https://github.com/NVIDIA/k8s-device-plugin#quick-start

k8s-device-plugin Failed to initialize NVML: could not load NVML library #47

github.com/NVIDIA/k8s-…

重新设置运行时,让docker启动采用nvida运行时

#正常运行的nvidia-device-plugin的日志为:

[root@aly-master-house]# kubelet logs -f nvidia-device-plugin-daemonset-fq9tk 
2022/04/24 10:03:19 Loading NVML
2022/04/24 10:03:19 Fetching devices.
2022/04/24 10:03:19 Starting FS watcher.
2022/04/24 10:03:19 Starting OS watcher.
2022/04/24 10:03:19 Starting GRPC server
2022/04/24 10:03:19 Starting to serve on /var/lib/kubelet/device-plugins/nvidia.sock
2022/04/24 10:03:19 Registered device plugin with Kubelet

最终通过kubelet 查看节点发现了nvidia.com/gpu 为1卡

问题2 执行nvidia-smi 报错

NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.

解决方式:删除重新安装驱动

其它实践

  • GPU虚拟化

通常K8S调度GPU最小调度单位是1卡,这样有些对GPU利用率不高而又独占GPU任务,gpu利用率不高, K8S管理GPU多了之后,为了加强GPU的使用率,可以通过GPU虚拟化的能力,能够把一卡拆成多卡进行调度,K8S 请求resouce可以零点几卡进行调度。

  • 深度学习kubeflow等框架的部署

通常企业使用深度学习建模会使用tensorflow、pytorch、cafe、还会有深度学习多机多卡训练的需求,采用horovod之类的进行深度学习训练,自己去实现非常困难,好在开源社区有了一些方案,可以通过部署kubeflow借助其提供的能力去进行深度学习任务提交,kubeflow采用k8s operator 、crd等方案为tensorflow、pytorch、tensorflow分布式进行了支持,可以部署kubeflow然后进行深度学习建模。

  • 训练推理加速

通常一线互联网QPS比较高,模型加载、GPU推理等都有需求,这块接触不多,不做过多的叙述。

参考文档

mp.weixin.qq.com/s/NU8Cj6DL8… www.kubernetes.org.cn/7486.html 官方指南:kubernetes.io/docs/tasks/… github.com/NVIDIA/k8s-… NVIDIA device plugin问题解决方案聚集地:github.com/NVIDIA/k8s-… 阿里云GPU实例指南 StartInstance - API参考| 阿里云 华为云服务生命周期管理 docs.nvidia.com/datacenter/… Repository configuration www.tensorflow.org/guide/gpu zhuanlan.zhihu.com/p/159139809 gitlab.com/nvidia/cont…

我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿

猜你喜欢

转载自juejin.im/post/7116037775291318280