6. Docker——详说镜像

news2024/9/29 19:30:23

本章讲解知识点

    1. Docker 镜像
    1. Union File System(联合文件系统)技术
    1. 回说 Docker 镜像分层
    1. Docker 镜像分层原理


1. Docker 镜像

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时的库、环境变量和配置文件

镜像是一个只读模板,带有创建 Docker 容器的说明。通常,一个镜像基于另一个镜像,并带有一些额外的定制。例如,可以构建一个基于 ubuntu 镜像的镜像,安装 Apache web 服务器和自己的应用程序,以及运行应用程序所需的配置细节,最终服务运行或项目运行都是在容器中的。

我们可以从开源镜像仓库里拉取镜像,我们在拉取镜像时,会发现 Docker 给我们的回显中,镜像似乎是分很多层的:

[root@master mtuser]# docker pull quay.io/coreos/flannel:v0.14.0

v0.14.0: Pulling from coreos/flannel
801bfaa63ef2: Pull complete
e4264a7179f6: Pull complete
bc75ea45ad2e: Pull complete
78648579d12a: Pull complete
3393447261e4: Pull complete
071b96dd834b: Pull complete
4de2f0468a91: Pull complete
Digest: sha256:4a330b2f2e74046e493b2edc30d61fdebbdddaaedcb32d62736f25be8d3c64d5
Status: Downloaded newer image for quay.io/coreos/flannel:v0.14.0
quay.io/coreos/flannel:v0.14.0

这是一个很有意思的现象,因为它引出了容器领域十分重要的技术:Union File System(联合文件系统)技术。正是Union File System(联合文件系统)技术的利用,容器技术才得以大行其道。


2. Union File System(联合文件系统)技术

联合文件系统(Union File System)是一种将多个文件系统挂载到同一目录下的技术,使得这些文件系统中的内容可以像一个文件系统一样被访问。在联合文件系统中,多个不同的文件系统以层次结构的形式被组织在一起,从而使得用户可以通过单一的挂载点来访问多个不同的文件系统。

联合文件系统的实现通常使用一些特殊的技术,比如链接(Link)和重定向(Redirect)。具体来说,联合文件系统使用链接技术将多个不同的文件系统的内容组合在一起,从而实现了文件系统的叠加。在联合文件系统中,每个文件系统都有一个挂载点,通过在这个挂载点上叠加其他的文件系统,就可以将它们的内容融合在一起。而重定向技术则用于实现对文件和目录的访问,使得用户可以在联合文件系统中访问多个不同文件系统的内容,同时还能够自由地添加、删除或更改这些文件系统中的文件和目录。

联合文件系统的优点包括可以将多个不同的文件系统整合在一起,从而方便用户管理和访问这些文件系统中的内容;可以在不同的文件系统之间共享文件和目录;可以根据需要动态地添加、删除和更改文件系统,从而提高了系统的灵活性。不过,联合文件系统的缺点也很明显,其中包括可能会导致性能下降、出现一些安全问题,以及需要特殊的文件系统支持等问题。

联合文件系统可以把只读和可读写文件系统合并在一起,具有 Copy-on-Write 功能,允许只读文件系统的修改可以保存到可写文件系统当中。

假设有两个文件系统:A 和 B,其中 A 包含文件 /A/foo 和目录 /A/bar,B 包含文件 /B/bar 和目录 /B/foo。使用联合文件系统技术可以将这两个文件系统合并成一个单独的文件系统 C。具体操作如下:

创建一个目录 /C,作为联合文件系统的挂载点。

将文件系统 A 挂载到 /C 上,使得文件 /A/foo 和目录 /A/bar 可以在 /C 目录下访问。

将文件系统 B 挂载到 /C 上,由于 /C 目录已经被 A 挂载,因此 B 将被挂载到 /C 目录下的一个新的子目录,比如 /C/B

现在,/C 目录下的内容将包括 A 和 B 两个文件系统的内容。因此,用户可以通过 /C/foo 访问文件 /A/foo,通过 /C/bar 访问目录 /A/bar,通过 /C/B/bar 访问文件 /B/bar,通过 /C/B/foo 访问目录 /B/foo


