请注意以下的内容大多来自个人理解,许多地方不够严谨,仅限入门使用
项目部署使用docker来部署,主要原因要安装很多的库(这些库的版本有的老有的新),电脑里本来就装了许多的库,环境会被污染。使用docker的好处之一就是环境的隔离(此处的好处与anconda管理虚拟环境一致),每个环境之间互相不会污染冲突。
简单的介绍一下docker,在我的理解中docker的出现是为了更好的环境配置和环境移植。
环境配置就类似于anaconda中管理虚拟环境一样,每个环境可以安装你需要的不同库,而不会互相的影响。在这配置环境的过程中,可以通过写一种叫做Dockerfile的脚本文件来全自动化配置。环境里面需要哪些包可以在Dockerfile里面写出来,会自动配置,这样就省去了创建好环境后还需要自己把包一个一个下载编译安装的流程。
环境的移植简单的说就是当你使用Docker配置好环境后,你就可以在这个环境下运行代码了,但是如果别人也需要在别人的电脑里运行同一个代码的话,你可以将你配置的Docker环境打包给别人,别人在其他电脑上安装这个环境就可以马上复制一个一模一样的环境了,也就可以马上运行同一代码了。(环境的移植貌似在anaconda中没有对应的功能,个人觉得这个功能可以有!以后直接下载代码对应的环境,一键安装上立马就可以运行了)
不过在Docker的术语中,不叫环境,叫做镜像。Docker中有三个绕不开的话题,镜像、容器和仓库。接下来一一掰扯掰扯。镜像在我的理解中就是你创建的环境。在创建环境的过程,Docker的定制化程度更高,你可以定制代码运行的操作系统,比如ubuntu, centos等等,你需要什么操作系统,就在仓库中下载一个对应的操作系统镜像。(所以仓库就是存放一些公开镜像的地方)这个从仓库中下载的操作系统镜像一般很小,只包括一些必要的东西。下载了这个操作系统镜像之后,就可以启动这个操作系统镜像进入其中,在这个镜像中你就可以随意安装你想要的包或者库了。安装好想要的包或者库让后退出就结束了?暂时不行。这里就涉及到镜像和容器的关系了!网上的资料一般将镜像和容器的关系形容为类和对象的关系,这个形容我觉得很贴切。镜像就像是一个类,容器就像是一个对象。当你下载好镜像,启动镜像的时候,其实你就创建了一个基于这个镜像的容器,在这个容器中你可以安装包什么的,但是当你安装好了包退出容器后,然后再次启动这个镜像的时候,发现安装的包不见了。其实这是因为你重新启动镜像相当于重新创建了一个容器,这个容器和刚刚你安装好包的容器是不一样的(因为这是两个不不同的对象,也就是根据同一个类,生成了两个对象,你在一个对象里的操作不会影响另一个对象)。对同一个镜像启动多次就会产生多个容器,每个容器都互不影响,但都是基于这个镜像的。所以如果我启动镜像,进入了容器,安装了包退出之后岂不是没用了?Docker提供了命令可以将一个容器保存为一个新的镜像!这个保存的镜像也就包括你在容器中安装了的包了。简单总结一下,镜像就是一个类,是一个静态的概念,容器是镜像的一次启动,是一个可操作的对象,是一个动态的概念。根据镜像里包括的内容不同,比如ubuntu的镜像,centos的镜像,会有许多的镜像,存放这些镜像的地方就是仓库。
说完了镜像、容器和仓库,再聊一下Dokerfile的事。Dokerfile就是一个脚本文件,里面说明了你最开始下载的镜像叫什么名字,然后要在这个镜像里装哪些包,下载哪些文件等等。写好之后,Docker会自动执行这个脚本文件,这样就可以全自动构建一个匹配的容器或者镜像出来了。也就是理论上只需要一条执行Dockerfile文件的命令就可以构建一个需要的环境了。这里列举一下Dockerfile文件的一些命令。
FROM nvidia/cuda:10.0-devel-ubuntu18.04 RUN apt-get update && apt-get
install -y
build-essential
pkg-config
git
wget
curl
unzip
cmake
sudo
apt-utils RUN cd / && wget https://raw.githubusercontent.com/laxnpander/OpenREALM/dev/tools/install_opencv.sh
第一行就说明了镜像的名字,是nvidia/cuda下的10.0-devel-ubuntu18.04开发版本。Docker就会在仓库中寻找对应名字的镜像然后下载到本地。然后第二行到第十一行是运行一系列指令(ubuntu下的apt-get安装包指令),要在这个容器中安装一些基本的包(说明最开始下载下的镜像比较空)。最后一行是进行容器中的根目录,然后使用wget在这个网站下载文件。说道这里,也就大概明白Dockerfile构建的原理了,就是一个要执行的命令清单,Docker会根据这个清单一条命令一条命令的执行。
有了之间的铺垫,后面就将介绍Docker如何安装,如何创建镜像和容器,如何进入容器等细节了。
ubuntu安装docker有许多种方式,官方文档里有详细的解释。这里只介绍Docker engine的安装方式。文档见https://docs.docker.com/engine/install/ubuntu/。当然也可以安装Docker desktop有图形界面的。Docker engine和Docker desktop两个的区别就是前者使用命令行来操作,后者可以使用图形界面来操作。Docker desktop安装文档见https://docs.docker.com/desktop/install/ubuntu/
接下来介绍在ubuntu下安装docker engine(这里可以用好几种方式,只介绍其中一种)
卸载旧版本的Docker engine
sudo apt-get remove docker docker-engine docker.io containerd runc
设置下载源
更新下载源并允许apt通过https访问
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
添加Docker的官方GPG密钥:
sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL
https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o
/etc/apt/keyrings/docker.gpg sudo chmod a+r
/etc/apt/keyrings/docker.gpg
设置下载源
echo \ “deb [arch=” ( d p k g − − p r i n t − a r c h i t e c t u r e ) " s i g n e d − b y = / e t c / a p t / k e y r i n g s / d o c k e r . g p g ] h t t p s : / / d o w n l o a d . d o c k e r . c o m / l i n u x / u b u n t u " (dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ " (dpkg−−print−architecture)"signed−by=/etc/apt/keyrings/docker.gpg]https://download.docker.com/linux/ubuntu "(. /etc/os-release &&
echo “$VERSION_CODENAME”)" stable" | \ sudo tee
/etc/apt/sources.list.d/docker.list > /dev/null
安装Docker engine
更新一下下载源
sudo apt-get update
安装Docker engine
sudo apt-get install docker-ce docker-ce-cli containerd.io
docker-buildx-plugin docker-compose-plugin
验证一下是否安装成功
sudo docker run hello-world
注意,如果直接执行下面的命令不行,在命令之前加上sudo
查看本机的所有镜像
docker image ls
REPOSITORY 镜像的仓库源
TAG 镜像的标签(可以理解为版本号)
IMAGE ID 镜像的ID
CREATED 镜像的创建时间
SIZE 镜像的大小
下载镜像
docker pull 镜像名[:tag]
当下载的时候只使用镜像名的时候,默认的tag是latest(最新)。例如
docker pull hello-world
就会默认下载tag为latest的镜像
删除镜像
docker rmi 镜像名/镜像名:tag/镜像id
删除镜像可以使用多种方式,需要注意的是使用镜像id删除镜像的时候,不必要使用全部镜像id,一般使用镜像id的前面几个字母就可以定位到该镜像了。例如删除hello-world的镜像,只使用部分部分镜像id便可以
docker rmi 9c7a
接下来是与容器有关的操作
新建容器并启动
docker run 镜像id
再提示一下,每次执行这条命令创建的容器都是一个新的基于该镜像的容器。执行完这条指令后,一般只是启动了一个容器,还没有进入容器,无法在容器内部操作,所以一般使用的命令是
docker run -it
/bin/bash
这条命令是说以表示以交互模式和终端模式(-it)运行容器。并且启动shell会话类型为bash。也就是我们常见的终端了。启动并进入容器后,就可以在容器中进行自己想要的操作了。
当然也可以指定一下容器的名字(方便将容器保存为一个新的镜像)
docker run -it --name=
/bin/bash
退出容器
exit
查看当前的容器
docker ps #查看当前运行的容器
docker ps - a# 列出当前正在运行的容器+历史运行过的容器
进入容器(注意这里是进入之前运行过的容器中)
docker exec -it 容器id /bin/bash
删除容器
docker rm 容器id 删除指定容器
将容器保存为一个新的镜像
我们在创建容器时,推荐指定一下容器的名字,这样方便将容器保存为一个新的镜像。
docker commit
这里再提一下,在容器中进行环境配置操作结束后,先退出容器,然后就可以使用docker commit命令将这个容器保存为一个新的镜像。这个新的镜像里面就会保存有创建的环境。
这里不讲如何编写Dockerfile,只讲在有了Dockerfile文件的情况下怎么构建一个匹配的环境。
前面已经讲了Dockefile文件的作用,是一个程序清单,指明了要在镜像中的操作内容和操作流程。编写好Dockerfile文件后,只需要执行
docker build -t 镜像名:镜像tag .
注意命令最后有一个.的符号,含义是在当前目录下搜索Dockerfile文件。也就是说这条命令应该在有Dockefile的文件目录下执行。执行后,docker就会根据编写的Dockerfile自动构建镜像。镜像构建成功后,可以启动一个对应的容器,在容器中执行代码了。
当然,docker还有许多的功能,例如可以讲主机的文件挂载到容器当中去,多个容器相互配合等等,这些操作这里不再介绍。