3.2 使用Docker image
Docker内嵌了一系列命令制作、管理、上传和下载镜像。可以调用REST API给Docker daemon发送相关命令,也可以使用client端提供的CLI命令完成操作。本书的第7章会详细阐述Docker REST API的细节,本节则主要根据功能对涉及image的命令进行说明。下面就从Docker image的生命周期角度说明Docker image的相关使用方法。
3.2.1 列出本机的镜像
下面的命令可以列出本地存储中镜像,也可以查看这些镜像的基本信息。
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 14.04.2 2103b00b3fdf 5 months ago 188.3 MB
ubuntu latest 2103b00b3fdf 5 months ago 188.3 MB
ubuntu trusty 2103b00b3fdf 5 months ago 188.3 MB
ubuntu trusty-20150228.11 2103b00b3fdf 5 months ago 188.3 MB
ubuntu 14.04 2d24f826cb16 5 months ago 188.3 MB
busybox buildroot-2014.02 4986bf8c1536 7 months ago 2.43 MB
busybox latest 4986bf8c1536 7 months ago 2.43 MB
此外,通过--help参数还可以查询docker images的详细用法,如下:
$ docker images --help
Usage: docker images [OPTIONS] [REPOSITORY]
List images
-a, --all=false Show all images (default hides intermediate images)
--digests=false Show digests
-f, --filter=[] Filter output based on conditions provided
--help=false Print usage
--no-trunc=false Don't truncate output
-q, --quiet=false Only show numeric IDs
其中,--filter用于过滤docker images的结果,过滤器采用key=value的这种形式。目前支持的过滤器为dangling和label。 --filter "dangling=true"会显示所有“悬挂”镜像。“悬挂”镜像没有对应的名称和tag,并且其最上层不会被任何镜像所依赖。docker commit在一些情况下会产生这种“悬挂”镜像。下面第一条命令产生了一个“悬挂”镜像,第二条命令则根据其特点过滤出该镜像了。图3-2中的d08407d841f3就是这种镜像。
$ docker commit 0d6cbf57f660
$ docker images --filter "dangling=true"
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
<none> <none> d08407d841f3 3 hours ago 2.43 MB
在上面的命令中,--no-trunc参数可以列出完整长度的Image ID。若添加参数-q则会只输出Image ID,该参数在管道命令中很有用处。一般来说悬挂镜像并不总是我们所需要的,并且会浪费磁盘空间。可以使用如下管道命令删除所有的“悬挂”镜像。
$ docker images --filter "dangling=true" -q | xargs docker rmi
Deleted: 8a39aa048fe3f2e319651b206073b2a2e437dcf85c15fedb6f437cfe86105145
这里的--digests比较特别,这个参数是伴随着新版本的Docker Registry V2(即Distribution)产生的,在本书接下来的第4章会详细说明。
按照Docker官方路标和最近的动作,Docker只会保留最核心的image相关命令和功能,因此那些非核心功能就会被删除。比如--tree和--dot已经从Docker 1.7中删掉。官方推荐使用dockerviz工具分析Docker image。执行以下命令,可以图形化地展示Docker image的层次关系。
dockviz images -d | dot -Tpng -o images.png
执行结果如图3-2所示,可以看到,同一个仓库中的镜像并不一定要有特别的关系,比如ubuntu: 14.04和ubuntu:14.04.2之间就没有共享任何层。
3.2.2 Build:创建一个镜像
创建镜像是一个很常用的功能,既可以从无到有地创建镜像,也可以以现有的镜像为基础进行增量开发,还可以把容器保存为镜像。下面就详细介绍这些方法。
1.直接下载镜像
我们可以从镜像仓库下载一个镜像,比如,以下为下载busybox镜像的示例。
$ docker pull busybox
Using default tag: latest
Pulling repository docker.io/library/busybox
8c2e06607696: Download complete
cf2616975b4a: Download complete
6ce2e90b0bc7: Download complete
Status: Downloaded newer image for busybox:latest
具体使用镜像仓库的方法,本书会在后续章节详细描述,这里暂不做说明。
2.导入镜像
还可以导入一个镜像,对此,Docker提供了两个可用的命令docker import和docker load。docker load一般只用于导入由docker save导出的镜像,导入后的镜像跟原镜像完全一样,包括拥有相同的镜像ID和分层等内容。下面的第一行命令可以导出busybox为busybox.tar,第二条命令则是导入该镜像:
$ docker save -o busybox.tar busybox
$ docker load -i busybox.tar
不同于docker load,docker import不能用于导入标准的Docker镜像,而是用于导入包含根文件系统的归档,并将之变成Docker镜像。
3.制作新的镜像
前面说过,docker import用于导入包含根文件系统的归档,并将之变成Docker镜像。因此,docker import常用来制作Docker基础镜像,如Ubuntu等镜像。与此相对,docker export则是把一个镜像导出为根文件系统的归档。
提
示 读者可以使用Debian提供的Debootstrap制作Debian或Ubuntu的Base image,可以在Docker官网找到教程。
Docker提供的docker commit命令可以增量地生成一个镜像,该命令可把容器保存为一个镜像,还能注明作者信息和镜像名称,这与git commit类似。当镜像名称为空时,就会形成“悬挂”镜像。当然,使用这种方式每新增加一层都需要数个步骤(比如,启动容器、修改、保存修改等),所以效率是比较低的,因此这种方式适合正式制作镜像前的尝试。当最终确定制作的步骤后,可以使用docker build 命令,通过Dockerfile文件生成镜像。
3.2.3 Ship:传输一个镜像
镜像传输是连接开发和部署的桥梁。可以使用Docker镜像仓库做中转传输,还可以使用docker export/docker save生成的tar包来实现,或者使用Docker镜像的模板文件Dockerfile做间接传输。目前托管在Github等网站上的项目,已经越来越多地包含有Dockerfile文件;同时Docker官方镜像仓库使用了github.com的webhook功能,若代码被修改就会触发流程自动重新制作镜像。
3.2.4 Run:以image为模板启动一个容器
启动容器时,可以使用docker run命令,该命令在相关章节会详细描述,本节不做深入说明。
图3-3总结了上文提到的Docker镜像生命周期管理的相关命令。现阶段Docker镜像相关的命令存在一些问题,包括:
命令间逻辑不一致,比如列出容器使用的是docker ps,列出镜像使用的是docker images。
混用命令导致命令语义不清晰,比如查看容器和镜像详细信息的命令都是 docker inspect。
所以基于这些考虑,Docker项目的路标中提到会把相关命令归类,并使用二级命令来管理。因此读者可以着重学习命令的用法和其实现的功能,不用过分关心命令的形式。