docker(四)使用篇二:docker 镜像
在上一章中,我们介绍了 docker 镜像仓库,本文就来介绍 docker 镜像。
一、什么是镜像
docker 镜像本质上是一个 read-only 只读文件, 这个文件包含了文件系统、源码、库文件、依赖、工具等一些运行 application 所必须的文件。
我们可以把 Docker 镜像 理解成一个模板,通过这个模板,可以实例化出来很多容器。
docker 镜像里面由一层层 Union FS(联合文件系统)组成
镜像生活案例
镜像相当于我们 java 或者 C++中的类,相当于一个模板,可以很方便的构建出来不同的对象。
docker 镜像的组合层核心:联合文件系统(Union FS)
联合文件系统可以将几层文件目录挂载到一起,形成一个虚拟文件系统。
每一层文件系统我们叫做一层 layer,联合文件系统可以对每一层文件系统设置三种权限,只读(readonly)、读写(readwrite)和写出(whiteout-able),但是 docker 镜像中每一层文件系统都是只读的。(PS:联合文件系统的读写速度都比较慢)
构建镜像的时候,会从一个最基本的操作系统开始构建;每个构建的操作都相当于做一层文件目录的修改,即增加了一层文件系统。
一层层往上叠加,上层的修改会覆盖底层该位置的可见性。这也很容易理解,就像上层把底层遮住了一样。当使用的时候,只会看到一个完全的整体,不知道里面有几层,也不清楚每一层所做的修改是什么。
联合文件系统使得容器可以拥有自己的文件视图(即容器层),同时共享宿主机或者其他容器的基础镜像层(只读层)。这种方式不仅减少了存储空间的使用,而且提高了容器启动速度,因为只需要复制必要的镜像即可创建新的容器。
联合文件系统镜像分层生活案例
我们以日常的地板为例,开发商的房子提供给用户的时候一般是做好了地暖,而这些地暖其实是一层一层添加的,最底层的钢筋水泥层,然后添加保温层,采暖管,再铺设水泥层,到最后交付的时候家家户户都是水泥面,这些层一般是不可修改的。
最上层用户一般会再铺设商木地板或者地板砖每家每户的选择不一样,相当于我们镜像的容器层。
二、为什么需要镜像
1、通过打包,解决环境不一致问题
在部署应用时,原先是通过手工 / 写一些脚本的方式进行部署。这样部署面临的最大问题就是云端和本地环境可能不一致。用户为每个应用打包过程比较繁琐,需要配置和修改等操作,非常费劲。 Docker 镜像就是为了解决这个小小的打包功能,突然一夜之间成名。
那么,读者可能会猜测 Docker 镜像就是个压缩包,是的,猜对了,它就像一个压缩包文件。那么它是如何解决 Paas 时代所面临的云端和本地一致性问题?
很简单,它是把一个镜像制作成一个完整的操作系统,有所有文件和对应的目录结构,这样的压缩包跟你本地和测试环境用的操作系统一摸一样。
2、减少空间占用,加速软件开发
docker 最大的贡献就是定义了容器镜像的分层的存储格式,docker 镜像技术的基础是联合文件系统(UnionFS),其文件系统是分层的。这样既可以充分利用共享层,又可以减少存储空间占用。
docker 镜像提供了一种打包应用程序和预配置服务器环境的便捷方式,也可以很方便的将其用于个人用途或与其他 Docker 用户公开共享。
三、核心:镜像相关命令
命令清单
命令 | 别名 | 功能 | 备注 |
docker pull | docker image pull | 从镜像仓库中拉取镜像 | 和镜像仓库命令相同,亦可以归类为镜像命令 |
docker push | docker image push | 推送镜像到仓库 | 和镜像仓库命令相同,亦可以归类为镜像命令 |
docker images | docker image ls / docker image list | 列出本地镜像 | 必须掌握 |
docker tag | docker image tag | 给本地某个镜像打标签(标记版本),在推送镜像到仓库时比较有用 | 必须掌握 |
docker rmi | docker image rm / docker image remove | 删除本地某个镜像 | 必须掌握 |
docker build | docker image build | 通过 dockerfile 制作镜像 | 必须掌握 |
docker save | docker image save | 把制定镜像保存成 tar 格式的归档文件 | 必须掌握 |
docker load | docker image load | 导入使用 docker save 保存的 tar 格式的镜像文件 | 必须掌握 |
docker image inspect | 查看镜像的详细信息 | 必须掌握 | |
docker history | docker image history | 查看镜像历史 | |
docker import | docker image import | 从归档文件 docker export 中创建镜像。 (与容器 docker export 对应,在下一章容器章节讲解) | |
docker prune | 删除不使用的镜像 |
1、docker images
# RESPOSITORY 指的是镜像所在仓库名
docker images [关键参数] [RESPOSITORY[:TAG]]
关键参数
无参情况:列出本地所有镜像
-a:列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层);
--digests:显示镜像的摘要信息;
-f:显示满足条件的镜像;
--format:指定返回值的模板文件;
--no-trunc:显示完整的镜像信息;
-q :只显示镜像 ID
功能: 列出本地镜像
# 列出本地全部镜像
docker images
# 列出本地镜像中 REPOSITORY 为 ubuntu 的镜像列表。
docker images ubuntu
2、docker tag
# SOURCE_IMAGE:原镜像名
# TARGET_IMAGE:目标镜像名(可以加上仓库地址,就可以归入某一仓库)
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
功能: 给本地镜像打标签,并归入某一仓库(目的通常为推送做准备)

