过路的知名喵喵拳大师
教练,我什么都想学

      

 

       Docker和传统虚拟机相比,有轻量化,灵活,但是安全性隔离性更差的特点。

       这个轻量化,灵活,平常我们从整个应用层面上讲,因为Docker把底层的OS给下线了,只保留应用需要的库和组件,所以从隔离机制来讲,安全性也更差。那我们有没有更深入的理解呢,当然是有的。

  

       Docker的所有镜像包(Image)都包含一个叫Dockerfile的文件,我们可以理解Docker镜像和千层蛋糕一样,有一层一层的分层,绝大部分还夹了不同的馅,这些不同层级就是Docker layer——具体表现为,Docker file有特定书写规则,这个文件的每一行都会成为镜像build时的一层。所以我们在pull或者build时,屏幕上显示的,每一行都是不同12位的字母数字组成的,一看就很计算机的无意义字符串,就是Docker随机生成的,Docker Layer的名字。所有Layer层ok了,那么这个千层蛋糕--容器就制作好了,否则我们在image列表就会看到明显是一个半成品的容器。

 

       Docker Layer最上面一层,是我们可以进行改写操作的一层,称之为可写层。除此之外,所有下层的Layer,都是只读层,是不允许我们用户直接进行修改的。所以我们exec进去进行操作的,都是最上面一层可写层。如果我们修改了一个下面只读层的一个文件(只要有权限,在可写层允许任意修改),那么这个只读层文件就会是我们可写层修改的内容。但是呢,原来未修改版本的这个只读层文件还是存在的,就是被隐藏起来了,这即是Docker的“写时复制”的机制。我们设源文件为A,这个修改过的文件为A',在当前这个容器里,退出再进去我们看见的就会是A',但是删除容器,重新用镜像构建,我们看到的就是A。当我们把这个A’删掉以后,源文件A就会出现了。

 

       这个Docker Layer在建立的时候,一般都会显示自己的大小(如几k,几M,几G),有时候很快,我们也很开心!有时候慢呢,我们又很抓狂,好家伙,难道真是我们网络问题,还是被我们嫌弃了一次又一次的外网的锅?其实网络当然有原因,但我们发现有时候具有相同依赖的两个不同镜像文件,即使有时候是几个G的Layer,构建起来也是很快的,这怎么解释,难道有复用?

      对,复用就是存在的,我们自己在Docker file随便加一行,再进行build,和原来的容器就是两个不同的容器,但物理上我们看到的两个不同容器,实际上,下层的只读层除了我们自己魔改的那一行成了一层layer外,两个容器用的是一样的东西,类似于互不干扰的映射关系。这就是我们说为啥Docker轻量级,省空间,但安全性不如传统虚拟机的原因。

 

      两个存在相同Layer的不同容器构建后关系如下图所示,容器1有ABCD四层,容器2有ABC三层。通常状况下,Layer内容相同,可以映射到不同容器需求的相应层级(这里只画了相同层级,实际上映射的层级可以不同),用户在可写层对容器Layer下层的只读层进行操作,但改变的是自己本身可写层的相应文件内容(下图容器1的A’和容器2的C’),不同容器内的映射的只读层原始内容,容器2的A和容器1的C的内容并不会跟着改变,除非用户进容器地下对他们进行改动操作。Layer内容不同,如下图容器1的D,就会直接成为容器1的layer,容器2则没有。

 

        说到这里是不是明确了很多,我们在构建产生错误的情况下,尤其是BUILD某一层总是出错的情况下,我们可以检查一下Docker file内对应那一层有啥毛病,要是真是要在网上下什么东西,我们可以直接在网上找这个资源的Docker镜像包自己先下载再在本地构建,这样容器的建立就顺畅很多。

 

posted on 2021-06-07 00:16  过路的知名喵喵拳大师  阅读(1831)  评论(0编辑  收藏  举报