什么是docker的写时复制(CoW)?有什么作用?


问题一个问题:docker CoW你知道是什么吗?

 

1、什么是CoW?

 

CoW = Copy-On-Write

 

也就是,你经常会听到的一个词,叫做:写时复制

 

那么,到底什么是写时复制,究竟有什么样的作用呢?

 

2、CoW有什么作用?

 

下面的部分,咱们就逐一进行揭晓:

 

首先,写时复制策略,是一种共享、拷贝文件的方法,用以最大化的提高效率。我们都知道,镜像是以多层的的方式存在的,如果有一个文件,在镜像的较低层中已经存在了,当其他的层需要读取这个文件的时候,就只是使用这个已经存在的文件。

 

是不是,听着有点懵,没关系,我们接着看:当第一次,另外的一个层需要修改这个文件的时候(构建镜像和运行容器的场景),在较低层中的文件被拷贝到这个需要的层,然后进行修改。简单来说,就是需要修改哪个文件,就拷贝哪个文件,然后进行修改,这样在构建或者运行容器,修改文件时,就最小化了拷贝的I/O的大小。同时,后面的层,无论是容器的可写层,还是镜像层的大小也将保持比较小的大小。

 

3、CoW的好处?

 

下面的部分,我们更加详细的解释,CoW策略的好处:

 

3.1、共享镜像层减少镜像的大小

 

先说第一个最大的好处:共享的好处,减少镜像的大小

 

当通过docker pull命令从镜像仓库拉取镜像,当本地没有这个镜像的时候,镜像的每一层都会被单独的拉取下来,然后存储到docker所在主机的存储目录中。

 

镜像的每一层都存储在自己的目录中,这些目录在docker宿主机的本地存储区域中(比如某个目录下,一般/var/lib/docker/<存储驱动>,当然可以修改目录的地址)。

 

假如,有2个Dockerfile,第一个创建一个镜像,名字:acme/my-base-image:1.0

 

# syntax=docker/dockerfile:1
FROM alpine
RUN apk add --no-cache bash

 

第2个镜像,基于这个镜像(from),然后,增加了一些额外的层

 

# syntax=docker/dockerfile:1
FROM acme/my-base-image:1.0
COPY . /app
RUN chmod +x /app/hello.sh
CMD /app/hello.sh

 

第2个镜像包含了第1个镜像的所有的层,然后增加了一些其他的层。

 

由于docker在构建第1个镜像的时候,已经有了所有的层,所以呢,就不需要再次的拉取这些层。简单来说,就是这2个镜像在某些层上是共用的

 

如果通过以上的2个Dockerfile来构建镜像,可以使用dokcer images 和 docker image history 命令看到,这些共享层的加密ID是相同的。

 

并且,共享的镜像的层,在docker的存储目录中,只有一份。同时呢,即使在向镜像仓库推送、存储的时候,也仅仅是存储一份,也是共享的。共享镜像层,也减少网络贷款和存储空间的大小。

 

3.2、复制使容器更高效

我们都知道,当启动一个容器的时候,会在所有的层上面增加一个可写的容器层。容器对于文件系统的任何的修改,都存储在这个层里面。最重要的,任何容器不会修改的文件,都不会被拷贝到这个可写层中来。也就是说,可写层会尽可能的小。

 

当需要在容器中对一个已经存在文件做修改时,存储驱动会执行一个写时拷贝的动作。具体的步骤如下(针对overlay2存储驱动):

 

  • 在镜像层中搜索该文件的最新版本。整个的搜索文件的过程,先从最上层,也就是最新的层开始,然后一直到最基础的层,每次只搜搜一层(当然,前提是当前层,没有找到)。当这个文件被找到的时候,会将这个文件加载到缓存中,为后续的操作做好准备。

 

  • 将文件拷贝到容器的可写层

 

  • 所有的修改,都是在这个文件的拷贝上执行的,容器无法看到存在于底层的只读状态的文件的拷贝。也就是说,对于容器来说,不管底层的文件的,只是对需要的文件的副本进行修改。

 

记住,对于容器来说,那些需要写大量数据的容器会消耗比较大的空间。因为,当进行写的操作的时候,会消耗容器的可写层的空间。

 

注意:修改文件的元数据(比如文件的权限,所有者),同样会执行拷贝的动作,因此,也会将文件拷贝到可写层。

 

注意,注意!文件的拷贝的操作是有性能的开销的。对于大文件,多镜像层,多级的目录树来说,这样的影响会比较显著

 

所以,简单来说,只是在可写层,对需要的文件进行拷贝,也减少了容器层的大小。

 

同时,对于容器的启动来说,仅仅是执行命令即可,减少容器的启动时间。

 

4、总结

 

我们来总结一下,CoW是什么,好处是什么?

 

CoW(Copy On Write):写时复制

 

好处:

 

  • 共享镜像层,减少镜像大小、占用存储空间大小
  • 减少容器大小
  • 减少容器的启动时间
  • 当多个容器使用相同镜像时,只需创建可写层

 

对比:

 

如果Docker每次创建一个新容器时都必须对底层映像堆栈进行完整的复制,那么容器创建时间和磁盘空间的使用将会显著增加。这类似于虚拟机的工作方式,每个虚拟机有一个或多个虚拟磁盘。

 

 

 

 

 

 

posted @ 2022-08-22 11:30  Zhai_David  阅读(1073)  评论(0编辑  收藏  举报