之前没接触过docker,应中国电信的合作之邀,准备把我们实验室的代码工程化,并且做成docker镜像放到中国电信云平台的服务器上,供他们测试使用。
之前对docker的理解存在问题,所以过程中走了很多弯路,特意在此记录下来,也算是给后来的朋友们一点点参考吧,能有份中文文档比啃英文的生肉要快的多。
我们的工程是基于深度学习的图像处理工程,因此自然而然地需要用到CUDA。
云主机环境:Ubuntu16.04LTS,已经预装好N-Vidia 384和CUDA8.0.61
docker环境:Ubuntu14.04LTS,裸机。【这个是为了配合我们实验室服务器版本】
docker部署的原则就是和工程强相关的库,在docker内部署;宿主机必备的库,即和工程非强相关的库,直接通过文件映射的方式映射到docker内。(直接映射就可以,用不着nvidia-docker)
通过如下的形式可以映射:
docker run -it --device /dev/nvidia0:/dev/nvidia0 --device /dev/nvidiactl:/dev/nvidiactl --device /dev/nvidia-uvm:/dev/nvidia-uvm --device /dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools -v /usr/lib/nvidia/:/usr/local/nvidia/lib64 -v /usr/local/cuda/:/usr/local/cuda -v /usr/lib/cuda/:/usr/lib/cuda hub.tech.21cn.com/aicloud/ai-tumour14-test:v0.1.3 bash
注:倒数第二项是镜像名称和标签。
映射之后可以通过nvidia-smi和nvcc -V两个命令测试是否成功,如果nvcc -V执行失败,添加export PATH=$PATH:/usr/local/cuda/bin(这样做每次开机都得添加,或者直接添加到.bashrc中,一劳永逸,方法自行google)
这之后就是要对裸机安装一些必备的库了,在安装过程中,尽量避免使用apt-get进行安装,apt-get安装包的版本控制做的很差,稍不小心就会出现依赖崩溃的现象。(当然,用apt-get安装个wget还是可以的)
此外,在使用apt-get时,可以考虑通过修改/etc/apt/sources.list文档把源换为国内的清华镜像源,注意备份以及你系统的版本要和清华源地址匹配。ubuntu是有一个版本号的(trusty tahr等),它清华源的目录上也有一层是和版本号相关,注意一一对应关系。
安装一般的库通常情况下使用wget去下载官方安装包是最稳妥的办法,每个包下载完再google安装教程。
安装python依赖库就需要pip了。
首先需要安装python3.6,如果默认Python是2.x的话,可以考虑把默认python从2.x改为3.6,这个修改usr/bin里的链接就可以了,网上很容易查到,故不赘述,细节以网上详细博客为准。
这之后需要安装pip,这个最好以手动形式安装:
我本机是pip-10.0.1,因此在docker里也要安装10.0.1,根据【http://www.mamicode.com/info-detail-2247945.html】文章中所叙述的方法进行安装,把对应的9都改成10即可。文中所说软链接那步可能需要灵活处理,可以考虑用whereis pip之类的命令先寻找一下。此外,pip不一定是pip,有可能带着版本号或者Python版本号,注意灵活处理。
剩下的包就都是我所需要的依赖了,可以首先先把你的python环境生成一个requirements.txt文件,然后根据这个文件在docker中一键安装。
需要注意requirements文件内容一定要完全一样,如果发现pip找不到对应的包,先去排查是不是文件中包的名写错了。
此外,cupy安装可能会出现各种各样的bug,可以根据它不同的报错信息寻找到一些蛛丝马迹,比较统一的一种情况是binutils是低于2.26的版本,和你linux的内核不匹配,这可以通过手动安装binutils2.26来解决,不要忘记把默认binutils修改为2.26版本,方法和修改默认python版本相同,此外要注意添加/usr/lib/binutils-2.26/bin环境变量。还有一种可能导致cupy的安装bug是因为没安装nccl库,报出nccl.hpp:5:18: fatal error: nccl.h: No such file or directory错误,根据【http://www.th7.cn/system/lin/201708/223795.shtml】问题11给出的解决方案手动下载安装nccl解决。
此外,如果你需要Lasagne0.2.dev1,pip10.0.1可能无法直接找到源,需要在pip中给出其源地址,通过 pip install -U https://github.com/Lasagne/Lasagne/archive/master.zip
安装。
pygpu只能手动安装,在安装它之前需要先通过pip安装cmake,之后根据http://www.52nlp.cn/tag/theano%E5%AE%89%E8%A3%85文章中4里头中间那段安装pygpu。
此外,还有些库如果现有的和requirements.txt中的有些微的不匹配(比如仅版本号第三位有区别),也可以尝试通过修改requirements.txt忽略版本区别(注意备份,这些都是潜在的隐患)。
在都安装完,配置cupy的时候,还是有可能报错,比如libcudart.so.8.0: cannot open shared object file: No such file or directory
这个时候缺啥补啥,将对应的链接手动放到它应该出现的地方,比如cp /usr/local/cuda/lib64/libcufft.so.8.0 /usr/local/lib/libcufft.so.8.0,然后再执行ldconfig,确保动态链接库ok。
测试程序,如果能够正常在docker中执行,说明大功告成。
docker没有垃圾回收机制,因此需要手动清除中间生成的docker,可以通过:
docker ps -a|grep Exited|awk '{print $1}'
查看exit状态的容器,并通过
docker rm `docker ps -a|grep Exited|awk '{print $1}'`
删除之。
大功告成。