3. 回说 Docker 镜像分层

3.1. 基础概念

联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像,可以制作各种具体的应用镜像

Docker 镜像是由多个分层(layers)组成的,每个分层都包含了文件系统的一部分。这种分层的设计使得 Docker 镜像非常轻量级,因为多个镜像可以共享相同的分层。当一个新的镜像被创建时,Docker 只需要为新镜像添加一些额外的分层,而不是重新创建整个文件系统

每个 Docker 镜像都由一个或多个分层组成,这些分层从基础镜像开始,一步步地添加文件系统的修改。每个分层都有一个唯一的 ID,并且可以在其他镜像中被共享。当你启动一个容器时,Docker 会将这个容器的文件系统组合成一个只读的联合文件系统,其中包含了容器所使用的所有分层。这种方式可以让容器在启动时非常快速地创建。

联合文件系统一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

3.2. 基础镜像

在 Docker 中,基础镜像是构建其他镜像的起点。基础镜像是一个包含操作系统和一些最基本软件包的最小镜像。它提供了一个最小的运行环境,使得应用程序可以在 Docker 容器中运行

基础镜像可以由用户自己创建,也可以从 Docker Hub 或其他 Docker 镜像仓库中获取。例如,一个常见的基础镜像是 ubuntu,它提供了一个基于 Ubuntu 操作系统的最小环境。在此基础镜像上,用户可以构建自己的应用程序或服务的镜像,添加所需的软件包和配置文件。

使用基础镜像的好处是可以减少构建镜像的时间和大小,因为基础镜像已经提供了必要的操作系统和软件包。此外,基础镜像通常已经经过了优化和测试,可以提供更高的稳定性和安全性。

3.3 镜像的内核与发行版

我们之前创建虚拟机时用到的 ISO 镜像文件来安装操作系统,它包含了两个部分:

在这里插入图片描述

1.Linux 内核版本:

[root@node1 docker]# uname -r
3.10.0-1160.el7.x86_64

2.系统发行版本(Ubuntu、CentOS)

[root@node1 docker]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

而 Docker 镜像则不一样,它不包含 Linux 内核,只是系统发行版本:

[root@node1 docker]# docker images  | grep centos
centos                                                   latest        5d0da3dc9764   18 months ago   231MB

从它们的文件大小也可能看出 ISO 镜像文件和 Docker 镜像的差别。

所以 Docker 基础镜像不包含 Linux 内核,而是共享主机操作系统的 Linux 内核,这是一个很重要的结论

3.4 内核空间和用户空间的文件系统

Linux 操作系统由内核空间和用户空间组成。

  1. 内核空间是 kernel,Linux 刚启动时会加载 bootfs 文件系统,之后 bootfs 会被卸载掉。
  2. 用户空间是 rootfs 文件系统,包含我们熟悉的 /dev, /proc, /bin 等目录。

在这里插入图片描述

对于基础镜像来说,底层直接共享主机操作系统的 Linux 内核,自己只需要提供 rootfs 就行了。而对于一个精简的 OS,rootfs 可以很小,只需要包括最基本的命令、工具和程序库就可以了。基础镜像提供的是最小安装的 Linux 发行版。

然后利用联合文件系统技术,就等于将 bootfs 文件系统rootfs 文件系统叠加起来利用了。


4. Docker 镜像分层原理

4.1 基本原理

Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。比如我们现在构建一个新的镜像,Dockerfile 如下:

# Version: 0.0.1
FROM debian               1.新镜像是从 Debian base 镜像上构建。
RUN apt-get update && apt-get install -y emacs        2.安装 emacs 编辑器。
RUN apt-get install -y apache2             3.安装 apache2。
CMD ["/bin/bash"]              4.容器启动时运行 bash。

在这里插入图片描述

可以看到,Docker 镜像都起始于一个基础镜像层,新镜像是从基础镜像一层一层叠加生成的。当进行修改或增加新的内容时,就会在当前镜像层上,创建新的镜像层

4.2 为什么要镜像分层

