天池大数据Docker镜像提交攻略
以下是自己接触Docker两天以来按照自己的理解所写,许多都是个人见解,如果有问题欢迎指正。
1. Docker是什么
Docker和虚拟机很类似,可以看作是一种微型系统,其作用主要是为应用的执行提供一个虚拟化的环境。
通常,当一份代码拷贝到另一台机器上时,经常会由于缺少一些环境依赖导致运行失败,有时候即使一个个的花时间解除了这些依赖,程序的运行结果也可能由于不同的机器系统、不同的环境依赖版本而导致结果的不同,这为程序的迁移造成了很大的麻烦。
Docker就很好的解决了这一难题,它可以将代码或程序,以及它所依赖的环境共同打包成一个镜像。当移植到其它机器时,只需通过这个镜像示例化出一个容器(对象),然后再执行里面的代码或程序,这样便可以方便的实现代码或程序以及它所依赖的环境的共同迁移,就不会有那么多的依赖问题了。
2. 镜像和容器是什么
镜像可以理解为一份小的系统备份,就像你曾经使用Ghost还原装系统一样,你可以从这个镜像还原出一个虚拟的系统环境。而容器其实就是还原出的一个实例,也就是说,这份镜像不止可以在你的机器上还原出一个虚拟系统,在其它机器上都可以还原得到一份,这些都是这个镜像的实例。(类和对象的概念相似)。
3. Docker的安装
linux的安装这里不详述,对于windows的安装,win10以下的老系统似乎只能使用Docker Toolbox,这里也不详述。
主要强调对于win10家庭版的用户,在安装时可能会出现安装失败的问题,这主要是由于系统的Hyper-V功能没开启,以及安装程序对于家庭版用户不会让你安装。
解决方案也很简单,首先开启Hyper-V功能,然后通过更改注册表把系统的标识改为专业版骗过去(不要怕会有什么影响,重启后这个标识又会变回家庭版,但只要骗过了安装就行,后面的使用一切正常)。
安装参考以下的博客:
Windows10家庭版安装Docker Desktop(非Docker Toolbox) - 简书
如果安装过程中出现 Containers Windows Feature is not available,说明还需要开启Container功能:
解决:Containers Windows Feature is not available_windows containers not enabled-CSDN博客
4. 如何通过Docker提交代码
4.1 创建阿里云代码仓库
为了方便后面提交到云仓库,需要先到阿里云开启容器镜像服务,创建一个仓库,地域可以选择为上海(或其他,但本次比赛好像最好是在长海),然后注意镜像仓库的代码源选择为本地仓库,这样灵活性大。
阿里云容器镜像服务链接:容器镜像服务_镜像构建_镜像授权_镜像托管-阿里云
同时一定要记得自己在创建仓库时设置的仓库密码,后期push代码是需要这个密码的。注册好后会得到如下的一个仓库的公网地址:
这个地址也需要记住。
4.2 构建镜像前的准备
首先我们为自己的docker项目创建一个专门的文件夹,然后在文件夹下新建一个名为"Dockerfile"的文件(注意是文件,不是文件夹,而且不要有后缀名,文件名不要打错),该文件便是我们建立镜像的初始配置文件。
以记事本打开,基本内容可以按照如下的写法:
# Base Images
## 从天池基础镜像构建
FROM registry.cn-shanghai.aliyuncs.com/tcc-public/python:3
## 把当前文件夹里的文件构建到镜像的根目录下
ADD . /
## 指定默认工作目录为根目录(需要把run.sh和生成的结果文件都放在该文件夹下,提交后才能运行)
WORKDIR /
## 镜像启动后统一执行 sh run.sh
CMD ["sh", "run.sh"]
FROM ... :这里是指你的初始镜像内容,可以理解为从某个已经构建好的镜像开始搭建自己的镜像,这里所选取的是阿里云的一个带了python3的镜像,相当于一个已经安装了python3的linux环境。
ADD . / :注意 . 和 / 间是有个空格的,这个表示把当前目录下的所有文件挂载到镜像的根目录下,这也是这两个符号的含义。这也意味着你需要将你的得到预测结果的所有代码、数据、脚本都放在该目录下,这样才能保证这些文件会被挂载到镜像中。
WORKDIR / :指定镜像的默认工作目录为根目录。
CMD ["sh", "run.sh"] :这个表示在镜像启动后会执行的指令,这里的意思是执行 “sh run.sh”即当镜像启动后会自动执行run.sh脚本的内容。这也是为什么当你在阿里云提交代码后,后台可以自动得到你的运行结果的原因,因为执行的就是这个指令。
run.sh文件同样放在该目录下,里面所写的就是得到预测结果的shell指令顺序,具体内容略。
==注意通常由于复赛的测试集是不能下载的,它是当你提交后被自动挂载在镜像的根目录下,所以你在写预测脚本时只能假装存在一个这样的测试集目录,但如果线下在镜像里运行脚本会报错说找不到文件。而在页面提交后后台在执行的时候会挂载上这个目录,所以提交是可以正常运行的。应对思路是手动创造一个这样的环境(见末尾的小技巧)。 ==
4.3 构建镜像
docker build -t xxx .
以上命令为创建一个名称为xxx的镜像,这个名称xxx需要设置为阿里云仓库的公网地址(至于为什么我也不太确定,不然一旦不是这个的话后面就不能push到云仓库里,可能是一种格式规范吧)。
格外注意末尾有一个 . ,这个代表以当前目录创建,意味着其为在当前目录下寻找Dockerfile文件,然后按照其内容初始化镜像。
创建好镜像后可以通过指令
docker images
查看当前拥有的所有镜像,如图所有镜像的名称、标签、ID、创建时间和大小都有显示。
4.4 配置镜像的环境
由于镜像是由一个只带了python3基本环境的linux构建的,所以我们还需要安装我们所依赖的第三方库,这时候我们可以通过镜像实例化一个容器出来,然后在容器中进行安装,再将容器中的修改提交到镜像中。
docker run -it 被选取的镜像名称 /bin/bash
该指令相当于以该镜像实例化一个容器,然后运行该容器;-it 表明以交互式的方式打开,同时分配到一个伪输入终端,其实就是让你能够与它实现交互;
然后就可以通过命令行直接操作这个linux的虚拟系统了,通过pip install安装所有需要的依赖环境,全部安装成功后输入exit退回windows下。
这个时候我们还只是在容器中装好了环境,但镜像还是没有变的,所以我们需要提交一下。
docker ps -a
通过以上命令查看所有最近的容器情况,第一条就是你刚刚做出改变的那个容器,我们需要把这些东西更新到镜像上。
这里面的信息包括容器ID,所从属镜像等,我们只需要这两个就OK。
docker commit 容器ID 镜像名
对应此处的提交代码就是
docker commit e3fafe095c95 registry.cn-shanghai.aliyuncs.com/data-science_by_dante/2020-dcic-zhhyjs:1.0
通过以上指令即可将容器的变化提交到所选择的镜像中去,这样一来便完成了镜像的环境搭建。
4.5 提交镜像
首先你需要登录你的阿里云仓库,然后再push本地镜像过去。
打开阿里云容器镜像服务的控制台:
然后在你刚刚创建的仓库那点击管理,得到如下页面:
其中:
docker login --username=mailto:xxxx@xxx.com registry-xxx
就是在本地docker登录到阿里云仓库的指令,直接在本地的命令行运行该指令就好,然后会要你输入仓库的密码,这里注意是仓库的密码,也就是你之前创建阿里云仓库时所设置的密码,不是阿里云账号的密码。
显示登录成功后,通过
docker push 镜像名
即可将本地的镜像push到阿里云仓库,如果之前设置了标签,在名称后面相应的加上类似“:1.0”就行,如果没有就不加。
等待push成功。
4.6 提交结果
这一步在提交页面配置好自己的阿里云公网地址,以及阿里云账号和仓库密码就OK,然后点击提交,等待结果。
5. 其它小技巧
5.1 由于测试集是提交后后台帮你挂载的,如何线下测试自己的代码准确性?
这里可以通过在线下的镜像中模拟一个线上挂载的数据的文件夹和路径,里面放上训练集的数据就好,然后线下在镜像中执行 run.sh,观察是否顺利。
以这次的题目为例,我在构建镜像的文件夹中同样加入了tcdata文件夹,里面也创建了一个hy_round2_testA_20200225的文件夹,然后文件夹里放入了少量的几个训练集的数据,这样便能测试代码的准确性,而不至于线上提交出错浪费机会。
测试完没问题后,最好删除镜像里整个tcdata文件夹,因为我不知道保留在镜像中会不会与后面的官方挂载出现冲突,删除的方式和配置镜像的环境类似,进入容器控制台rm -rf /tcdata然后exit出来,commit就好。
5.2 如果修改了模型或者代码,如何更新到镜像中?
这里我暂时没有找到直接把代码或文件复制到镜像里的方法,目前我的做法是当模型或代码发生改变后,重新build一个镜像。
但此时要注意,build的时候在Dockerfile文件里,FROM部分修改为之前已经配置好环境的镜像名。否则如果从阿里云的python镜像初始化的话,那么又得重新搭建一次镜像的环境依赖,重新pip install。
而且构建时,镜像名可以直接沿用之前镜像的名字,这样会覆盖掉原来的,同时又是从原来的镜像初始化,所以那些装的包都会有,不用重新安装。
5.3 应该差不多了,祝大家摸奖顺利。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。