如何在k8s叢集中安裝nvidia、cuda並使用GPU進行訓練
如何在k8s叢集中安裝nvidia、cuda使用GPU進行訓練
在寫具體步驟前,發表一下自己的感想體會,因為在這過程中,踩過很多坑,對於像我們這種小白,踩坑真的是無處不在,真的很感謝網上一些大神細心地幫助,也感謝其它大神分享的部落格。所以自己實現之後也想把這過程中遇到的坑和解決的方法總結總結,希望對大家有用。
本文主要是針對已經部署好了k8s叢集的,基於centos系統,截止k8s1.8版本,對GPU的使用支援還是停留在實驗階段,只支援nvidia的GPU,在k8s上使用GPU,先要裝好幾樣東西。
安裝流程:
1、關閉UEFI。這個很重要,因為如果不關閉可能會導致安裝nvidia驅動的時候無法載入kernel模組,我就在這浪費了好多時間。具體做法是開機按F2進入BIOS設定,通常在BOOT或Secure選項卡上,把安全啟動[Secure BOOT],改為[Disable],如果不是的話自己去搜搜相應的。
2、確認自己主機有nvidia的顯示卡。
輸入命令lspci | grep-i nvidia 檢視nvidia顯示卡情況。
3、檢查系統版本,確保系統支援(需要Linux-64bit系統)
#uname -m && cat /etc/*release
4、根據nvidia顯示卡的資訊和系統下載相應的安裝包。
NVIDIA-Linux-x86_64-381.22.run # 最新顯示卡驅動
cuda_9.0.61_375.26_linux.run # 最新CUDA安裝包
(1)登入NVIDIA官網http://www.geforce.cn/drivers設定驅動檢索條件(注意儘量設定語言英文):
(2)官網下載cuda-rpm包https://developer.nvidia.com/cuda-downloads,一定要對應自己的版本。
(3)下載cudnn需要註冊https://developer.nvidia.com/rdp/cudnn-download,注意有些瀏覽器是註冊不了的,我就踩了這個坑。
5、安裝gcc gcc-c++
#yum install gcc gcc-c++
6、檢視核心是否一致。
#uname -r
#rpm -q kernel-devel
#rpm -q kernel-headers
如果一致的話這步可以跳過,輸入rpm -q kernel-devel時有可能是not found,說明沒有安裝,有顯示說明已安裝。
安裝kernel-devel和kernel-headers。
#sudo yum install kernel-devel-$(uname -r) kernel-headers-$(uname -r)
或者
#yum install kernel-headers
如果安裝完發現不一致的話需要 yum -y update
7、安裝cuda(最好是先安裝好這個再去安裝驅動,不然會nvidia的安裝不會很順利,我就踩了這個坑。)
#sudo rpm -icuda-repo-rhel7-8-0-local-ga2-8.0.61-1.x86_64.rpm
#sudo yum clean all
#sudo yum install cuda
可能會報錯,
(1)原因是缺少2個包,裝第一個:
#sudo vim /etc/yum.repos.d/linuxtech.testing.repo
輸入:
[linuxtech-testing]
name=LinuxTECH Testing
baseurl=http://pkgrepo.linuxtech.net/el6/testing/
enabled=0
gpgcheck=1
gpgkey=http://pkgrepo.linuxtech.net/el6/release/RPM-GPG-KEY-LinuxTECH.NET
退出。
#sudo yum --enablerepo=linuxtech-testing install libvdpau
(2)第二個,尤其是dkms,安裝驅動的時候會用到這個模組。
#yum -y install epel-release
#yum -y install --enablerepo=epel dkms
(3)好了,再次執行安裝cuda的步驟。
(4)驗證安裝結果。
新增環境變數,在 ~/.bashrc的最後面新增下面兩行。
#vi
~/.bashrc
export PATH=/usr/
local/cuda-
8.0/bin:$PATH
export LD_LIBRARY_PATH=/usr/
local/cuda-
8.0/lib64:/usr/
local/cuda-
8.0/extras/CUPTI/lib64:$LD_LIBRARY_PATH
使生效
# source ~/.bashrc
驗證安裝結果
#nvcc -V
8、安裝顯示卡驅動
安裝NVIDIA驅動是很重要的步驟,該步成功了,後面也就基本上一馬平川了。
(1)、關閉X server,不然在安裝過程中會出現以下錯誤。
#sudo init 3(建議用這個)
或者
#systemctl stop gdm.service
(2)禁用nouveau(因為它是一般linxu系統自帶的顯示卡驅動,會和nvidia衝突,所以必須要關掉)
使用su命令切換到root使用者下: suroot
#vi /lib/modprobe.d/dist-blacklist.conf
將nvidiafb註釋掉。
#blacklist nvidiafb
然後新增以下語句:
blacklist nouveau
options nouveau modeset=0
(3)重建initramfs image步驟
備份 initramfs 檔案
# sudo mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak
重建 initramfs 檔案
# sudo dracut -v /boot/initramfs-$(uname -r).img $(uname -r)
(4)修改執行級別為文字模式
systemctl set-default multi-user.target
(5)關機重啟#reboot
(6)檢視nouveau是否已經禁用,沒有輸出就表示禁用了。
# lsmod | grep nouveau
(7)開始安裝nvidia驅動(在驅動的目錄下)
#chmod +x NVIDIA-Linux-x86_64-384.98.run
#sh NVIDIA-Linux-x86_64-384.98.run
開始安裝
選擇Accept
32bit相容包選擇, 這裡要注意選擇NO,不然後面就會出錯。
X-configurtion的選擇頁面YES
後面的都選擇預設即可。
安裝完之後輸入nvidia-smi,能顯示說明安裝正確。
9、安裝cuDNN
$ tar
-xvzfcudnn
-8.0-linux-x64-v6.0.tgz
$ cp
-Pcuda/include/cudnn
.h /usr/
local/cuda
-9.0/include
$ cp
-Pcuda/lib64/libcudnn
*/usr/
local/cuda
-9.0/lib64
$ chmod a
+r /usr/
local/cuda
-9.0/include/cudnn
.h /usr/
local/cuda
-9.0/lib64/libcudnn
*
10、安裝nvidia-docker and nvidia-docker-plugin
#wget -P /tmphttps://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker-1.0.1-1.x86_64.rpm
#sudo rpm -i /tmp/nvidia-docker*.rpm && rm/tmp/nvidia-docker*.rpm
啟動nvidia-docker
#sudo systemctl start nvidia-docker
為了確認 nvidia-docker 是否安裝成功,執行
#nvidia-docker run --rm nvidia/cuda nvidia-smi
如果出現下面這些,說明正確(這過程可能有些久,因為要pull映象)
另外通過使用一些命令也可以查到相應的資訊。比如:
#nvidia-docker volume ls,檢視卷
#systemctl status nvidia-docker,檢視nvidia-docker執行狀態,途中綠色的點說明在執行。記得一定要啟動nvidia-docker。
#ll /var/lib/nvidia-docker/volumes/nvidia_driver/384.98/,檢視安裝了nvidia-docker後對映的nvidia驅動和cuda庫(注意後面的384.98資料夾因版本可能不一,要記住這個路徑,因為用yaml檔案建立pod的時候需要掛載這個資料夾)
11、至此,nvidia的驅動和cuda以及cudnn和nvidia-docker已經安裝完成。可以用nvidia-docker run來跑個容器來試試看看。
#nvidia-docker run -itd -p 8888:8888 --name tentensorflow/tensorflow:0.11.0rc0-gpu
等容器建立完後在瀏覽器可以用8888埠訪問,可以訪問jupyter,然後輸入如下資訊,如果出現GPU,也進一步證明nvidia等是安裝正確的。
from tensorflow.python.client import device_lib
def get_available_devices():
local_device_protos = device_lib.list_local_devices()
return [x.namefor x in local_device_protos]
print(get_available_devices())
或者使用docker進入容器,輸入nvidia-smi能輸出一下資訊,說明nvidia-docker等是安裝成功。
# docker exec -it 869e1da6f5ef(容器ID) /bin/sh
#nvidia-smi
12、在kube-apiserver, kube-controller-manager,kube-scheduler和kubelet上開啟--feature-gates="Accelerators=true"。
這個很重要,我之前就是因為沒有開啟這些,所以一直在困惑中度過,幸好有濤哥大神幫我一步步排查,最後才發現是沒有加入啟動引數。記得,kubelet啟動引數一定要在所有的機子上加入,包括master和node,其它幾個好像只有master上有。
(1)、在master上和node上的kubelet加入啟動引數
#vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
新增:--feature-gates=Accelerators=true
執行如下命令使新增引數生效
# systemctl stop kubelet
# systemctl daemon-reload
# systemctl start kubelet
檢查新增引數是否已經生效
# ps -ef | grep kubelet
(2)在master的kube-apiserver,kube-controller-manager, kube-scheduler
上參入啟動引數。
我的是在/etc/kubernetes/manifests/目錄下,
#cd /etc/kubernetes/manifests/
# vi kube-apiserver.yaml
新增- --feature-gates=Accelerators=true
#vi kube-controller-manager.yaml
#vi kube-scheduler.yaml
(3)重新啟動docker和kubelet
#service docker restart
#systemctl restart kubelet
(4)檢查叢集是否已經重啟和連上。
# kubectl get nodes
如果是NotReady說明(1)和(2)配置那裡出錯了,重新回去看看。
13、在master上檢視node資訊,看k8s是否能識別node的gpu.
#kubectl get node minion-1 -o yaml
或者
#kubectl describe node minion-1
如果未出現GPU或者GPU後面的數字是0,那就說明安裝或者配置沒有成功,回過頭看看哪一步漏了。
至此,你的k8s叢集能夠使用GPU了。
14、用yaml建立pod來測試看看。
這裡要說一說,建立yaml檔案的時候kind型別可以直接用pod,也可使用Deployment,但使用ReplicationController的時候雖然也能建立容器,但卻無法使用GPU,到現在我也不知道為什麼。
另外,為了防止容器修改了宿主機的nvidia驅動,在掛載的時候要設定為只讀模式
#vi jupyter.yaml
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jupyter
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: jupyter
spec:
containers:
- name: jupyter
image: tensorflow/tensorflow:0.11.0rc0-gpu
ports:
- containerPort: 8080
- containerPort: 8888
resources:
limits:
alpha.kubernetes.io/nvidia-gpu: 1
volumeMounts:
- mountPath: /usr/local/nvidia
name: nvidia
readOnly: true
volumes:
- hostPath:
path: /var/lib/nvidia-docker/volumes/nvidia_driver/384.98
name: nvidia
---
apiVersion: v1
kind: Service
metadata:
name: jupyter-svc
spec:
type: NodePort
ports:
- port: 8888
nodePort: 31001
name: jupyter
- port: 8080
nodePort: 31002
name: ssh
selector:
k8s-app: jupyter
Deployment配置:
(1)alpha.kubernetes.io/nvidia-gpu
指定呼叫nvidia gpu的數量
(2)為了能讓GPU容器執行起來,需要將Nvidia驅動和CUDA庫檔案指定到容器中。這裡需要使用hostPath,您只需要將hostPath指定到/var/lib/nvidia-docker/volumes/nvidia_driver/
384.98即可,並不需要指定多個bin和lib目錄。
建立pod的
# kubectl create -f jupyter.yaml --validate=false
#kubectl get pod
在瀏覽器輸入31001埠訪問jupyter
輸入以下內容看是否能使用GPU
from tensorflow.python.client import device_lib
def get_available_devices():
local_device_protos = device_lib.list_local_devices()
return [x.name for x in local_device_protos]
print(get_available_devices())
或者開啟一個terminal
輸入nvidia-smi
14、到這裡,已經成功配置使用GPU了。
15、說一說在這過程中踩過的坑以及解決方法。
先奉上一些可能用到命令
(1)解除安裝NVIDIA驅動,前提是安裝包還在哈。
#shNVIDIA-Linux-x86_64-384.98.run --uninstall
(2)解除安裝nvidia-docker(這是centos解除安裝方式)
#docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
#sudo yum remove nvidia-docker
(3)檢視nvidia-docker狀態等
systemctl status nvidia-docker
systemctl start nvidia-docker
systemctl stop nvidia-docker
nvidia-docker volume ls
(4)重新命名映象
#docker tag IMAGEID(映象id) REPOSITORY:TAG(倉庫:標籤)
下面是可能出現的問題(我踩過的坑)
(1)ERROR:The Nouveau kernel driver is currently in use by your system. This driver isincompatible with the NVIDIA driver。說明是Nouveau沒有禁用,請看我上面寫的“第8步內容:禁用nouveau”
(2)ERROR: Youappear to be running an X server; please exit X before installing.是因為沒有關閉X server,輸入init 3。
(3)The driver installation is unable to locate the kernel source. Please make sure that the
kernel source packages areinstalled and set up correctly.
If you know that the kernel source packages are installed and set up correctly, you may pass the location of thekernelsource with the '--kernel-source-path' flag.
解決方法都是安裝下面這兩個,這也就為什麼最好先安裝cuda先。
#sudo yum install epel-release
#sudo yum install --enablerepo=epel dkms
(4)ERROR: Unable to load the 'nvidia-drm' kernel module.
解決方法:
關閉BIOS中的UEFI,也就是最前面說的第一步。
(5)裝完nvidia後輸入nvidia-smi,出現下面這個:
NVIDIA-SMI has failed because it couldn’t communicate withthe NVIDIA driver. Make sure that the latest NVIDIA driver is installed andrunning
解決辦法:
出現這個問題說明nvidia沒裝好,缺少東西,解決就是安裝nvidia驅動前確保UEFI關了,還有明確 dkms等是否安裝了,往文章上面看看哪些沒做的。要麼就是安裝的kernel-devel版本不一樣,需要yum -y update,記得重啟電腦。
(6)kubectl get node minion-1 -o yaml顯示
alpha.kubernetes.io/nvidia-gpu: "0"或者直接沒有顯示
說明驅動、nvidia-docker沒裝好,如果都裝好了,用nvidia-docker run能跑容器,說明是kube-apiserver, kube-controller-manager, kube-scheduler, kubelet這些啟動引數沒配好,尤其是gpu顯示是0的這種情況,非常有可能就是kubelet等啟動引數沒有配好,記得master和node上都要配,我就是在這費了好多時間。忘文章上面看看第11和12步是如何做的。
16、在這分享幾位大神的部落格連結,感謝大神們無私的分享和教導。
(1)、西電濤哥的部落格:如何在Kubernetes叢集中利用GPU進行AI訓練。
https://my.oschina.net/jxcdwangtao/blog/1574199
(2)、kubernetes官網使用指南
https://zhuanlan.zhihu.com/p/27376696
(3)、nvidia-docker以及掛載路徑的一些解析
http://blog.csdn.net/qq_35254726/article/details/60326433
(4)、cento7 安裝GPU版TensorFlow教程
http://blog.csdn.net/j790675692/article/details/78133551
(5)、在CentOS7上安裝NVIDIA CUDA 並在docker中使用CUDA
http://blog.csdn.net/itaacy/article/details/72628792?utm_source=itdadao&utm_medium=referral
(6)、阿里雲部署叢集GPU
https://yq.aliyun.com/articles/203865
(7)、centos7.3安裝nvidia驅動、cuda、cudnn