3、docker rmi
# 可以同时删除多个镜像
docker rim [关键参数] 镜像名....
关键参数
-f:强制删除;
--no-prune:不移除该镜像的过程镜像,默认移除;
功能:删除指定镜像
(PS:删除前需要把引用了该镜像的容器删掉之后才能删除镜像;由于是比较暴力的删除镜像,用的较少,一般使用 docker rm 删除容器)

4、docker save
# 可以同时把多个镜像归档到一个文件
docker save [关键参数] 镜像名...
功能:把指定的镜像保存成 tar 归档文件,便于在各个服务器上分发
关键参数
-o:把镜像保存到哪一个文件中,(可以同时写上路径,就保存在那个路径中;只写文件名则是默认保存在当前文件夹中)

5、docker load
docker load [关键参数]
功能:把 tar 文件再加载成镜像
关键参数
--input , -i : 导入的文件的文件名,代替 STDIN。
--quiet , -q : 精简输出信息。(默认是一层层导入的,会全部展示)

6、docker image inspect
# 可以同时查看多个镜像
docker image inspect [关键参数] 镜像名...
功能:查看镜像的详细信息
(PS:如果是 docker inspect 的话,docker 会自动判断是镜像还是容器,然后显示信息)

7、docker history
docker history [关键参数] 镜像名
功能:显示镜像的历史
关键参数:
-H , --human:大小和日期采用人容易读的格式展现
--no-trunc:显示全部信息,不要隔断(不截断的话像 ID 等都会很长)
-q, --quiet:只显示镜像 id 信息

8、docker import
其与容器 docker export 对应,二者搭配使用,因此将在下一章容器进行讲解
9、docker image prune
docker image prune [关键参数]
功能:删除当前未使用的镜像
(PS:无参的话,会删除虚悬镜像,即那些既没有标签又被没有任何容器引用的镜像)
关键参数:
-a , --all:删除全部不使用的镜像(只要没有容器使用,就被视作未使用镜像,比较危险,慎用)
--filter filter:指定过滤条件;
-f, --force:不提示是否删除;

10、docker build
docker build [关键参数] PATH | URL | -
功能:用于使用 dockfile 创建镜像(会在 dockerfile 制作镜像章节详细讲解)
关键参数:
--build-arg=[] :设置镜像创建时的变量;
-f :指定要使用的 Dockerfile 路径;
--label=[] :设置镜像使用的元数据;
--no-cache :创建镜像的过程不使用缓存;
--pull :尝试去更新镜像的新版本;
--quiet, -q :安静模式,成功后只输出镜像 ID;
○ --tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构
建中为一个镜像设置多个标签。
○ --network: 默认 default。在构建期间设置 RUN 指令的网络模式