Docker 采用镜像分层的机制,主要是为了提高镜像的可重复性和可维护性,同时也能节省存储空间。具体来说,镜像分层可以实现以下几点:

  1. 减少存储空间:Docker 镜像的每一层都是只读的,只有最上层的容器层可以被写入。这意味着多个镜像可以共享相同的底层镜像层,从而减少存储空间。

  2. 支持版本控制:每一个镜像层都可以被认为是一个单独的版本,这使得镜像可以进行版本控制和管理,方便维护和升级。

  3. 提高可重复性:每个容器都可以由多个层次构成,这使得容器的创建和销毁变得更加灵活。镜像分层也可以确保容器的可重复性,因为每个容器都可以使用相同的基础镜像层和组件。

  4. 支持增量更新:由于每个镜像层都是只读的,更新镜像时只需要对需要更新的层进行修改,而不需要重新构建整个镜像,这提高了镜像的更新效率。

4.3 容器 Copy-on-Write(COW) 特性

容器 Copy-on-Write (COW) 特性是 Docker 中非常重要的一个特性。它的作用是让容器创建时尽可能地复用镜像层,从而节省存储空间并提高容器的创建速度。

当一个容器启动时,Docker 会创建一个容器层作为容器的可写层,并将该容器层与镜像层进行联合挂载。在容器运行时,所有的写操作都会被记录到容器层中,而不会对镜像层进行任何修改。因此,如果多个容器都使用同一个镜像,它们会共享相同的镜像层,而容器层则会针对每个容器单独记录写入操作。这种方式可以避免重复复制相同的数据,从而提高存储效率,并且能够更快地启动新的容器。

当容器层中的文件被修改时,Docker 会使用 Copy-on-Write (COW) 技术来创建新的文件副本,而不是在原始镜像层上直接修改文件。这意味着对文件的修改不会影响其他容器或镜像的使用,同时也能够更好地支持多个容器同时使用同一个镜像的场景。

4.4 可写的容器层

Docker 镜像都是只读的,当你创建一个新的容器时,你会在基础层之上添加一个新的可写层,该层通常都称为容器层

对正在运行的容器所做的所有更改,例如写入新文件、修改现有文件和删除文件,都被写入这个可写的容器层

在这里插入图片描述

在容器运行时,所有的写操作都会被记录到容器层中,而不会对镜像层进行任何修改,其余的镜像层都是只读的。

对容器层文件的操作规则:

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

4.5 小示例

1.查看 flannel 镜像

[root@node1 docker]# docker images | grep flan
quay.io/coreos/flannel                                   v0.14.0       8522d622299c   22 months ago   67.9MB

2.查看 flannel 镜像分层

[root@node1 docker]# docker inspect 8522d622299c | grep "RootFS" -A 12
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:777b2c648970480f50f5b4d0af8f9a8ea798eea43dbcf40ce4a8c7118736bdcf",
                "sha256:815dff9e0b5742e2a1b9c06fc748a4181a349d638bd4d66e5072df83f5fba336",
                "sha256:2e16188127c8c7ccc2d27f3ecb0c9de6ce109fbaeb3600d060a52b024dbabcc2",
                "sha256:eb738177d102ee90366379b7a67d6f8005b24d28a7049156f4c12da0c7321480",
                "sha256:b613d890216ce3ba102eb169e30d768aefcb0536f95fc60812d9566aac64ce78",
                "sha256:8a984b390686f05792e045c24dc98042be50334e94fb46990fed1646f52d3399",
                "sha256:814fbd599e1fb4f5a522ffedff9f9dfee491e3b566c1a550dfdf908e04c9bc3d"
            ]
        },

3.进入 /var/lib/docker/image/overlay2/layerdb/sha256 目录查看分层

