当前位置:   article > 正文

Docker进阶与实战-理解 Docker镜像(1)

Docker进阶与实战-理解 Docker镜像(1)

 

Docker所宣称的用户可以随心所欲地“Build、Ship and Run”应用的能力,其核心是由Docker image(Docker 镜像)来支撑的。Docker通过把应用的运行时环境和应用打包在一起,解决了部署环境依赖的问题;通过引入分层文件系统这种概念,解决了空间利用的问题。它彻底消除了编译、打包与部署、运维之间的鸿沟,与现在互联网企业推崇的DevOps 理念不谋而合,大大提高了应用开发部署的效率。Docker 公司的理念被越来越多的人理解和认可也就是理所当然的了,而理解 Docker image则是深入理解 Docker 技术的一个关键点。
本章主要介绍 Docker image的使用和相关技术细节。其中3.1节介绍Docker image的基本概念;3.2节从image生命周期的角度介绍其使用方法;3.3 节介绍 Doker image 的组织结构;3.4节介绍Dockerimage相关的一些扩展知识。


3.1 Dockerimage概念介绍 

简单地说,Docker image 是用来启动容器的只读模板,是容器启动所需要的rootfs,类似于虚拟机所使用的镜像。首先需要通过一定的规则和方法表示 Docker image,如图3-1所示。
图3-1是典型的Docker 镜像的表示方法,可以看到其被“/”分为了三个部分,其中每部分都可以类比Github中的概念。下面按照从左到右的Namespace Repository TagRemote image hub顺序介绍这几个部分以及相关的一些重要概念
Remote-dockerhub.com/namespace/bar:latest
图3-1 Docker 镜像的典型表示法。

口Remote docker hub:集中存储镜像的We 服务器地址。该部分的存在使得可以区分从不同镜像库中拉取的镜像。若 Docker 的镜像表示中缺少该部分,说明使用的是默认镜像库,即Docker 官方镜像库
口Namespace:类似于Github 中的命名空间,是一个用户或组织中所有镜像的集合口 Repository:类似于Git 仓库,一个仓库可以有多个镜像,不同镜像通过 tag 来区分口Tag:类似Git仓库中的 tag,一般用来区分同一类镜像的不同版本。
口 Layer:镜像由一系列层组成,每层都用64位的十六进制数表示,非常类似于Git仓库中的commit。
口Image ID:镜像最上层的layer ID 就是该镜像的ID,Repotag 提供了易于人类识别的名字,而ID便于脚本处理、操作镜像。

镜像库是 Docker 公司最先提出的概念,非常类似应用市场的概念。用户可以发布自己的镜像,也可以使用别人的镜像。Docker 开源了镜像存储部分的源代码(Docker Registry以及Distribution),但是这些开源组件并不适合独立地发挥功能,需要使用Nginx等代理工具添加基本的鉴权功能,才能搭建出私有镜像仓库。本地镜像则是已经下载到本地的镜像可以使用docker images 等命令进行管理。这些镜像默认存储在/var/lib/docker 路径下,该路径也可以使用dockerdaemon-g参数在启动Daemon时指定。
提Docker 的镜像已经支持更多层级,比如用户的命名空间之前可以包含组织(Remotedockerhub.com/group/namespace/bar:latest)。但是目前Docker 官方的镜像库还不具备该能力。
3.2 使用Dockerimage

Docker内嵌了一系列命令制作、管理、上传和下载镜像。可以调用RESTAPI给Docker daemon发送相关命令,也可以使用client端提供的CLI命令完成操作。本书的第7章会详细阐述Docker RESTAPI的细节,本节则主要根据功能对涉及image的命令进行说明。下面就从Dockerimage的生命周期角度说明 Dockerimage的相关使用方法:

 

其中,--filter 用于过滤 docker images 的结果,过滤器采用 key=value 的这种形式。目前支持的过滤器为dangling和label。--filter"dangling-true"会显示所有“悬挂”镜像。“悬挂”镜像没有对应的名称和 tag,并且其最上层不会被任何镜像所依赖。docker commit在一些情况下会产生这种“悬挂”镜像。下面第一条命令产生了一个“悬挂”镜像,第二条命令则根据其特点过滤出该镜像了。图3-2中的d08407d841f3 就是这种镜像。

 

在上面的命令中,--no-trunc 参数可以列出完整长度的Image ID。若添加参数-q则会只输出Image ID,该参数在管道命令中很有用处。一般来说悬挂镜像并不总是我们所需要的,并且会浪费磁盘空间。可以使用如下管道命令删除所有的“悬挂”镜像。

 

这里的--digests比较特别,这个参数是伴随着新版本的Docker Registry V2(即Distribution)产生的,在本书接下来的第4章会详细说明。
按照Docker 官方路标和最近的动作Docker 只会保留最核心的image相关命令和功能因此那些非核心功能就会被删除。比如--tree 和--dot已经从Docker 1.7中删掉。官方推荐使用dockerviz@工具分析 Docker image。执行以下命令,可以图形化地展示 Docker image 

3.2.2 Build:创建一个镜像
创建镜像是一个很常用的功能,既可以从无到有地创建镜像,也可以以现有的镜像为基础进行增量开发,还可以把容器保存为镜像。下面就详细介绍这些方法。
1直接下载镜像
我们可以从镜像仓库下载一个镜像,比如,以下为下载busybox镜像的示例。
S 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和dockeload。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 等镜像。与此相对,dockerexport则是把一个镜像导出为根文件系统的归档。
福读者可以使用 Debian提供的 Debootstrap 制作 Debian或Ubuntu的 Base image,可以在Docker 官网找到教程 。

