Docker 镜像的缓存特性-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

dockerimages

Authorrab


目录


前言

首先我们要清楚Docker 的镜像结构是分层的镜像本身是只读的不管任何一层当我们基于某镜像运行一个容器时会有一个新的可写层被加载到镜像的顶部我们通常将这一层称之为容器层容器层之下的都称之为镜像层。我们所有对容器的增删操作都只会发生在容器层中因此容器层保存的是从容器运行时开始到当前的数据变化部分不会对镜像层本身进行任何修改。镜像的其他特性就不在一一举例了我们现在的目标是镜像的缓存特性镜像的缓存有什么优势它在哪方面实现缓存接下来我们来细看一下。

一、构建缓存

1、什么是构建

Docker 镜像构建使用分层文件系统的概念每个 Dockerfile 指令都会生成一个新的文件系统层这些层通过联合文件系统UnionFS技术叠加在一起形成最终的镜像。

2、什么是缓存

Docker 使用缓存来提高构建效率当构建镜像时如果之前的层已经存在并且没有发生更改顺序上的更改那 Docker 将重用这些层而不是重新生成它们这可以显著减少构建时间和服务器带宽使用。

3、案例演示缓存特性

  • 创建 Dockerfile 文件并构建镜像

    mkdir -p /root/dist && cd /root/dist     # 创建构建上下文目录
    vim Dockerfile                           # 添加下面内容
    
    FROM centos:centos7.9.2009
    RUN yum install -y wget
    
    docker build -t centos:v1 .
    
    Sending build context to Docker daemon  2.048kB ①
    Step 1/2 : FROM centos:centos7.9.2009  ②
     ---> eeb6ee3f44bd  
    Step 2/2 : RUN yum install -y wget  ③
     ---> Running in a51051b0f4a5
    Loaded plugins: fastestmirror, ovl
    Determining fastest mirrors
     * base: mirrors.ustc.edu.cn
     * extras: mirrors.ustc.edu.cn
     * updates: mirrors.huaweicloud.com
    Resolving Dependencies
    --> Running transaction check
    ---> Package wget.x86_64 0:1.14-18.el7_6.1 will be installed
    --> Finished Dependency Resolution
    ...
    ...
    Installed:
      wget.x86_64 0:1.14-18.el7_6.1                                                 
    
    Complete!
    Removing intermediate container a51051b0f4a5  ④
     ---> 9a4b27a6d88d  
    Successfully built 9a4b27a6d88d  ⑤
    Successfully tagged centos:v1  ⑥
    

    镜像构建流程分析

    向 Docker 守护进程发送构建上下文即将 /root/dist 目录下的所有文件发送给 Docker daemon因此不要将 //usr/etc 等目录作为构建上下文发送给 Docker daemon否则构建出的镜像将会很臃肿且构建会很缓慢甚至有可能会构建失败所以为什么一开始我就创建了一个空目录/root/dist作为我上下文的存储目录。

    步骤1Step 1/2将 centos:centos7.9.2009 作为构建的基础base镜像该 base 镜像 ID 为 eeb6ee3f44bd

    步骤1Step 2/2开始执行 Dockerfile 中的指令 RUN yum install -y wget而且是在一个中间临时容器上执行的指令该临时容器的 ID 为 a51051b0f4a5为什么要使用临时容器因为 base 镜像是只读的想要进行增删只能在容器层实现。

    RUN yum install -y wget 指令在临时容器 a51051b0f4a5 完成安装后就会将临时容器删除即构建信息中的 Removing intermediate container a51051b0f4a5 部分并最终将该临时容器保存为镜像且镜像 ID 为 9a4b27a6d88d

    镜像 9a4b27a6d88d 构建成功。

    将镜像 9a4b27a6d88d 打上 Tag 为 centos:v1

    查看本地镜像详情

    image-20231006093145229

    可见图中的 TAG、IMAGE ID 与我们 ⑤、⑥ 是一一对应的而且你会发现构建后的镜像的容量比基础镜像更大了。

  • Docker 镜像缓存应用

    在构建上下文目录中创建一个测试文件test.txt进行缓存测试验证。

    touch test.txt   # 创建测试文件
    vim Dockerfile   # 添加下面内容
    
    FROM centos:centos7.9.2009
    RUN yum install -y wget
    COPY test.txt /usr/local
    
    docker build -t centos:v2 .
    
    Sending build context to Docker daemon   2.56kB
    Step 1/3 : FROM centos:centos7.9.2009
     ---> eeb6ee3f44bd
    Step 2/3 : RUN yum install -y wget  ①
     ---> Using cache
     ---> 9a4b27a6d88d
    Step 3/3 : COPY test.txt /usr/local  ②
     ---> 8f421058bfd8
    Successfully built 8f421058bfd8
    Successfully tagged centos:v2
    

    镜像构建流程分析

    当执行 RUN yum install -y wget 指令时就使用了缓存 Using cache且是镜像 9a4b27a6d88d 层的缓存不难看出这镜像就是上面我们刚构建而成的。

    同样 COPY test.txt /usr/local 指令在临时容器中构建完成并最终生成镜像 8f421058bfd8

    查看本地镜像详情

    image-20231006094542859

    如果你不想使用镜像缓存可添加 --no-cache 选项docker build -t centos:v2 --no-cache .

    此时构建镜像就不会使用本地镜像缓存了。