[root@node1 sha256]# ll | grep 777b2c648970480f50f5b4d0af8f9a8ea798eea43dbcf40ce4a8c7118736bdcf
drwx------. 2 root root 71 Feb 19 01:20 777b2c648970480f50f5b4d0af8f9a8ea798eea43dbcf40ce4a8c7118736bdcf
[root@node1 sha256]# ll | grep 815dff9e0b5742e2a1b9c06fc748a4181a349d638bd4d66e5072df83f5fba336
[root@node1 sha256]# ll | grep 2e16188127c8c7ccc2d27f3ecb0c9de6ce109fbaeb3600d060a52b024dbabcc2
[root@node1 sha256]# ll | grep eb738177d102ee90366379b7a67d6f8005b24d28a7049156f4c12da0c7321480
[root@node1 sha256]# ll | grep b613d890216ce3ba102eb169e30d768aefcb0536f95fc60812d9566aac64ce78
[root@node1 sha256]# ll | grep 8a984b390686f05792e045c24dc98042be50334e94fb46990fed1646f52d3399
[root@node1 sha256]# ll | grep 814fbd599e1fb4f5a522ffedff9f9dfee491e3b566c1a550dfdf908e04c9bc3d

除了 777b2c648970480f50f5b4d0af8f9a8ea798eea43dbcf40ce4a8c7118736bdcf 以外,其他分层在其他目录下。我们来找找

4.利用 find 命令找寻其他分层的位置

[root@node1 sha256]# find / -name 815dff9e0b5742e2a1b9c06fc748a4181a349d638bd4d66e5072df83f5fba336
/var/lib/docker/image/overlay2/distribution/v2metadata-by-diffid/sha256/815dff9e0b5742e2a1b9c06fc748a4181a349d638bd4d66e5072df83f5fba336
[root@node1 sha256]# find / -name 2e16188127c8c7ccc2d27f3ecb0c9de6ce109fbaeb3600d060a52b024dbabcc2
/var/lib/docker/image/overlay2/distribution/v2metadata-by-diffid/sha256/2e16188127c8c7ccc2d27f3ecb0c9de6ce109fbaeb3600d060a52b024dbabcc2
[root@node1 sha256]# find / -name eb738177d102ee90366379b7a67d6f8005b24d28a7049156f4c12da0c7321480
/var/lib/docker/image/overlay2/distribution/v2metadata-by-diffid/sha256/eb738177d102ee90366379b7a67d6f8005b24d28a7049156f4c12da0c7321480
[root@node1 sha256]# find / -name b613d890216ce3ba102eb169e30d768aefcb0536f95fc60812d9566aac64ce78
/var/lib/docker/image/overlay2/distribution/v2metadata-by-diffid/sha256/b613d890216ce3ba102eb169e30d768aefcb0536f95fc60812d9566aac64ce78
[root@node1 sha256]# find / -name 8a984b390686f05792e045c24dc98042be50334e94fb46990fed1646f52d3399
/var/lib/docker/image/overlay2/distribution/v2metadata-by-diffid/sha256/8a984b390686f05792e045c24dc98042be50334e94fb46990fed1646f52d3399
[root@node1 sha256]# find / -name 814fbd599e1fb4f5a522ffedff9f9dfee491e3b566c1a550dfdf908e04c9bc3d
/var/lib/docker/image/overlay2/distribution/v2metadata-by-diffid/sha256/814fbd599e1fb4f5a522ffedff9f9dfee491e3b566c1a550dfdf908e04c9bc3d

可以看到,其他分层在另外的目录下,你看,利用 UFS 联合文件系统将不同位置的分层合并成了一个镜像文件,是不是很有意思。

5.用 docker history 查看镜像分层

[root@node1 mtuser]# docker history quay.io/coreos/flannel:v0.14.0 --no-trunc > text

