1  概述

镜像包含启动容器所需的文件系统和内容,可以理解为打包的文件,用于创建并启动docker容器。

镜像的生成途径有三个:

1.基于dockerfile实现,镜像制作的程序文件

2.基于容器实现,启动容器后,将新的操作制作为新镜像

3.docker hub automated builds

镜像文件采用分层构建机制,最底层为bootfs,上面为rootfsrootfs上还可以有多层。位于最下层的镜像文件为父镜像(parent image,最底层为基础镜像(base imagerootfs为这一层,这一层必须存在).最上层为“可读写”层,其下的均为“只读”层

如下截图

Docker 之 基于容器的镜像制作_第1张图片

其中:

bootfs:用于系统引导的文件系统,包含bootloaderkernel,容器启动完成后会被卸载以节约内存资源,可以理解为容器引擎,不是宿主机操作系统

rootfs:位于bootfs之上,表现为docker容器的根文件系统;

传统模式中,系统启动时,内核挂载rootfs时会首先将其挂载为只读模式,完整性自检完成后将其重新挂载为读写模式

docker中,rootfs由内核挂载为只读模式,而后通过“联合挂载”技术额外挂载一个“可写”层。联合挂载,需要文件系统支持,目前支持最好的文件系统为Aufs(advanced multi-layered unification filesystem),高级多层统一文件系统,用于为linux文件系统实现”联合挂载“,docker 最初使用aufs作为容器文件系统层,目前还作为存储后端之一来支持,目前没有基层到linux内核,需要对内核打补丁才能使用aufsdocker的分层镜像,除了aufs,还支持btrfs,devicemappervfs。在ubuntu系统下,docker默认支持ubuntuaufs,这也是为什么很多底层镜像都是ubuntu的原因,因为ubuntu更好的支持aufs.centos7用的是devicemapper.但是,devicemapper在性能上有问题。linux 在3.18版本后把overlayfs整合到内核里,docker-ce目前在centos7上支持的文件系统为overlay,使用overlay作为docker的后端存储机制,如果是按照extras源里的docker包,版本1.12,后端的存储为devicemapper文件系统

2  Regeistry介绍

Registry用于保存docker镜像,包括镜像的层次结构和元数据,RegistryRepositoryIndex两个组件组成

启动镜像时,docker daemon会试图从本地获取相关的镜像,本地镜像不存在时,将从registry中下载该镜像并保存到本地。

registry是一个无状态,高可扩展的服务端应用程序,可以用于存储和分发docker 镜像。docker registry里,index是一个重要组件,让用户可以查询搜索到相关的镜像,同时index支持认证功能。

registry分为两种:

公共的registry,如docker hub,

私有化docker registry,自己搭建的registry。

通过应用程序包docker-distribution.x86_64 来实现私有registry搭建,在extras仓库中。这个软件没有web页面,也不支持认证。可以通过nginx配置反代,在nginx上实现认证

或者通过harbor这个软件才实现私有化仓库搭建,这个软件有vmware公司维护,企业级的容器registry,是在docker-distribution基础上添加功能实现的。建议用harbor创建私有registry(仓库)

3  Repository介绍

Repository是指由某特定的docker镜像的所有迭代版本组成的镜像仓库,一个Registry内部有多个Repository.其中,Repository可风味“顶层仓库”和“用户仓库”,用户仓库名称格式为“用户名/仓库名”。

每个仓库可以包含多个Tag(标签),每个标签对象对应一个镜像,可以手动打标签,如果和官方有冲突,以本标签地为准,统一镜像可以有多个标签,tag不一样,但是image id一样,便签配置命令如下,把busybox的镜像latest版本,再打一个标签为sunny01,则busybox同时有两个标签,image id一样

 docker tag busybox:latest busybox:sunny01

4  Index介绍

用于维护用户账号,镜像的校验以及公共名称空间的信息

相当于为registry提供了一个可以完成用户认证等功能的检索接口

5  docker hub功能介绍

docker hub支持如下组件

image repositories:镜像仓库

automated builds:当修改原码仓库时自动构建镜像,只需要上传dockerfile就会构建镜像

webhooks:自动构建的属性之一,当成功推送一个文件到仓库后webhooks触发一个动作

organizations:工作组

github and bitbucket integration:和github整合起来,在github上开发,定义webhooks,当监控到github有新的推送后,自动执行构建镜像,完成镜像构建。

使用docker hub之外的第三方仓库,推送镜像,需要指定如下信息

向那个仓库的那个端口,哪个名称空间推送镜像,镜像名称和标签是什么,其中port默认为5000,命令如下

docker pull  [:]/[/]:

6  基于容器制作镜像

制作镜像三个方法

1.基于容器制作

2.基于dockerfile实现,镜像制作的程序文件

3.Docker Hub Automated Builds

这里仅介绍基于容器制作镜像

1.基于容器实现

启动容器后,将新的操作制作为新镜像

例子

启动干净的镜像文件busybox,然后再容器内创建httpd的根目录和index.html文件,然后制作成行的镜像

 启动容器,名称为sunny01img

docker run -it --name sunny01img busybox:sunny01
#在容器内进行修改
/ # mkdir -p /web/html
/ # cd /web/html
/web/html # vi index.html

this is sunny docker image,it is a nice day!<\h1>

在另一个终端,执行如下命令

 docker commit -a "sunny" -p -m "for test commit image"  sunny01img

用命令查看新生成的镜像

docker images

查看到有tag为none的新生成的镜像

将镜像推送到阿里云镜像仓库中

登录https://dev.aliyun.com,选择产品和服务--》容器镜像服务--》镜像仓库,创建一个本地仓库,名称为sunnytest

首先给本地镜像打标签

docker tag 3498bc48a842 registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest:sunnyweb

这里的镜像名称为新建的仓库名

将打了标签的镜像推送到阿里云,要先登录仓库


docker login registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest

这里registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest 为新建的仓库名,输入账号为开发者平台的账号,密码为Registry登录密码,不是登录开发者平台密码

登录成功后,将镜像推送到阿里云仓库sunnytest上,把镜像推送到远程仓库,用push实现


 docker push registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest:sunnyweb

这里的registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest:sunnyweb是镜像名:tag

使用新的镜像来启动容器

新建一个标签

docker tag  3498bc48a842 websrv:sunnyweb01

将新的镜像websrv:sunnyweb01 运行为守护模式(-d,即后台),然后指定进程为httpd,前端运行模式(-f),指定家目录为/web/html

docker run --name sunnyweb01 -d websrv:sunnyweb01 httpd -f -h /web/html

查看

docker ps

查看到websrv:sunnyweb01镜像运行为容器sunnyweb01.

 查看进程信息

 docker top sunnyweb01

查看详细容器信息

docker inspect sunnyweb01

查看到当前的容器ip为172.17.0.3

测试httpd的服务

curl 172.17.0.3

改变容器的默认启动命令

在第一版新建镜像websrv:sunnyweb01的基础上创建第二版的镜像,

在另一个终端上,不执行默认的cmd,而是默认启动httpd服务

首先,先启动镜像,进入cmd,执行相关命令

docker run --name sunnyweb02 -it websrv:sunnyweb01

打开另一个shell终端,执行如下命令,生成一个新的镜像

docker commit -a "sunny " -p -m "web server" -c 'CMD  ["/bin/httpd","-f","-h","/web/html"]' sunnyweb02

注意,-c,修改运行中的命令,后接一个字典,所有的字段都要分别传递,用引号引用,逗号隔开,否则参数传递失败,导致镜像不能启动。

sunnyweb02是指当前要作为镜像的模板容器名称,如这里以sunnyweb02这个容器作为模板来创建新镜像

给新生成的镜像打标签

docker tag 990ff989b8fb registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest:sunnyweb2.0

经新生成的镜像推送到阿里云仓库

 docker push registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest:sunnyweb2.0

启动镜像,容器名称为web2.0,并且运行在后台(-d)

docker run --name web2.0 -d registry.cn-hangzhou.aliyuncs.com/ghbsunny/sunnytest:sunnyweb2.0

测试

查看容器是否正常运行

docker ps

查看容器的ip

docker inspect web2.0

这里查看到ip 为 172.17.0.6

测试httpd服务


curl 172.17.0.6

这个例子说明,制作镜像是可以-c改变默认的命令,而不是默认的sh命令,可以让容器基于新建镜像启动时运行指定的命令。

7  分发镜像文件

docker允许把镜像导入和导出,包括镜像的源属性信息和所有层存储为tar格式的打包文件,并在其他服务器导入该镜像,并运行

导出镜像

默认情况下,会把导出文件打印在屏幕,因此需要用参数-o来指定输入的镜像文件

命令如下


docker save -o /root/testsave.tar sunnytest3:1.0

/root/testsave.tar 的镜像打包文件传到运行docker服务的10.10.10.73的服务器上


scp testsave.tar 10.10.10.73:/root

 10.10.10.73上导入镜像

注意,确保 10.10.10.73安装docker,且运行docker服务,-i选项是指从tar备份文件输入,而不是从标准输入来输入数据

docker load -i testsave.tar

 10.10.10.73运行导入的镜像sunnytest3:1.0,后台运行(-d)

 docker run --name testload -d sunnytest3:1.0

测试

容器启动成功后,运行一个httpd服务,因此用curl进行测试

 curl 172.17.0.2

以上用于分发需求较少的情况下使用,只能在数量不多,分发需求较少的环境实现。注意12版和17版命令有区别,17 docker image save / load

命令docker image --help来查看更多选项的介绍

用docker image history 查看镜像的操作历史

docker image history sunnytest3:1.0

命令stats用来统计容器的数据,查看容器的资源利用状态,动态刷新,如容器的CPU,内存,网络等信息,如下命令,统计容器testload的信息

docker stats testload