一、获取镜像
- 镜像获取即是从镜像仓库中下载镜像到本地,默认配置下即使从官方Docker Hub中下载镜像到本地;当然,也可以通过修改本地配置和账户信息,从国内的公有仓国库(例如阿里云仓库)下载镜像,或是在配置了私有仓库后,从公司/个人的私有仓库中下载镜像到本地。无论是从哪个仓库下载镜像,使用的命令都是一样的:
docker pull Name:Tag
(Name表示镜像仓库名称,用于区分镜像;Tag是镜像标签,用于标识镜像版本) - 获取镜像示例,例如获取一个Ubuntu 18.04系统的基础镜像:
docker pull ubuntu:18.04
- 在拉取镜像时,也可以省略镜像标签(tag),例如使用docker pull ubuntu 也能够拉取一套ubuntu的镜像,当不指定标签时,系统默认会为我们选择latest标签,这时候就会下载仓库中最新版本的镜像。但是,不推荐使用省略标签的方式来来取镜像,因为镜像的latest标签意味着该镜像的内容会跟踪最新版本的变更而变化,镜像内容是不稳定的,所以企业从稳定性角度考虑,一般不会使用latest标签的镜像。
- 在拉取镜像的过程中,我们能够观察到镜像的分层(layer)信息,当不同的镜像包括相同的层时,本地仅存储了层的一份内容,减小了存储空间。
- 张三家的狗可以叫“旺财”,李四家的狗也可以叫“旺财”,那如何区分这两只“旺财”呢?在Docker中,也可能出现类似的问题,即是张三的仓库中可能有一个“ubuntu:16.04”的镜像,李四的仓库中也有可能有一个“ubuntu:16.04”的镜像,这时候出现了镜像重名的情况,那这种情况应该如何区分呢?
- 实际上,镜像的仓库名称中还应该添加仓库地址,即是注册服务器(registry)的地址作为前缀,当省略前缀时,则默认拉取的官方Docker hub所提供的镜像。
docker pull ubuntu:16.04
表示从官方docker hub中拉去进行docker pull cloudcomputing/ubuntu:tagname
表示从自己在Docker hub上创建的个人仓库中拉取镜像docker pull regis**.aliyuncs.com/cloudubuntu/ubuntu:16.04
表示从自己在阿里云上注册的仓库中拉取镜像- 所以,会到上面提到的问题,如何区分两个叫“旺财”的狗呢,本质上就是在“旺财”前面加上它的主人,“张三家的旺财”、“李四家的旺财”来进行区分。想要区分不同开发者打包的名字相同(ubuntu:16.04)的镜像,则是在镜像名称前加上注册服务器的名称。
二、查看镜像信息
- 查看本地主机上的所有镜像:
docker images
或者docker image ls
(docker images书写简洁,因此使用较多)。
- 第一列(
REPOSITORY
)表示仓库名 - 第二列(
TAG
)表示标签信息。(用于标记镜像的版本,例如在同一个仓库[ubuntu]中,可以通过标签[14.04, 16.04]来区分不同的镜像版本)。 - 第三列(
IMAGE ID
)表示镜像ID。(该属性是镜像的重要属性,是镜像的唯一标识符。) - 第四列(
CREATED
)表示镜像的创建时间 - 第五列(
SIZE
)表示镜像的大小。(SIZE只表示了该镜像的逻辑体积大小,实际上由于相同的镜像层本地只会保存一份,物理上占用的存储空间会消息SIZE所表示的逻辑体积。)
- 使用tag命令添加镜像标签:
docker tag ubuntu:16.04 myubuntu:16.04
- 以上命令只是改变了镜像的标签信息,实际上通过对比镜像ID会发现,两个镜像的ID是一致的,也即是这两个名称指代的镜像本质上指向的是同一个镜像文件。(例如姓名“张三”指的是你,学号“2023001”指的还是你,某一门课程上“3组组长”指的还是你……)
- 使用inspect查看镜像的详细信息,包括镜像的制作者、适应的架构等:
docker inspect ubuntu:16.04
- 如果只想要查看某一项的内容,则使用:
docker inspect -f {{“.Architecture”}} ubuntu:18.04
- 使用history命令查看镜像历史(镜像文件采用分层技术进行构建,那各个层次的具体内容是什么?可使用history进行查看):
docker histoty ubuntu:18.04
三、搜索镜像
- Docker官方仓库为开发者提供了丰富的镜像资源,就以‘ubuntu’镜像为例,docker hub中就提供了一万多个相关的镜像仓库,那如何找到自己想要的镜像呢?那我们就需要了解docker镜像搜索的方法。
- docker搜索镜像语法:
docker search [option] keyword
,这里的option
是命令中的可选参数,主要包括如下选项:
-f/--filter
: 过滤输出内容--format string
:格式化输出内容--limit int
:限制输出结果的数量,默认是25个--no-trunc
:不截断输出结果
3 案例:搜索官方提供的带有‘ubuntu’关键字的镜像:docker search --filter=is-official=true ubuntu
4 案例:搜索仓库收藏数超过100,且含有关键字‘centos’的镜像:docker search --filter=stars=20 centos
四、删除和清理镜像
- 基于标签删除镜像:
docker rmi name:tag
,例如:docker rmi ubuntu:16.04
- 基于镜像ID删除镜像:
docker rmi ID
,例如:docker rmi b6f507652425
- 如果基于镜像已经创建了相应的容器,则该镜像文件默认是无法被删除的。
- 如果想要强行删除被使用的镜像,可以使用如下语法:
docker rmi -f name:tag
- 以上语法虽然实现了镜像的强制删除,但是并不推荐这种方式,正确的做法应该是先删除容器,再删除镜像。
- 使用Docker一段时间后,系统中可能会遗留一些临时的镜像文件,以及一些没有被使用的镜像,可以通过
docker image prune
命令来进行清理。
五、创建镜像
- 创建镜像的方法主要有以下几种:基于容器进行创建(commit)、本地模板导入(import)、基于Dockerfile创建(build)。
(一)基于容器进行创建
- 通过前面的学习,我们了解到,一方面,通过运行镜像能够启动一个Docker容器,容器也是我们向外提供服务的基本单元;另一方面,我们了解到镜像通过分层思想来构建,当我们对容器这里的容器进行修改后,就是在原镜像的基础上增加了一个新的层。
- 基本语法:
docker commit [options] container [repository] [:tag]
,其中options的可选项包括:
-a/--author=” ”
:作者信息-c/--change=[ ]
: 提交的时候执行Dockerfile指令,包括CMD|EXPOSE等-m/--message=” “
: 提交信息-p/--pause=true
: 提交时暂停容器运行
- 案例:
docker commit -m “build image from container” -a “cloud” a925cb40b3f0 testubuntu:16.04
(二)基于本地模板导入
- 在北京的甲公司承接了在重庆的乙公司的某一个开发项目,项目的最终交付形式之一就是一套docker镜像,这时候甲公司可能会将制作好的镜像打包成一个个文件,然后交付给乙公司。乙公司的工程师首先将文件上传到服务器,然后在服务器中通过将本地文件导入到docker仓库中,就实现了镜像的创建。所以这种方式的本质就是从本地读取特定格式的文件,然后将该文件保存到本地仓库。
- 语法:
docker [image] import [options] file | url [repository] [:tag]
- 案例:
docker import local-ubuntu.tar.gz localubuntu:16.04
(三)基于Dockerfile创建镜像
- 基于Dockerfile创建镜像是最常用的方式,相较于前两种方法,这种方法的效率更高,定制性更强,因而更符合企业中的应用需求。Dockerfile本质上是一个文本文件,文件中按照一定的顺序编写好了构建镜像的指令,基于Dockerfile构建镜像时,首先需要指定一个基础镜像,然后则会顺序执行文件中的指令,在运行指令的过程中会在基础镜像的基础上逐渐增加文件层(这也对应了前面提到的分层构建思路)。
- 基于Dockerfile构建镜像的步骤
- 首先新建一个空目录,该目录用于保存下面提到的Dockerfile以及相关文件
- 然后创建一个Dockerfile文件,Dockerfile中安装创建需求编写好相应的代码
- 再者,如果需要导入或引用其他的文件,则将这些文件保存到以上目录中
- 最后,基于Dockerfile制作一个新镜像(注意:不要省略了最后的点号):
docker build -t myubuntu:18.04 .
- Dockerfile案例一
- 以上案例展示了Dockerfile文件中的四个主体内容,包括基础镜像信息、维护者信息、镜像操作指令和容器启动时的执行指令;当然,并不是所有的Dockerfile都包含这几部分。
- FROM指令指明本镜像的基础镜像、LABEL标记维护者信息、RUN后面的指令即是对镜像的操作指令,每执行一次RUN指令就会在docker镜像中增加一层(回忆docker的分层构建概念理解),而过多无意义的层,会造成镜像膨胀过大。因此在编写Dockerfile的过程中应当尽量减少指令的执行次数。CMD来指定运行容器时的操作指令。
- 基于Dockerfile构建镜像(注意:不要省略了最后的点号):
docker build -t myubuntu:18.04 .
- Dockerfile案例二
- Dockerfile 的指令每执行一次都会在 docker 上新建一层,在本案例中,一共运行了三次run命令,因此会创建三次,这可能导致最终创建的镜像过大。因此这不是一种高效的编写方法。
- 运行该Dockerfile:
docker build -t redis:v5.1 .
六、存出和导入镜像
- 存出镜像:即是将镜像保存为本地文件
- 案例:
docker save -o ubuntu_18.04.tar demoubuntu:18.04
- 载入镜像:将本地的tar文件导入到本地的镜像仓库
- 案例:
docker load -i ubuntu_18.04.tar 或者 docker load < ubuntu_18.04.tar
七、上传镜像
- 上传镜像即是将自己制作好的镜像上传到Docker公共仓库或者企业内部的私有仓库,亦或是其他的仓库。
- 从开发者的角度来看,前面我们到docker hub中来取镜像时,即是从docker官方的公共仓库中拉取其他工程师制作好的镜像,因此这里的docker hub为所有的开发者提供了一个交流共享的平台;从企业的角度来讲,企业即希望内部的员工能够实现资源共享以提高公司的生产效率,又希望保护公司内部的私有财产和知识产权,因此企业通常会创建一个供企业内部使用的私有仓库。所以上传镜像本质上就是将镜像上传到一个远程(docker官方仓库、企业内部、阿里云公共仓库)的仓库中。
(一)上传镜像到Docker Hub - 注册Docker Hub账号(网址:https://hub.docker.com/)
- 准备好原始镜像,例如我这里选择Ubuntu:18.04作为源镜像
- 在本地docker客户端登录docker账户(提前注册):
docker login
- 到docker官网(https://hub.docker.com/)创建自己的私人仓库
- 根据私人仓库名称对镜像标签镜像重命名:
sudo docker tag ubuntu:18.04 swxycloudcomputing/cloud:latest
- 将本地镜像推送至在线仓库:
sudo docker push swxycloudcomputing/cloud:latest
- 打开docker官网,查看刚推送的镜像
(二)上传镜像到阿里云公共仓库 - 步骤和前面的案例类似,登录到阿里云仓库也会有相应的语法提示。