4、注意

这里要注意的是缓存生效的前提是 Dockerfile 的指令未发生位置顺序上的变动否则缓存失效会重新生成新的镜像层而不会使用缓存具体案例如下。

  • 修改 Dockerfile 文件中的指令顺序并构建镜像

    FROM centos:centos7.9.2009
    COPY test.txt /usr/local
    RUN yum install -y wget
    
    docker build -t centos:v3 .
    

    镜像构建流程分析

    此时就没使用缓存了构建流程与上面是一致的。

    查看本地镜像详情

    image-20231006095006205

  • 构建说明

    尽管从逻辑上来说改动指令顺序对镜像的内容没有改变但由于镜像的分层结构特性改动 Dockerfile 指令顺序后 Docker 必须重建受影响的镜像层。

    看看分层图中更清晰地像我们展示了镜像的分层结构可见这些镜像都是在基础镜像层上继续叠加新的镜像层成为新的镜像每一层由上至下排列且上层依赖于下层。

    image-20231006095626841

二、Pull 缓存

Docker 除了在镜像构建时可使用缓存在拉取pull镜像时也会使用缓存具体案例如下。

1、先 pull 一个基础镜像如debian

docker pull debian

2、再 pull 一个应用镜像如httpd

docker pull httpd

Pull 分析怎么证明本次的 pull 使用了缓存

下图中Already exists说明该 httpd 镜像使用的 base 镜像是 debian 镜像而 debian 镜像我们已经提前 pull 了因此就不需额外地再次 pull提升了镜像的构建效率。

image-20231006100356941

总结

综上案例我们要知道镜像的缓存可以是在构建时发生也会在 pull 镜像时发生。

而且我们不难归纳出 Docker 镜像缓存在实际应用中的优势

  • 构建速度提升使用缓存可以显著提高镜像构建的速度减少了不必要的工作节省时间

  • 减少带宽使用因为构建可以从本地缓存中获取所以减少了从其他远程仓库下载的数据量从而减少了带宽的使用

  • 提高可重复性镜像缓存确保了构建的可重复性这点毋庸置疑这也是 Docker 镜像的精髓所在

  • 降低资源消耗因为缓存特性Docker Daemon 不必重新执行 Dockerfile 中已经缓存的指令从而降低了系统资源的消耗

  • 减少互联网依赖如果缓存中已经存在所需的镜像层那么构建过程则不依赖于互联网上的外部资源尤其是在网络不稳定或有限的环境中更体现出来其可靠性。

—END

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Docker