Docker 镜像的缓存特性

dockerimages

Author:rab


目录

    • 前言
    • 一、构建缓存
    • 二、Pull 缓存
    • 总结


前言

首先我们要清楚,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)作为我上下文的存储目录。

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

    ③:步骤1(Step 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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux嵌入式学习之Ubuntu入门(六)shell脚本详解

系列文章内容 Linux嵌入式学习之Ubuntu入门(一)基本命令、软件安装、文件结构、编辑器介绍 Linux嵌入式学习之Ubuntu入门(二)磁盘文件介绍及分区、格式化等 Linux嵌入式学习之Ubuntu入门(三)用户、用户组…

【C++设计模式之状态模式:行为型】分析及示例

简介 状态模式(State Pattern)是一种行为型设计模式,它允许对象在内部状态改变时改变其行为,看起来就像是改变了其类。状态模式将对象的状态封装成不同的类,并使得对象在不同状态下有不同的行为。 描述 状态模式通过…

Redis的五种常用数据类型

1.字符串 String的数据结构是简单的Key-Value模型,Value可以是字符串,也可以是数字。 String是Redis最基本的类型,是二进制安全的,意味着Redis的string可以包含任何数据,比如jpg图片。 一个redis中字符串value最大是…

整理mongodb文档:副本集二

个人博客 整理mongodb文档:副本集二 个人博客,求推荐,本片内容较为乱 文章概叙 本文章主要讲在MongoDB的副本集中的一些注意点,主要是如何对seconadry进行数据操作,以及对更新数据的一些介绍 查看当前节点 上一集讲了关于搭…

B (1089) : DS单链表--合并

Description 假定两个单链表是递增有序,定义并实现以下函数,完成两个单链表的合并,继续保持递增有序 int LL_merge(ListNode *La, ListNode *Lb) Input 第1行先输入n表示有n个数据,接着输入n个数据 第2行先输入m表示有M个数据…

TSINGSEE青犀基于AI视频智能分析的客流统计分析场景方案

随着AI技术的不断发展与人类需求的不断提升,视觉目标的检测识别、智能监控在人们的生活中均有着广泛的应用。其中,智能安防视频监控是计算机视觉的重要应用领域,而AI客流统计则是近年来此领域大家关注热度较高的技术之一。 行业痛点 传统的客…

【抢先体验】开通使用 ChatGPT 语音版功能保姆级教程

大家好,我是苍何,一个土木转码的非典型程序员,也是一名技术管理者,同时也是 AI 应用的探索者。今天在视频号上看到和 ChatGPT 语音对话的视频,其声音的真实感太让人震撼了,于是也想去抢先体验一下 ChatGPT …

互联网项目有哪些值得做的

互联网已经融入了我们生活的方方面面,从电商巨头到科技创新,互联网带来的变革和便利无处不在。而在这个信息广泛的时代,越来越多的人开始思考如何利用互联网去创造价值。现如今,互联网项目的形式多种多样,有些让我们的…

python—如何提取word中指定内容

假设有一个Word,该Word中存在 “联系人” 关键字,如何将该Word中的联系人所对应的内容提取出来呢? 该Word内容如下所示: 要在给定的Word文档中提取出与"联系人"关键字对应的内容,可以使用Python的py…

详解链表oJ<反转链表,链表的中间节点及链表的回文>

hello,大家好,这里是Dark FlameMaster,今天和大家分享的是有关数据结构链表的几道题目,链表的中间节点,反转链表及判断链表是否为回文结构,放在一起讲解会印象更加深刻。 文章目录 一,链表的中间节点二&…

你的librosa和scikit-learn打架了吗?

被这个问题困扰好久!!!!!!!!!!!!!! 我的原来版本librosa0.7.1 和 scikit-learn1.3.1 一直拆了按,按…

【力扣每日一题】2023.10.7 股票价格跨度

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 给我们一个数组表示不同时间的股票的价格,要我们按照顺序返回每天的股票价格跨度,价格跨度就是股票价格小于或等于…