IMAGE                                                                     CREATED         CREATED BY                                                                                                           SIZE      COMMENT
sha256:8522d622299ca431311ac69992419c956fbaca6fa8289c76810c9399d17c69de   22 months ago   /bin/sh -c #(nop)  ENTRYPOINT ["/opt/bin/flanneld"]                                                                  0B
<missing>                                                                 22 months ago   /bin/sh -c /iptables-wrapper-installer.sh                                                                            1.93kB
<missing>                                                                 22 months ago   /bin/sh -c #(nop) COPY file:1a43b192bfd032f1dbb35156e5e82a505618eb82ae8dd58b3cdec45882d7e102 in /                    7.66kB
<missing>                                                                 22 months ago   /bin/sh -c #(nop) COPY file:8f67962c12e58671bee18c93535885714647b91271193b7dc5832188905ec9d1 in /opt/bin/            2.14kB
<missing>                                                                 22 months ago   /bin/sh -c #(nop) COPY file:d4fe84b0a6b8e73f9c28b314a51706f4a65ab0fde83db87b000ba72e6efbacf6 in /opt/bin/flanneld    49.3MB
<missing>                                                                 2 years ago     /bin/sh -c apk add wireguard-tools --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/community       2.18MB
<missing>                                                                 2 years ago     /bin/sh -c apk add --no-cache iproute2 net-tools ca-certificates iptables strongswan && update-ca-certificates       10.8MB
<missing>                                                                 2 years ago     /bin/sh -c #(nop)  ENV FLANNEL_ARCH=amd64                                                                            0B
<missing>                                                                 2 years ago     /bin/sh -c #(nop)  LABEL maintainer=Tom Denham <tom@tigera.io>                                                       0B
<missing>                                                                 2 years ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]                                                                                   0B
<missing>                                                                 2 years ago     /bin/sh -c #(nop) ADD file:ec475c2abb2d46435286b5ae5efacf5b50b1a9e3b6293b69db3c0172b5b9658b in /                     5.58MB

flannel 的镜像分层就是通过上面的命令一层一层叠加的。



面试题

1. 什么是 Docker 镜像分层?⭐⭐⭐⭐

Docker 将一个 Docker 镜像分解成多个不同的层(Layer),每个层都是只读的文件系统,层与层之间是相互独立的。这种分层的设计可以提高 Docker 镜像的复用性和共享性。每个 Docker 镜像都是由一个或多个只读层(镜像层)和一个可读写层(容器层)组成。只读层是可以在不同镜像之间共享的,因此 Docker 的镜像可以通过利用这种分层的设计来尽可能地减少重复的数据存储,提高镜像的复用性。同时,Docker 镜像分层的设计还可以方便地管理和维护镜像。例如,在更新镜像时,只需要修改镜像的某个层,而不需要对整个镜像重新构建,从而节省了时间和资源。

2. Docker 镜像分层的优势是什么?⭐⭐⭐⭐

  1. 减小镜像大小:因为每个层都是只读的,所以在创建新镜像时,只需要新增或修改一层即可,不会影响到已有的层,从而减小了镜像的大小。同时,不同的镜像可以共享相同的层,从而减少了重复的数据存储,进一步减小了镜像的大小。

  2. 提高镜像的复用性:由于Docker镜像分层的设计,不同的镜像可以共享相同的层,这就使得镜像的复用性得到了极大地提高。例如,当多个容器需要使用同一份镜像时,它们可以共享相同的只读层,这样就可以节省存储空间,并且不需要重复下载和构建镜像。

  3. 方便镜像的管理和维护:由于每个层都可以单独更新和管理,因此 Docker 镜像的管理和维护变得更加容易。例如,在更新镜像时,只需要修改镜像的某个层,而不需要对整个镜像重新构建,这样就可以节省时间和资源,并且降低出错的风险。

  4. 提高镜像的构建效率:利用 Docker 镜像分层的特性,可以将常用的层缓存下来,从而减少重复的构建过程,加快镜像构建的速度。同时,通过多阶段构建的方式,将构建过程拆分成多个阶段,每个阶段都可以利用不同的Docker镜像分层,从而进一步提高构建速度。

3. Docker 镜像的分层是如何实现的?⭐⭐⭐⭐

Docker 镜像分层的实现是通过 UFS(Union File System)联合文件系统来实现的。联合文件系统(Union File System)是一种将多个文件系统挂载到同一目录下的技术,使得这些文件系统中的内容可以像一个文件系统一样被访问。在联合文件系统中,多个不同的文件系统以层次结构的形式被组织在一起,从而使得用户可以通过单一的挂载点来访问多个不同的文件系统。

在 Docker 中,每个镜像都是由多个只读层(镜像层)和一个可读写层(容器层)组成。Docker 通过 UFS 联合文件系统将这些只读层和可读写层合并在一起,形成一个联合文件系统。

4. 如何利用 Docker 镜像分层优化镜像构建过程?⭐⭐⭐

