Docker镜像浅谈

先抛出几个我在学习过程当中产生的几个问题.git

1. 容器镜像是什么和装系统时的镜像有什么关系?github

2. 容器镜像的做用是什么?docker

3. 不一样版本的ubuntu镜像有什么区别好比说 ubuntu:18.04ubuntn:16.04 的区别?shell

4. Docker 镜像为何要分层 每层都包含什么 何时会建立新的一层 ?  每层的权限是如何 配置的只有最底层的镜像层是只读的吗 ?
 

1 Docker镜像之初见

1.1 什么是镜像

      使用docker pull <image name>下载一个镜像看看ubuntu

 

      能够看到咱们仅仅是pull了一个ubuntu18.04的镜像, docker pull的结果却出现了多行这是由于镜像是分红多层的具体为何要分层每一层又是什么下文咱们会谈到.缓存

      因为docker 18.04采用的是overlayfs2做为默认的存储驱动因此下载的镜像都存储在/var/lib/docker/overlay2 .学习

 

     能够看到这里的目录个数和镜像层数是一致而且除了0c开头的那一层其余目录都是有diffwork两个子目录 . 0c开头的目录就是整个镜像最底层的只读层 ui

l目录下所有都是指向这些diff目录的软连接.让咱们进入0c.../diff中看看能够看到在diff目录中是一套完整的根目录因此说本质上根目录就是一个rootfs. this

跟装系统时的镜像没有一点点关系.spa

 

1.2 构建Docker镜像

     本节来讲说如何使用使用Dockerfile构建本身的镜像, dockfile由一系列的命令构成。我目前用过的有FROM RUN CMD ADD COPY命令。

     From用来制定一个基础镜像层。

     RUN命令会在一个新的镜像层上执行参数中所指定的任何命令commit命令的执行结果。

     CMD命令在我初次使用时RUN有所混淆可是其实两者是彻底不一样的, CMD只是指定了运行容器时的初始命令可是在镜像构建时没有commit任何命令的结果。

举例来讲下图是一个Dockerfile. 在其中咱们先在一个新的镜像层建立一个shell脚本而后在CMD中运行这个脚本。

 

 

      能够看到容器执行CMD中指定的命令.

2 镜像的特性

2.1 分层特性

  在咱们使用docker run命令启动一个容器时就会在现有的只读镜像层之上在建立一个可读写的容器层. 当咱们将这些容器删除时这些容器层也会被删除

可是容器层之下的镜像层却不会改变.

 图盗自(docker reference)

 

 

经过这种共享相同的镜像层的方式, 容器即实现了必定的隔离(容器层之间), 又节省了空间.

2.2 写时拷贝(COW)

      若是容器须要读底层的文件或者目录那么直接读取底层的文件可是若是容器须要修改底层的文件那么容器层就会拷贝一个底层的文件.

虽然说都是COW策略可是实现起来不一样的存储驱动也是有所不一样的.

      以overlayfs/overlayfs2为例:

    1. 搜索全部的镜像层找到要修改的文件这个过程从最新的一层直到最底层另外搜索结果会放到缓存中加速下一次的查找。

    2. 执行copy_up操做将文件拷贝到容器层

    3. 修改文件的拷贝同时底层的文件对于容器层是不可见的.

      只说了修改和读取那么当容器层要删除一个镜像层的文件时会发生什么呢让咱们看看。

      先直接在底层镜像层中建立一个文件还记得上文中说到的那个只有diff目录和link文件的目录吗?那个就是最底层的镜像层

咱们直接在diff/tmp/目录中建立一个文件文件名为thisIsAFileCreateImageLayer

      而后运行一个容器进入tmp目录能够看到这个文件对于容器是可见的.

     在容器层删除该文件

 

     在镜像层看看

 

       由上图能够看到在镜像层该文件是依然存在的这是由于在容器层在容器层删除文件或者目录

, overlayfs采用了whiteoutsopaque技术.

      Whiteouts是一个设备号为0/0的字符设备文件当上层目录中发现一个whiteout文件时在上层目录中读取底层的同名的文件时底层的文件就会被忽略.

以下图所示在新建立的容器层中咱们能够看到一个设备号为0,0的字符设备文件.

 

接下来我来尝试解答一下我以前的疑问:

其实前两个问题已经获得了解答, 先说说第三个问题

3. 不一样版本的ubuntu镜像有什么区别好比说 ubuntu:18.04ubuntn:16.04  的区别?

     不一样版本的ubuntu的区别我目前知道的区别是软件库的版本不一样. 

4. Docker 镜像为何要分层 每层都包含什么 何时会建立新的一层 ?  每层的权限是如何 配置的只有最底层的镜像层是只读的吗 ?
     分层实现了空间最小化的隔离, 在运行一个新的容器时会建立一个新的读写层, 在使用Dockerfile构建新的镜像时会在已有的镜像层的基础上建立新的一层.
 

参考

https://docs.docker.com/storage/storagedriver/   //关于docker存储驱动很好的讲解
https://docs.docker.com/engine/reference/builder/#from //关于Dockerfile很好的资料
相关文章
相关标签/搜索