本次Docker学习缘于Datawhale的NLP实践-文本分类活动。
 那就顺便介绍一下这个比赛. 这个比赛是关于预训练模型的挑战赛, 任务为多模态任务, 即使用一个bert完成多个任务,不过每个任务都属于分类任务。本次比赛要求使用docker打包镜像进行提交,我之前只听说过docker而并没有使用过,所以为了提交这个比赛花了不少功夫。一开始并没有想着专门来学docker,所以在提交时各种碰壁,后来还是打算学习一下docker,所以在b站学习了up主遇见狂神说ocker教学视频,以下为我的docker复盘。

在win10上使用Docker

 因为我使用的win10系统,所以对于使用docker,首先使用了docker for Windows。一开始了解到docker是在Linux上使用的,所以知道docker有Windows版本之后还是觉得很担心,因为觉得只是大家需要在Windows上使用所以才有Windows版本而其使用起来可能令人堪忧。
 安装过程就不多介绍了,在后面使用中接触到了Dockerfile,而自己使用的是其他人已经编写好的Dockerfile,所以提交镜像时进行一些修改就总是报错。比如说我想要将Dockerfile所在目录的上级文件夹中的文件加入镜像中,于是我在Dockerfile中加入ADD ../*(在这个时候我还没有搞清楚ADD的用法/wul,因为我参考的Dockerfile中出现的ADD用法为如下图:

我以为. /是连在一起的,即./表示将当前目录添加进镜像,所以我写了如上的呆呆的命令。然后在build的时候总是报错,提示没有这个文件,就让我很是恼火。
 修改这个Dockerfile是在尝试提交比赛的baseline的时候,因为当时理解的是将py脚本完成之后将环境和应用一起打包成一个镜像,然后编写一个sh文件,让容器在启动的时候就去执行脚本执行py脚本,然后看到baseline中的run.sh文件是空的,于是想是不是要我们自己根据自己的环境去编写run.sh,所以就根据自己的理解去编写了run.sh文件,但是Dockerfile文件在py脚本文件的目录的某一个下层文件夹中。

文件结构
baseline
  |-train.py
  |-submission
     |-Dockerfile
     |-run.sh

我想要将这些py脚本一起打包进镜像的话需要返回上级。所以在run.sh和Dockerfile中编写了错误的命令哈哈哈哈。后来不断思考,终于理解了baseline的做法。
 首先说一下我理解的测评环境需要我们做的:评测程序需要我们编写相应的py脚本,然后编写一个run.sh文件以便在容器启动时可以去使用python进行训练以及输出最终需要的结果,接着评测程序拉取我们生成的result.zip的文件去进行最终结果的评测。但是baseline则忽略了前面的训练以及输出的过程。baseline选择直接在本机上进行最终结果的输出以及打包,然后打包成镜像之后再上传到阿里云仓库,接着提交我们的仓库让测评程序去进行测评。此时由于我们已经生成的结果文件result.zip而且run.sh文件为空,那么容器启动时我们执行这个run.sh也什么都没有做(在这里说明一下,run.sh文件不是一定要执行的,这取决于我们Dockerfile的编写),然后测评程序按顺序去获取我们的result.zip文件,然后进行测评即可。所以在这里,我觉得我现在学习docker的目的可以简单的了解docker之后,构建一个自己的镜像,不过这次不是在本地完成了训练之后才提交镜像,而是利用天池提供的4小时训练时间,让我们的程序在它那里训练,然后生成result.zip文件,然后进行测评,这可能就是我现在学习docker的短期期望了。
 所以我选择了去b站学习docker。

在Linux上使用docker

docker的安装

 在这里我使用自己的阿里云的服务器,使用xshell进行远程连接。
安装可以采用官方文档上提供的方法进行安装,具体命令我也不记得了,要用的时候再查吧。
大致的步骤是:
– 删除本机上已有的docker
– yum安装工具
– 添加docker镜像地址
– 下载docker

docker的使用

镜像(image)

 镜像是docker中一个很重要的观念,就和我们装虚拟机一样,会有一个镜像文件。我们将应用和环境打包成一个镜像,然后镜像可以被下载,然后我们可以运行一个镜像(这里镜像可以被认作一个小型的Linux系统),那么运行的这个镜像就会实例化成一个容器。
 镜像好比一个箱子,我们在一个镜像里面添加一些应用,然后将其打包。在需要的时候可以直接使用这个箱子去构建一个环境,而不需要我们自己去重新安装环境,就可以节省很多时间。

查看镜像

docker images # 查看所有镜像
docker images -q # 查看所有镜像的id

容器(container)

 容器可以看作一个镜像的实例化,当我们运行一个镜像的时候,一个容器就被创建并被运行,我们就可以将这个容器看作一个小型的Linux,我们可以进入该容器(就和虚拟机一样感觉)。这个容器实际上就是我们这个镜像的一个实例。(感觉说的很迷糊,淦)

交互式启动容器

 运行一个镜像,以交互方式启动一个容器

docker run -it --name container_name your_image

退出并当前容器

exit

退出但不停止当前容器

ctrl+p+q

查看容器

docker ps # 查看当前正在运行的容器
docker ps -a # 查看所有容器

删除容器

docker rm container_name/container_id # 使用容器名字或者容器id来删除容器
docker rm $(docker ps -aq) # 删除所有容器

查看进程信息

docker top contained_id # 查看容器内进程信息

查看镜像元数据

docker inspect container_id

进入当前正在运行的容器

docker exec -it 容器id # 进入该容器并开启一个新的终端

docker attach 容器id   # 进入容器但是不开启一个新的终端

从容器内拷贝文件到主机上

docker cp 容器id:容器内文件path 主机目的path

容器数据卷

 容器数据卷可以提供数据挂载的功能,其功能在于可以实现数据的双向绑定,比如容器内的数据和宿主机某个文件夹一起同步,目的:
– 可以直接在宿主机进行文件的修改而不用专门进入容器
– 实现数据的持久化存储,保证在容器被删除之后数据不会因为容器的删除而彻底删除。比如我们容器中含有mysql的应用,mysql中存储了很多数据,但是因为容器被删除我们数据就无了

使用-v参数

docker run -v 主机内目录:容器内目录

匿名挂载和具名挂载

docker run -v 容器内目录 # 匿名挂载
docker run -v my_name:容器内目录 # 具名挂载,名字为my_name

Dockerfile

Dockerfile主要在我们构建镜像的时候使用,构建镜像我们可以直接使用命令去构建,和git相同

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

但是也有另一种方法,即使用Dockerfile编写脚本

Dockerfile关键字

FROM       # 基础镜像, 一切从这里构建, eg: centos
MAINTAINER # 这个镜像谁负责维护, 姓名+邮箱
RUN        # 镜像构建的时候需要运行的命令
ADD        # tomcat镜像, 添加一个Tomcat的压缩包
WORKDIR    # 镜像的工作目录,即那个镜像的Linux的工作目录
VOLUME     # 设置卷,挂载主机目录
EXPOSE     # 指定对外的端口
CMD        # 指定这个容器启动的时候要运行的命令, 只有最后一个会生效,可被代替
ENTRYPOINT # 指定这个容器启动的时候要运行的命令, 可以追加命令
ONBUILD    # 当镜像被继承时会自动执行的命令
COPY       # 类似ADD,即将我们的文件拷贝到镜像中
ENV        # 构建的时候设置环境变量

在有了Dockerfile之后我们就可以利用Dockerfile构建容器了

docker build -t my_image:edition context_path
# eg docker build -t my_image:1.0 .
# 解释:
# -t 代表target,后面跟上我们构建的镜像名字如my_image
# 后面的edition表示版本,没有版本的话默认是latest
# 最后的那个点,我之前一直不理解,以为就是一个.,后来上网查阅资料才了解到
# 这个.是context_path参数,这个参数是一个路径,这个路径就是context环境,
# 感觉功能上就是作为根目录,在Dockerfile中ADD或者COPY只能是根目录下的文件
# 所以想要ADD Dockerfile文件所在的上层目录的文件,可以进入上层目录,将上层目录(此时
# context_path就是.嘛,然后加入-f参数,提供Dockerfile的路径,即
docker build -f ./dir/ -t my_image:edition .
# 这样docker就可以根据dir下的Dockerfile进行镜像的构建

大概就先写这么多自己看看就行,不丢人现眼了~~~

分类: docker

0 条评论

发表评论