利用 Docker 镜像分层优化镜像构建过程可以从以下几个方面入手:

  1. 利用缓存:在构建 Docker 镜像时,Docker 会利用缓存来避免重复的构建过程。如果某个镜像层已经被构建过,Docker 就可以直接从缓存中获取该层,从而加快构建速度。因此,为了利用缓存,我们应该尽量减少构建过程中的变化,例如在 Dockerfile 中将不经常修改的指令放在前面,将经常修改的指令放在后面。

  2. 利用多阶段构建:Docker 从 17.05 版本开始支持多阶段构建。利用多阶段构建,可以将构建过程拆分成多个阶段,并在每个阶段中利用不同的 Docker 镜像分层,从而减少重复的构建过程。

  3. 选择合适的基础镜像:选择合适的基础镜像可以减少构建过程中的变化,从而提高构建速度。通常情况下,我们应该选择官方的基础镜像,因为官方的基础镜像已经被优化过,同时也得到了广泛的测试和验证。

  4. 减小镜像大小:减小镜像大小可以加快构建速度,同时也可以减少存储空间的占用。为了减小镜像大小,我们可以采用一些常用的优化技巧,例如将多个指令合并成一个、使用多阶段构建、删除无用文件和缓存等。

5. 镜像层是可写的吗?怎么实现可写⭐⭐⭐⭐

Docker 镜像层是只读的,这是为了保证镜像的不可变性,也就是说,一个镜像被创建之后,它的每一层都是只读的,不能被修改。这样可以保证每个容器都以相同的镜像层为基础,从而保证容器之间的环境一致性。

然而,在有些情况下,我们需要对容器进行一些修改,例如安装软件、修改配置文件等。此时,我们可以通过在容器层上创建一个新的可写层来实现这个目的。Docker 中的可写层也称为容器层(container layer)或工作层(working layer),它是在只读的镜像层之上创建的一个可写层。

当我们启动一个容器时,Docker 会在镜像层之上创建一个可写层,并将这个可写层挂载到容器的文件系统中。容器层中的所有修改都将保存在这个可写层中,而镜像层则保持不变。这样,即使多个容器都使用同一个镜像,它们之间也可以有不同的可写层。

6. Docker 中基础镜像的作用⭐⭐⭐⭐

Docker 中基础镜像是用来构建 Docker 镜像的基础,也是构建整个 Docker 镜像的起点。它是一个只读的文件系统,包含了一些基本的操作系统和软件组件,例如操作系统内核、文件系统、运行时环境、库文件、工具等。

使用基础镜像可以避免从头开始构建 Docker 镜像,从而节省时间和精力。基础镜像已经被优化过,并且得到了广泛的测试和验证,因此可以保证镜像的稳定性和可靠性。

7. 容器层删除文件时,文件本体会被删除吗?⭐⭐⭐⭐

当容器层中的文件被删除时,文件本体不会被删除,因为容器层是一个可写层,它是在只读的镜像层之上创建的一个可写层,容器层中的所有修改都将保存在这个可写层中,而镜像层则保持不变。因此,当容器中的文件被删除时,实际上是删除了容器层中的文件记录,而不是删除了镜像层中的文件本体。

8. centos 镜像几个 G,但是 docker centos 镜像才几百 M,这是为什么?⭐⭐⭐⭐

这是因为 CentOS 镜像是完整的操作系统镜像,包含了所有的软件包和文件,而 Docker 镜像则是基于操作系统的一层层的增量更新,每一层都只包含一个或几个操作,可以共用基础镜像,因此其大小较小。

9. 讲一下镜像的分层结构以及为什么要使用镜像的分层结构?⭐⭐⭐⭐

一个新的镜像其实是从基础镜像一层一层叠加生成的。每安装一个软件,dockerfile 中使用 RUM 命令,就会在现有镜像的基础上增加一层,这样一层一层的叠加最后构成整个镜像。

分层结构最大的一个好处就是:共享资源。比如:有多个镜像都从相同的基础镜像构建而来,那么只需在磁盘上保存一份基础镜像;同时内存中也只需加载一份基础镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

10. 说说容器 Copy-on-Write(COW) 特性⭐⭐⭐⭐

容器 Copy-on-Write (COW) 特性是 Docker 中非常重要的一个特性。它的作用是让容器创建时尽可能地复用镜像层,从而节省存储空间并提高容器的创建速度。

