Docker 镜像的缓存特性

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 wgetdocker 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。查看本地镜像详情:

可见,图中的 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/localdocker 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。查看本地镜像详情:

如果你不想使用镜像缓存可添加 --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 wgetdocker build -t centos:v3 .镜像构建流程分析:
此时就没使用缓存了,构建流程与上面是一致的。
查看本地镜像详情:

-
构建说明
尽管从逻辑上来说改动指令顺序对镜像的内容没有改变,但由于镜像的分层结构特性,改动 Dockerfile 指令顺序后 Docker 必须重建受影响的镜像层。
看看分层:图中更清晰地像我们展示了镜像的分层结构(可见这些镜像都是在基础镜像层上继续叠加新的镜像层成为新的镜像),每一层由上至下排列,且上层依赖于下层。

二、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,提升了镜像的构建效率。
总结
综上案例我们要知道,镜像的缓存可以是在构建时发生,也会在 pull 镜像时发生。
而且我们不难归纳出 Docker 镜像缓存在实际应用中的优势:
-
构建速度提升:使用缓存可以显著提高镜像构建的速度,减少了不必要的工作,节省时间;
-
减少带宽使用:因为构建可以从本地缓存中获取,所以减少了从其他远程仓库下载的数据量,从而减少了带宽的使用;
-
提高可重复性:镜像缓存确保了构建的可重复性,这点毋庸置疑,这也是 Docker 镜像的精髓所在;
-
降低资源消耗:因为缓存特性,Docker Daemon 不必重新执行 Dockerfile 中已经缓存的指令,从而降低了系统资源的消耗;
-
减少互联网依赖:如果缓存中已经存在所需的镜像层,那么构建过程则不依赖于互联网上的外部资源,尤其是在网络不稳定或有限的环境中,更体现出来其可靠性。
—END
相关文章:
Docker 镜像的缓存特性
Author:rab 目录 前言一、构建缓存二、Pull 缓存总结 前言 首先我们要清楚,Docker 的镜像结构是分层的,镜像本身是只读的(不管任何一层),当我们基于某镜像运行一个容器时,会有一个新的可写层被…...
Javascript 笔记:object
一部分object可以见:JavaScript 笔记 初识JavaScript(变量)_UQI-LIUWJ的博客-CSDN博客 1 in操作符 2 hasOwnProperty 3 获取一个object所拥有的所有property 不去原型链上找 4 定义data property...
【vue3】可编辑el-table
<template><el-table:data"tableData"style"width: 100%"><el-table-columnprop"date"label"日期"width"180"><template #default"{row,$index}"><input type"text" v-mode…...
一个开源的安卓相机:OpenCamera
原网址 Open Camera download | SourceForge.net 我也上传了一个 https://github.com/quantum6/Android-OpenCamera...
分类预测 | MATLAB实现POA-CNN鹈鹕算法优化卷积神经网络多特征分类预测
分类预测 | MATLAB实现POA-CNN鹈鹕算法优化卷积神经网络多特征分类预测 目录 分类预测 | MATLAB实现POA-CNN鹈鹕算法优化卷积神经网络多特征分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现POA-CNN鹈鹕算法优化卷积神经网络多特征分类预测࿰…...
学习网络编程No.7【应用层之序列化和反序列化】
引言: 北京时间:2023/9/14/19:13,下午刚刚更完文章,是一篇很久很久以前的文章,由于各种原因,留到了今天更新,非常惭愧呀!目前在上学校开的一门网络课程,学校的课听不了一…...
小谈设计模式(10)—原型模式
小谈设计模式(10)—原型模式 专栏介绍专栏地址专栏介绍 原型模式角色分类抽象原型(Prototype)具体原型(Concrete Prototype)客户端(Client)原型管理器(Prototype Manager…...
用《斗破苍穹》的视角打开C#3 标签与反射(人物创建与斗技使用)
随着剧情的发展,主线人物登场得越来越多,时不时跳出一个大佬,对我张牙舞爪地攻击。眼花缭乱的斗技让我不厌其烦,一个不小心,我就记不清楚在哪里遇上过什么人,他会什么斗技了。这时候,我就特别希…...
c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(下))
上篇文章介绍了一些常用的字符串函数,大家可以跳转过去浏览一下:c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(上))_总之就是非常唔姆的博客-CSDN博客 今天接着来介绍一些&#x…...
一文看懂光模块的工作原理
你们好,我的网工朋友 光模块有很多类别,是我们经常要用到的PHY层器件。虽然封装,速率,传输距离有所不同,但是其内部组成基本是一致的。 以太网交换机常用的光模块有SFP,GBIC,XFP,X…...
基于SpringBoot的桂林旅游景点导游平台
目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 景点类型管理 景点信息管理 线路推荐管理 用户注册 线路推荐 论坛交流 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实…...
【小程序 - 加强】自定义组件、使用npm包、全局数据共享、分包_05
目录 一、自定义组件 1. 组件的创建与引用 1.1 创建组件 1.2 引用组件 1.2.1 局部引用组件 1.2.2 全局引用组件 1.2.3 全局引用 VS 局部引用 1.2.4 组件和页面的区别 2. 样式 2.1 组件样式隔离 2.2 组件样式隔离的注意点 2.3 修改组件的样式隔离选项 2.4 styleIso…...
Vue.js3学习篇--Vue模板应用
目录 一,模板基础 1.模板插值 (1)基础插值 (2)HTML代码插值 (3)标签属性插值 2.模板指令 (1)定义 (2)指令参数 二.条件渲染 1.使用v-if指令渲染 2.使…...
【软考】5.2 传输介质/通信方式/IP地址/子网划分
《传输介质》 双绞线:网线;传输距离在100m以内 无屏蔽双绞线:UTP;可靠性相对较低屏蔽双绞线:STP;屏蔽怕干扰;可靠性相对较高;一般用于对传输可靠性要求很高的场合 网线:…...
软件测试银行项目网上支付接口调用测试实例
公司最近有一个网站商城项目要开始开发了,这几天老板和几个同事一起开着需求会议, 讨论了接下来的业务规划和需求策略,等技术需求一下来还要讨论技术需求, 确认后再慢慢的进入开发阶段,趁着闲暇时间新造的人想总结一…...
w806 adc 中断扫描通道采集
用到了该芯片adc 扫描4个adc 通道,官方的死循环等待非常浪费时间,这里改用adc 中断采集方式,记录一下 int32_t adcFilterSum[4]{0}; int32_t detec_adc_value[4]{0};//mV int16_t detec_convt_ok[4]{0};/*is OK*/ ADC_HandleTypeDef hadc;vo…...
使用CSS的Positions布局打造响应式网页
在当今移动互联网的时代,响应式网页设计已经成为了一个必备的技能。通过使用CSS Positions布局,我们可以轻松地实现一个响应式的网页,使网页能够在不同的屏幕尺寸下自动适应。本文将介绍如何使用CSS Positions布局来打造一个响应式网页&#…...
模型训练环境相关(CUDA、PyTorch)
模型训练环境相关(CUDA、PyTorch) 1. 查看当前 GPU 所能支持的最高版本的 CUDA2. 如何判断是否安装了 CUDA3. 安装 PyTorch3.1 创建虚拟环境3.2 激活并进入虚拟环境3.3 安装 PyTorch 1. 查看当前 GPU 所能支持的最高版本的 CUDA 打开 NVIDIA 控制面板&a…...
链动2+1模式:社交电商行业的新型商业模式与营销手段
链动21模式是近年来在社交电商行业中崭露头角的一种新型商业模式和营销手段。在经历了多年的发展之后,社交电商行业已经进入了一个竞争激烈、用户获取成本高昂的阶段。在这个阶段,如何迅速吸引用户并增加他们的留存率和复购率成为了亟待解决的问题。 为了…...
竞赛选题 深度学习 opencv python 实现中国交通标志识别
文章目录 0 前言1 yolov5实现中国交通标志检测2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 实现效果5.1 视频效果 6 最后 0 前言 🔥 优质…...
5分钟掌握:billd-desk跨平台远程控制高效解决方案
5分钟掌握:billd-desk跨平台远程控制高效解决方案 【免费下载链接】billd-desk 基于Vue3 WebRTC Nodejs Flutter搭建的远程桌面控制 项目地址: https://gitcode.com/gh_mirrors/bi/billd-desk 还在为远程办公的卡顿和限制而烦恼吗?当你急需远程…...
IDEA插件开发:集成Nunchaku-flux-1-dev实现代码注释自动图解
IDEA插件开发:集成Nunchaku-flux-1-dev实现代码注释自动图解 1. 引言 作为一名Java开发者,你是否曾经面对过这样的困境:接手一个复杂的遗留系统,代码量庞大但注释稀少,逻辑关系错综复杂,光是理解代码执行…...
热键冲突解决:从检测到修复的完整指南
热键冲突解决:从检测到修复的完整指南 【免费下载链接】hotkey-detective A small program for investigating stolen hotkeys under Windows 8 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective 在日常电脑使用中,我们经常会遇到这…...
Phi-3-mini-4k-instruct-gguf GPU利用率优化:CUDA核心占用率与吞吐量分析
Phi-3-mini-4k-instruct-gguf GPU利用率优化:CUDA核心占用率与吞吐量分析 1. 模型概述与性能挑战 Phi-3-mini-4k-instruct-gguf是微软推出的轻量级文本生成模型,基于GGUF格式优化,特别适合问答、文本改写和摘要生成等场景。虽然模型体积小巧…...
小米智能家居与Home Assistant完美融合:打造高效智能家居生态
小米智能家居与Home Assistant完美融合:打造高效智能家居生态 【免费下载链接】ha_xiaomi_home Xiaomi Home Integration for Home Assistant 项目地址: https://gitcode.com/GitHub_Trending/ha/ha_xiaomi_home 小米智能家居Home Assistant集成是由小米官方…...
告别卡顿!用MobileNetv2+MPPTSNet-EC在树莓派上跑实时语义分割(附完整配置与性能测试)
树莓派实战:MobileNetv2MPPTSNet-EC实时语义分割全流程解析 当你在树莓派上第一次看到摄像头画面被实时分割成不同语义区域时,那种成就感绝对值得记录。本文将带你完整实现从模型选择到部署优化的全流程,用MobileNetv2MPPTSNet-EC这套组合拳&…...
C++的std--ranges中的技术优化排序
C20引入的std::ranges库为算法操作带来了革命性改进,尤其在排序优化领域展现出强大的现代性。本文将深入探讨std::ranges如何通过结构化绑定、惰性求值和定制化投影等技术,实现更高效、更灵活的排序操作,为开发者提供超越传统STL的解决方案。…...
嵌入式NTP客户端库:高精度时间同步与自动时区管理
1. NTP客户端库深度解析:嵌入式系统中的高精度时间同步与时区管理1.1 库定位与工程价值NTP(Network Time Protocol)客户端库是嵌入式系统中实现网络时间同步的关键组件。该库并非简单封装UDP通信,而是构建了一套完整的“时间服务栈…...
AUTOSAR SPI配置进阶:如何为你的车载传感器设计高效可靠的通信序列?
AUTOSAR SPI配置进阶:车载传感器通信序列设计实战指南 在智能驾驶系统开发中,SPI总线作为连接毫米波雷达、IMU等关键传感器的神经末梢,其通信效率直接影响着环境感知的实时性。传统配置手册往往止步于基础参数说明,而本文将带您深…...
从YOLO到A*:手把手教你用PyTorch和OpenCV搭建一个简易的自动驾驶避障仿真器
从YOLO到A*:用PyTorch和OpenCV构建自动驾驶避障仿真器 想象一下,你正坐在一辆自动驾驶汽车里,车辆能够自动识别前方的行人、车辆和障碍物,并规划出安全的行驶路径。这种看似科幻的场景,如今正逐渐成为现实。本文将带你…...