Docker 提供的docker commit 命令可以增量地生成一个镜像,该命令可把容器保存为一个镜像,还能注明作者信息和镜像名称,这与git commit类似。当镜像名称为空时,就会形成“悬挂”镜像。当然,使用这种方式每新增加一层都需要数个步骤(比如,启动容器、修改、保存修改等),所以效率是比较低的,因此这种方式适合正式制作镜像前的尝试当最终确定制作的步骤后,可以使用 docker build 命令,通过Dockerfile 文件生成镜像。
3.2.3Ship:传输一个镜像
镜像传输是连接开发和部署的桥梁。可以使用Docker 镜像仓库做中转传输,还可以使用docker export/docker save生成的tar包来实现,或者使用Docker 镜像的模板文件Dockerfile做间接传输。目前托管在Github 等网站上的项目,已经越来越多地包含有Dockerfile 文件;同时 Docker 官方镜像仓库使用了github.com的webhook 功能,若代码被修改就会触发流程自动重新制作镜像。

3.24Run:以image为模板启动一个容器
启动容器时,可以使用docker run 命令,该命令在相关章节会详细描述,本节不做深入说明。
图3-3总结了上文提到的 Docker 镜像生命周期管理的相关命令。现阶段 Docker 镜像相关的命令存在一些问题,包括:
口命令间逻辑不一致,比如列出容器使用的是 docker ps,列出镜像使用的是 dockerimageso
口混用命令导致命令语义不清晰,比如查看容器和镜像详细信息的命令都是 dockerinspecto
所以基于这些考虑,Docker 项目的路标中提到会把相关命令归类,并使用二级命令来管理。因此读者可以着重学习命令的用法和其实现的功能,不用过分关心命令的形式。

3.3 Dockerimage的组织结构
上节讲到 Docker image是用来启动容器的只读模板,提供容器启动所需要的rootfs.
那么Docker是怎么组织这些数据的呢?
3.31数据的内容
Docker image 包含着数据及必要的元数据。数据由一层层的image layer 组成,元数据则是一些JSON文件,用来描述数据(image layer)之间的关系以及容器的一些配置信息下面使用overlay存储驱动对 Docker image 的组织结构进行分析,首先需要启动Dockerdaemon,命令如下:
# docker daemon -D-s overlay -g /var/lib/docker
这里从官方镜像库下载busybox镜像用作分析。由于前面已经下载过该镜像,所以这里并没有重新下载,而只是做了简单的校验。可以看到 Docker 对镜像进行了完整性校验这种完整性的凭证是由镜像仓库提供的。相关内容会在后面的章节提到,这里不再展开介绍。

 

2数据和元数据
graph目录和overlay目录包含本地镜像库中的所有元数据和数据信息。对于不同的存储驱动,数据的存储位置和存储结构是不同的,本章不做深入的讨论。可以通过下面的命令观察数据和元数据中的具体内容。元数据含json和 layersize 两个文件,其中json 文件包含了必要的层次和配置信息,layersize 文件则包含了该层的大小。

 2数据和元数据
graph目录和overlay目录包含本地镜像库中的所有元数据和数据信息。对于不同的存储驱动,数据的存储位置和存储结构是不同的,本章不做深入的讨论。可以通过下面的命令观察数据和元数据中的具体内容。元数据含json和 layersize 两个文件,其中json 文件包含了必要的层次和配置信息,layersize 文件则包含了该层的大小。

 

可以看到Docker 镜像存储路径下已经存储了足够的信息,Docker daemon 可以通过这些信息还原出 Docker image:先通过repositories-overlay 获得image 对应的layerID;再根据layer 对应的元数据梳理出image 包含的所有层,以及层与层之间的关系;然后使用联合挂载技术还原出容器启动所需要的rootfs 和一些基本的配置信息。

3.32数据的组织
从上节看到,通过repositories-overlay 可以找到某个镜像的最上层layer ID,进而找到对应的元数据,那么元数据都存了哪些信息呢?可以通过 docker inspect 得到该层的元数据。为了简单起见,下面的命令输出中删除了一些与讨论无关的层次信息。
docker inspect 并不是直接输出磁盘中的元数据文件,而是对元数据文件进行了整注理,使其更易读,比如标记镜像创建时间的条目由created 改成了Created;标记容器配置的条目由container config 改成了ContainerConfig,但是两者的数据是完全一致的。

 

对于上面的输出,有几项需要重点说明一下:口Id:Image的ID。通过上面的讨论,可以看到imageID 实际上只是最上层的layerID,所以 dockerinspect 也适用于任意一层layer。口Parent:该layer的父层,可以递归地获得某个image的所有 layer 信息。口Comment:非常类似于Git的commit message,可以为该层做一些历史记录,方便其他人理解
口Container:这个条目比较有意思,其中包含哲学的味道。比如前面提到容器的启动需要以image为模板。但又可以把该容器保存为镜像,所以一般来说image的每个layer都保存自一个容器,所以该容器可以说是imagelayer的“模板”口Config:包含了该image的一些配置信息,其中比较重要的是:“env”容器启动时会作为容器的环境变量;“Cmd”作为容器启动时的默认命令;“Labels”参数可以用于dockerimages命令过滤
口Architecture:该image对应的CPU体系结构。现在Docker 官方支持amd64,对其他体系架构的支持也在进行中。

通过这些元数据信息,可以得到某个image包含的所有layer,进而组合出容器的rootfs,再加上元数据中的配置信息(环境变量、启动参数、体系架构等)作为容器启动时的参数。至此已经具备启动容器必需的所有信息。 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/73524?site
推荐阅读
相关标签
  

闽ICP备14008679号