当一个容器启动时,Docker 会创建一个容器层作为容器的可写层,并将该容器层与镜像层进行联合挂载。在容器运行时,所有的写操作都会被记录到容器层中,而不会对镜像层进行任何修改。因此,如果多个容器都使用同一个镜像,它们会共享相同的镜像层,而容器层则会针对每个容器单独记录写入操作。这种方式可以避免重复复制相同的数据,从而提高存储效率,并且能够更快地启动新的容器。

当容器层中的文件被修改时,Docker 会使用 Copy-on-Write (COW) 技术来创建新的文件副本,而不是在原始镜像层上直接修改文件。这意味着对文件的修改不会影响其他容器或镜像的使用,同时也能够更好地支持多个容器同时使用同一个镜像的场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/485968.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文了解 Zebec Labs 投资的 Coral Finance,空投计划或在不久推出

在前不久&#xff0c;Zebec Labs 宣布对链上衍生品协议 Coral Finance 进行150万美元的投资&#xff0c;以帮助该协议完成早期启动并&#xff0c;并在后续持续的为其提供孵化支持。Coral Finance 将在不久部署在 Nautilus Chain 主网上。据了解&#xff0c;Coral Finance 是 Na…

【VM服务管家】VM4.2平台SDK_6.2 模块操作类

目录 2.2.1 流程操作&#xff1a;通过流程或Group设置输入输出图像的方法2.2.2 模块操作&#xff1a;设置输入图像、参数和ROI2.2.3 N点标定&#xff1a;清空标定点、生成标定文件2.2.4 分支字符&#xff1a;控制调试模式开关的方法2.2.5 条件检测&#xff1a;条件检测模块设置…

【GAMES101】02 Review Of Linear Algebra

1.点乘&#xff1a; 向量点乘 → 一个数值 点乘在图形学中的应用&#xff1a; 找到两个方向之间的夹角。找到一个向量投影到另一个向量上是什么样的。计算两个向量的方向&#xff08;是接近还是远离&#xff09;判定高光范围&#xff0c;从1&#xff08;重合&#xff…

【VM服务管家】VM4.2平台SDK_6.5 全局类

目录 2.5.1 全局相机&#xff1a;获取全局相机列表和设置相机参数的方法 2.5.1 全局相机&#xff1a;获取全局相机列表和设置相机参数的方法 描述 环境&#xff1a;VM4.2 VS2013及以上 问题&#xff1a;问题1&#xff1a;如何获取方案中所有的全局相机的连接状态&#xff0c;…

c++基础-分支语句

目录 if语句 if-else switch语句 if语句 在C中&#xff0c;if语句是一种分支结构&#xff0c;它允许程序根据条件执行不同的操作。可以使用if语句来检查一个条件是否为真&#xff0c;如果为真就执行一个语句块&#xff0c;否则执行另一个语句块。 if语句的语法如下&#xff…

自媒体平台图文创作建议和技巧

自媒体博主在自媒体平台进行图文创作时&#xff0c;需要注意哪些方面才能创造出更好的内容获得更多的关注呢&#xff1f;今天跟大家分享自媒体创作中的一些图文创作建议和技巧。 一、确定目标受众 首先需要明确自己要传达的信息和目标受众。要考虑读者的兴趣、需求和阅读习惯&…

2001-2021年全国30省就业人数数据

2001-2021年全国30省就业人数数据/各省就业人数数据 1、时间&#xff1a;2001-2021年 2、范围&#xff1a;包括30个省市不含西藏 3、指标&#xff1a;就业人数 4、来源&#xff1a;各省NJ、社会统计NJ 5、缺失情况说明&#xff1a;无缺失 6、指标说明&#xff1a; 就业人…

【Python入门】人生苦短,我用Python

前言 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于Python零基础入门系列&#xff0c;本专栏主要内容为Python基础语法、判断、循环语句、函…

10万字城市大脑一网统管分析平台及大数据平台建设方案(WORD)

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除。 一.1.1.督查监管子系统 督察监管子系统是指通过独立的督察队伍&#xff0c;以日常督察、专项督察的方式&#xff0c;来检查运行效果。根据工作进度&#xff0c;工作中存在的…

