docker(13):docker镜像的分层

docker(13):docker镜像的分层

https://www.cnblogs.com/CloudMan6/p/6806193.html

https://docs.docker.com/storage/storagedriver/

https://www.jianshu.com/p/e3a4b69f649c

1 什么是镜像分层

  因为镜像包含操作系统完整的 root 文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 Union FS 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。

镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。

分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。

1.1   图形

 

 

 

① 新镜像不再是从 scratch 开始,而是直接在 Debian base 镜像上构建。
② 安装 emacs 编辑器。
③ 安装 apache2。
④ 容器启动时运行 bash。

 

一个docker镜像由多个可读的镜像层组成,然后运行的容器会在这个docker的镜像上面多加一层可写的容器层,任何的对文件的更改都只存在此容器层。因此任何对容器的操作均不会影响到镜像。

 

所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。

只有容器层是可写的,容器层下面的所有镜像层都是只读的

下面我们深入讨论容器层的细节。

镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /a,上层的 /a 会覆盖下层的 /a,也就是说用户只能访问到上层中的文件 /a。在容器层中,用户看到的是一个叠加之后的文件系统。

  1. 添加文件 在容器中创建文件时,新文件被添加到容器层中。
  2. 读取文件 在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后打开并读入内存。
  3. 修改文件 在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。
  4. 删除文件 在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。

只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。

这样就解释了我们前面提出的问题:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享

 

1.2  命令呈现

[root@docker-136 ~]# docker images | grep kod
kod                           v8                  58de0c0137bb        20 hours ago        556MB
kod                           v7                  e36f3f496d0a        20 hours ago        556MB
kod                           v1                  681c97c0548e        25 hours ago        550MB
[root@docker-136 ~]# docker image history kod:v8
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
58de0c0137bb        20 hours ago        /bin/sh -c #(nop)  CMD ["/bin/bash" "/init.s…   0B                  
0fa6d928d688        20 hours ago        /bin/sh -c #(nop) ADD file:fa11fc6a3c3a33648…   47B                 
7a19cf169c31        20 hours ago        /bin/sh -c chown -R nginx:nginx  /usr/share/…   46.2MB              
72fd74170a7a        20 hours ago        /bin/sh -c cd /usr/share/nginx/html  && \cur…   46.2MB              
1271f8a62000        20 hours ago        /bin/sh -c #(nop) ADD file:01f739a3567b5c1f4…   653B                
e75650fe8ed5        20 hours ago        /bin/sh -c rm -f /etc/nginx/nginx.conf          0B                  
625b5155b66c        20 hours ago        /bin/sh -c sed -i "s#apache#nginx#g"  /etc/p…   10kB                
db621c02d365        20 hours ago        /bin/sh -c yum install curl  nginx net-tools…   262MB               
0fc4bba9b2ac        20 hours ago        /bin/sh -c curl -o /etc/yum.repos.d/epel.rep…   664B                
caa065f6c677        20 hours ago        /bin/sh -c sed -i 's#$basearch#x86_64#g' /et…   1.44kB              
4c9370a41440        20 hours ago        /bin/sh -c sed -i 's#$releasever#7#g' /etc/y…   1.46kB              
78d6598368d1        20 hours ago        /bin/sh -c curl -o /etc/yum.repos.d/CentOS-B…   1.57kB              
9a247db207e6        4 days ago          /bin/sh -c #(nop)  ENV container=docker         0B                  
9f38484d220f        5 months ago        /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
<missing>           5 months ago        /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B                  
<missing>           5 months ago        /bin/sh -c #(nop) ADD file:074f2c974463ab38c…   202MB               
[root@docker-136 ~]#

 

2  镜像分层的好处

共享资源,节省资源
有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了

修改dockerfile之后(尽量追加到文件后面),再次构建速度快

 

posted on 2019-08-13 13:40  光阴8023  阅读(428)  评论(0编辑  收藏  举报