Docker 学习笔记 - Docker的写时复制

前面说了,Docker的容器是一个多层的结构。如果对镜像做history操作,我们可以看见他里面每一次dockerfile的命令都会创建一个新的层次。

[root@ip-172-16-1-4 ec2-user]# docker image history nginx
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
8cf1bfb43ff5        6 days ago          /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B
<missing>           6 days ago          /bin/sh -c #(nop)  STOPSIGNAL SIGTERM           0B
<missing>           6 days ago          /bin/sh -c #(nop)  EXPOSE 80                    0B
<missing>           6 days ago          /bin/sh -c #(nop)  ENTRYPOINT ["/docker-entr…   0B
<missing>           6 days ago          /bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7…   1.04kB
<missing>           6 days ago          /bin/sh -c #(nop) COPY file:1d0a4127e78a26c1…   1.96kB
<missing>           6 days ago          /bin/sh -c #(nop) COPY file:e7e183879c35719c…   1.2kB
<missing>           6 days ago          /bin/sh -c set -x     && addgroup --system -…   63.3MB
<missing>           6 days ago          /bin/sh -c #(nop)  ENV PKG_RELEASE=1~buster     0B
<missing>           6 days ago          /bin/sh -c #(nop)  ENV NJS_VERSION=0.4.2        0B
<missing>           6 days ago          /bin/sh -c #(nop)  ENV NGINX_VERSION=1.19.1     0B
<missing>           6 days ago          /bin/sh -c #(nop)  LABEL maintainer=NGINX Do…   0B
<missing>           6 days ago          /bin/sh -c #(nop)  CMD ["bash"]                 0B
<missing>           6 days ago          /bin/sh -c #(nop) ADD file:6ccb3bbcc69b0d44c…   69.2MB

Docker里面有一个重要的概念叫做 Storage driver,他可以帮助我们实现对容器的分层和读写。目前,docker的默认storage driver 是overlay2。所有的容器相关的文件都保存在/var/lib/docker这个目录下。我们可以看见在overlay2里面有很多不同的文件,注意这些文件和上面的dockerfile的命令并不是一一对应的。

[root@ip-172-16-1-4 ec2-user]# ls /var/lib/docker/overlay2/
12597d435b78d470bed7cf3a4cc7d60691432e74f12c00fd44def7ecf6ab659f       6945f4530a5212bc3a8aa598dc88839d39b763799ccdfbd18a5f04180e3b676e       d1f1bcc388595272f11f4ace02f9e6976dc96fd80cce8216d3626484ba114aad
145e76991ae57691ed94de5dd2ea950ff7b50dc26729605e711cd0f35f275e84       7c4d732c22b84e0df8c0d317df825623958d4eff59055827e6b2c76cbe8b0350       d1f1bcc388595272f11f4ace02f9e6976dc96fd80cce8216d3626484ba114aad-init
16da856b3acb71eea396f529a80cf728d664a4bf3eb042f828cb9651d82e90bf       9b6749a9a76ad9f76d7795ebbf8e47595dada7a06b9126f5d9c6e1084f1d0c02       f089b3fd763c560e1c398c9b432100cea56ad4dae3a6b760de42b45e856ce693
16da856b3acb71eea396f529a80cf728d664a4bf3eb042f828cb9651d82e90bf-init  a60b187ea615a59402ad2fe6687a4dc87f1c037eafea6880167795c6e1b7f900       f089b3fd763c560e1c398c9b432100cea56ad4dae3a6b760de42b45e856ce693-init
658b1eab364b4523a8c7274e9b8a2bdc55095e9bd56dcb697f6456b4064abe66       a60b187ea615a59402ad2fe6687a4dc87f1c037eafea6880167795c6e1b7f900-init  l
658b1eab364b4523a8c7274e9b8a2bdc55095e9bd56dcb697f6456b4064abe66-init  backingFsBlockDev

一个典型的场景如下所示,一个镜像文件里面,里面分了多层,最下面的是基础镜像,这个基础镜像不包括内核文件,执行的时候他会直接调用宿主机的内核,因此他的空间并不大。在基础镜像上面,又分了很多层,每一层代表在dockerfile里面执行的一行命令。这整个镜像文件都是只读的。每个容器通过镜像创建自己的容器层,而容器层是可以读写的,修改的内容他们会保存在自己的目录下面。因此每个容器对自己的修改 不会影响到其他容器。

Docker 学习笔记 - Docker的写时复制

在docker里面,我们通过storage driver来进行所谓的copy on write ( 写时复制)的操作。storage driver有很多种,目前默认的是overlay2

overlay的基本工作原理如下

我们通过镜像创建的容器包括了三层。最下面的是一个只读的镜像层,第二层是容器层,在他上面最上面的容器挂载层。最上层显示的是我们在容器上直接看见的内容,他通过UnionFS,或者说类似软连接的方式,文件的路径指向了容器层或者是镜像层。当我们尝试读取,修改或者创建一个新的文件时,我们总是从上到下进行搜索,如果在容器层找到了,那么就直接打开;如果容器层没有,那就从镜像层打开。如果是一个新建的文档,那么就从镜像层拷贝到容器层,再打开操作。

Docker 学习笔记 - Docker的写时复制

猜你喜欢

转载自blog.51cto.com/beanxyz/2514039
今日推荐