【无人车】无人驾驶地面车辆避障研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

ChatGPT常见问题及其解决方法汇总

好久没有更新过技术类的文章了&#xff0c;希望本篇文章能够对你有所帮助&#xff0c;今天这篇博客将会把ChatGPT注册中可能遇到的问题彻头彻尾的讲一下&#xff0c;创作不易&#xff0c;如果感觉有帮助的话就动动你发财的小手点个收藏点个赞吧。如有需要转载请附上原文链接&am…

mysql5.7以上的启动、停止、赋权命令

文章目录 1、启动mysql server2、查看初始密码3、本地登陆mysql4、修改本地root用户密码5、防火墙设置6、开启mysql的远程登录 1、启动mysql server systemctl start mysqld #启动程序 systemctl enable mysqld #开机自运行 systemctl status mysqld #查看状态…

浅谈WebGIS未来应用与技术发展趋势

前言 WebGIS&#xff08;Web GIS&#xff09;是一种基于Web的地理信息系统&#xff0c;它可以实现地理空间数据的查询、分析、管理和可视化。与传统的 GIS 相比&#xff0c;WebGIS 是通过浏览器实现客户端与服务器间的信息交流&#xff0c;成本降低&#xff0c;且界面友好&…

No.046<软考>《(高项)备考大全》【专项2】《案例分析 - 计算题(上)》

《&#xff08;高项&#xff09;备考大全》【专项2】《案例分析 - 计算题》 1 题型全部概况2 时间管理2.1 关键路径法 CMP2.1.1 原理2.1.2 关键路径的基本问题2.1.3 题目7、题目6 - 正推、反推8、题目7 2.2 PERT&#xff08;计划评审技术&#xff09;2.3 活动排序网络图 3 成本…

CesiumForUnreal、UE5实现限高分析效果

文章目录 1.实现目标2.实现过程2.1 材质2.2 Widget2.3 运行测试3.参考资料1.实现目标 在UE5中基于CesiumForUnreal插件实现简单GIS分析功能中的限高分析效果,GIF动图如下: 2.实现过程 实现限高分析功能的方法可以大致分为两种,一种是修改3DTileset的材质;另一种是基于贴花…

gitee同一台电脑使用多个账号的问题

官方文档&#xff1a;https://gitee.com/help/articles/4238#article-header0 目录 一、通过 https / ssh 协议推拉代码二、通过 https 推拉代码但是存在多个账号的问题三、通过 ssh 推拉代码四、Git配置多个SSH-Key五、TortoiseGit客户端 一、通过 https / ssh 协议推拉代码 …

Eplan 部件库导入部件的方法

1. 部件宏文件如何下载 1.1 西门子部件宏文件下载 EPLAN 的部件库是可以更新的,一般元器件厂商会提供其部件文件,以 SIEMENS 为例 进入网站,点击EPLAN 的图标 https://www.automation.siemens.com/bilddb/index.aspx?lang=en 在订货号中输入所需部件订货号,点击搜索。点…

超快速搭建Vue3 + Vite + Cesium 开发环境

发现一个大神写的插件&#xff0c;使用非常方便 GitHub - nshen/create-cesium: &#x1f30f; Create blazing fast Cesium apps with no configuration.&#x1f30f; Create blazing fast Cesium apps with no configuration. - GitHub - nshen/create-cesium: &#x1f30…

leetcode刷题之有关树的算法

144.二叉树的前序遍历 方法一:递归 var preorderTraversal function(root) {let arr []const preorder root >{//递归的出口if(rootnull){return}arr.push(root.val)preorder(root.left)preorder(root.right)}preorder(root)return arr };方法二&#xff1a;迭代 使用栈…

Cell:癌症研究的下一个问题是什么?

人类对自身肿瘤发生和癌症进展的理解以及不同癌症类型的临床治疗在近年来发生了巨大的变化。然而&#xff0c;即使有这些进展&#xff0c;科学家和肿瘤学家仍然面临着许多挑战&#xff0c;从揭示其中的分子和细胞机制到治疗和生物标志物的开发&#xff0c;再到治疗后的生活质量…