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.rhkb.cn/news/151540.html

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

相关文章

CCF中国开源大会专访|毛晓光:“联合”是开源走向“共赢”的必由之路

受访嘉宾 | 毛晓光 记者 | 朱珂欣 2023 CCF 中国开源大会( CCF ChinaOSC )拟于 2023 年 10 月 21 日至 22 日在湖南省长沙市北辰国际会议中心召开。 作为第二届 CCF 中国开源大会,本届大会将组织特邀报告、高峰论坛和领域分论坛等不同类…

echarts

1 type值汇总 不同的type的值对应的图表类型如下: type: ‘bar’:柱状/条形图 type: ‘line’:折线/面积图 type: ‘pie’:饼图 type: ‘scatter’:散点(气泡)图 type: ‘effectScatter’&…

聪明应对工程项目管理难题的方法和技巧

对于国内的工程项目管理中,经常需要面对以下几个问题: 1.项目问题相互牵扯,积累成堆:通常一个问题不能及时的解决,就会导致更多的任务无法完成,问题越堆积越严重。 2.项目延期,增加成本&#xf…

NSA 和 CISA 联合揭露当下十大网络安全错误配置

10月5日,美国国家安全局 (NSA) 和网络安全与基础设施安全局 (CISA) 公布了十大目前最常见的网络安全错误配置,这些错误由红蓝团队在大型组织网络中发现。 根据发布的联合报告,团队评估了国防部 (DoD)、联邦民事行政部门 (FCEB)、州和地方政府…

ASP.NET Core教程:ASP.NET Core 程序部署到Windows系统

框架依赖 一、发布 框架依赖(FDD):即Framework-dependent deployments的缩写。这种发布方式依赖于Framework框架,即要部署的服务器上面必须按照ASP.NET Core 运行时环境(ASP.NET Core Runtime)。这种部署方式是微软默认推荐的。下…

C#中的数组探究与学习

目录 C#中的数组一般分为:一.数组定义:为什么要使用数组?什么是数组?C#一维数组for和foreach的区别C#多维数组C#锯齿数组初始化的意义:适用场景: C#中的数组一般分为: ​①.一维数组。 ②.多维…

分布式文件系统HDFS(林子雨慕课课程)

文章目录 3. 分布式文件系统HDFS3.1 分布式文件系统HDFS简介3.2 HDFS相关概念3.3 HDFS的体系结构3.4 HDFS的存储原理3.5 HDFS数据读写3.5.1 HDFS的读数据过程3.5.2 HDFS的写数据过程 3.6 HDFS编程实战 3. 分布式文件系统HDFS 3.1 分布式文件系统HDFS简介 HDFS就是解决海量数据…

读书笔记——C++高性能编程(一至三)

《C高性能编程》作者:费多尔.G.皮克斯 版本:2022年11月第1版 第一章.性能基础 描述了吞吐量,功耗,实时应用性能的含义。 阐述了“虽然几乎不可能提前预测最佳优化,但是可以确定某些设计决策将使后续优化变得非常困难…

C/C++ 进程间通信system V IPC对象超详细讲解(系统性学习day9)

目录 前言 一、system V IPC对象图解 1.流程图解: ​编辑 2.查看linux内核中的ipc对象: 二、消息队列 1.消息队列的原理 2.消息队列相关的API 2.1 获取或创建消息队列(msgget) 实例代码如下: 2.2 发送消息到消…

单元测试该怎么写

单元测试对于开发人员来说很熟悉,各种语言都提供了单元测试的框架,用于自动化执行单元测试并生成测试报告。它通常提供了一组API和工具,使开发人员能够编写和运行测试用例,比较预期行为和实际行为之间的差异,并准确地识…

多线程锁-synchronized字节码分析

从字节码角度分析synchronized实现 javap -c(v附加信息) ***.class 文件反编译 synchronized同步代码块 >>>实现使用的是monitorenter和monitorexit指令 synchronized普通同步方法 >>>调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置&#xf…

【数据结构-二叉树 九】【树的子结构】:树的子结构

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【子结构】,使用【二叉树】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为&…

不同数据类型在单片机内存中占多少字节?

文章目录 前言一、不同编译器二、C51* 指针型 三、sizeof结构体联合体 前言 在C语言中,数据类型指的是用于声明不同类型的变量或者函数的一个广泛的系统。变量的类型决定了变量存储占用的空间 一、不同编译器 类型16位编译器大小32位编译器大小64位编译器大小char…

Kafka 简介之(学习之路)

正文 一、简介 1.1 概述 Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志、访问日志,消息服务…

软件设计原则 1小时系列 (C++版)

文章目录 前言基本概念 Design Principles⭐单一职责原则(SRP) Single Responsibility PrincipleCode ⭐里氏替换原则(LSP) Liskov Substitution PrincipleCode ⭐开闭原则(OCP) Open Closed PrincipleCode ⭐依赖倒置原则(DIP) Dependency Inversion PrincipleCode ⭐接口隔离…

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

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

Centos7安装MongoDB7.xxNoSQL数据库|设置开机启动(骨灰级+保姆级)

一: mongodb下载 MongoDB 社区免费下载版 MongoDB社区下载版 [rootwww tools]# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-7.1.0-rc4.tgz 二: 解压到指定目录 [rootwww tools]# mkdir -p /usr/local/mongodb [rootwww tools]# tar -zxvf mongodb-…

选择适合普通公司的项目管理软件

不管是打工人还是学生党都适合使用Zoho Projects项目管理软件。利用项目概览功能,将整体项目尽收眼底,作为项目管理者,项目日程、进度都可见,Zoho Projects项目管理APP助推项目每一环节的进展,更便于管理者设计项目的下…

ThingsBoard如何自定义tcp-transport

1、概述 很久没有更新了,一直忙于其他的事情,最近去搞了一个在ThingsBoard中自定义一个tcp-transport,用于连接使用tcp长连接的设备,目前使用tcp和mqtt协议连接服务端的设备还是很多,ThingsBoard的PE版提供了Integration是可以实现tcp的接入,但是CE版是没有提供接入tcp长…

【MySQL】基本查询(二)

文章目录 一. 结果排序二. 筛选分页结果三. Update四. Delete五. 截断表六. 插入查询结果结束语 操作如下表 //创建表结构 mysql> create table exam_result(-> id int unsigned primary key auto_increment,-> name varchar(20) not null comment 同学姓名,-> chi…