掌握了Docker Layer Caching才敢自称精通Dockerfile

长话短说:本次原创将向您展示在Docker中使用Layer Cache以加快镜像构建。

这个话题的初衷在于:应用打包过程是很慢的(下载并安装框架&第三方依赖包、生成assets),这个过程在Docker中也不能避免。

About Layer Caching  in Docker

Docker使用层layer创建镜像,Dockerfile中每一个命令都会创建一个新的层,每层都包含执行命令前后的状态之间镜像的文件系统更改。

为了加快构建速度,Docker实现了缓存:
如果Dockerfile和相关文件未更改,则重建(rebuild)时可以重用本地镜像缓存中的某些现有层。
但是,为了利用此缓存,您需要了解它的工作方式,这就是我们将在本文中介绍的内容。

The basic algorithm

当您构建Dockerfile时,Docker将查看它是否可以使用先前构建的缓存结果:

  • 对于大多数命令,如果命令文本未更改,则将使用缓存中的版本。

  • 对于COPY,它还会检查您要复制的文件是否未更改。

我们来看一个使用以下Dockerfile的示例:

FROM python:3.7-slim-buster
COPY . .
RUN pip install --quiet -r requirements.txt
ENTRYPOINT ["python", "server.py"]

第一次运行时,所有命令都会运行:

$ docker build -t example1 .
Sending build context to Docker daemon   5.12kB
Step 1/4 : FROM python:3.7-slim-buster---> f96c28b7013f
Step 2/4 : COPY . .---> eff791eb839d
Step 3/4 : RUN pip install --quiet -r requirements.txt---> Running in 591f97f47b6e
Removing intermediate container 591f97f47b6e---> 02c7cf5a3d9a
Step 4/4 : ENTRYPOINT ["python", "server.py"]---> Running in e3cf483c3381
Removing intermediate container e3cf483c3381---> 598b0340cc90
Successfully built 598b0340cc90
Successfully tagged example1:latest

第二次构建时,因为没有任何改变,docker构建将使用镜像缓存:

$ docker build -t example1 .
Sending build context to Docker daemon   5.12kB
Step 1/4 : FROM python:3.7-slim-buster---> f96c28b7013f
Step 2/4 : COPY . .---> Using cache---> eff791eb839d
Step 3/4 : RUN pip install --quiet -r requirements.txt---> Using cache---> 02c7cf5a3d9a
Step 4/4 : ENTRYPOINT ["python", "server.py"]---> Using cache---> 598b0340cc90
Successfully built 598b0340cc90
Successfully tagged example1:latest

请注意,上面显示的Using cache加快了构建速度(无需从网络下载任何pip依赖包)

如果我们删除镜像,则后续构建将从头开始(没有层缓存了):

$ docker image rm example1
Untagged: example1:latest
Deleted: sha256:598b0340cc90967501c5c51862dc586ca69a01ca465f48232fc457d3ab122a73
Deleted: sha256:02c7cf5a3d9af1939b9f5286312b23898fd3ea12b7cb1d7a77251251740a806c
Deleted: sha256:d9e9602d9c3fd7381a8e1de301dc4345be2eb2b8488b5fc3e190eaacbb2f9596
Deleted: sha256:eff791eb839d00cbf46d139d8595b23867bc580bb9164b90253d0b2d9fcca236
Deleted: sha256:53d34b2ead0a465d229a4260fee2a845fb8551856d4019cd2e608dfe0e039e77
$ docker build -t example1 .
Sending build context to Docker daemon   5.12kB
Step 1/4 : FROM python:3.7-slim-buster---> f96c28b7013f
Step 2/4 : COPY . .---> 63c32b9b1af6
...

Taking advantage of caching

缓存算法还有一个更重要的规则:

  • 如果某层无法应用层缓存,则后续层都不能从层缓存加载

在以下示例中,前后两次构建过程的C层均未更改,尽管如此,由于上层并不是从层缓存中加载,因此后置的C层仍然无法从缓存中加载:

层缓存对下面的Dockerfile意味着什么?

FROM python:3.7-slim-buster
COPY requirements.txt .
COPY server.py .
RUN pip install --quiet -r requirements.txt
ENTRYPOINT ["python", "server.py"]

如果COPY命令的任何文件改变了,则会使后续所有层缓存失效:我们需要重新运行pip install (这一层若不走缓存,通常耗时久)。
但是,如果requirements.txt没有更改 & server.py更改了,为什么我们必须重做pip安装?毕竟,pip安装仅使用requirements.txt

推及到现代编程语言:前端的依赖包文件paakcage.json, dotnet的项目管理文件dotnetdemo.csproj等,一般很少变更;随时变动的业务代码,导致后续的层缓存失效(后续层每次都要重新下载&安装依赖)。

因此,您要做的是仅复制实际需要运行下一步的那些文件,以最大程度地减少缓存失效的机会。

FROM python:3.7-slim-buster
COPY requirements.txt .
RUN pip install --quiet -r requirements.txt
COPY server.py .
ENTRYPOINT ["python", "server.py"]

由于server.py仅在pip安装后才复制到构建上下文,因此,只要requirements.txt不变,仍然可以从缓存加载由上次pip安装创建的层。

Designing your Dockerfile for caching

如果您想通过重用之前缓存的层来进行快速构建,则需要适当地编写Dockerfile:

  • 仅复制下一步所需的文件,以最大程度地减少构建过程中的缓存失效。

  • 尽量将文件可能变更的新增(ADD命令)、拷贝(COPY命令) 延迟到Dockerfile的后部。

“阅读全文,体验更佳”

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

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

相关文章

How Many Answers Are Wrong HDU - 3038(带权并查集)

题意: TT写一个数列,现在TT会选择一个区间,然后让FF计算这个区间里面所有数的和,FF准备捉弄一下TT,有时候她会故意计算出来一个错的答案,当然TT也比较聪明,他会发现这个答案跟以前的答案会有冲…

ASP.NET Core on K8s学习之旅(14)Ingress灰度发布

【云原生】| 作者/Edison Zhou这是恰童鞋骚年的第236篇原创文章上一篇介绍了Ingress的基本概念和Nginx Ingress的基本配置和使用,然后我还录了一个快速分享小视频介绍了一下蓝绿发布和灰度发布策略的基本概念,本篇介绍一下如何实战使用Nginx Ingress实现…

[汇编语言]实验:应用更灵活的寻址方式来定位内存地址

实验内容: (1)将datasg段中每个单词的头一个字母改成大写字母。 datasg段中的数据为: (2) 将datasg段中每个单词的字母改成大写字母。 datasg段中的数据为: ibm dec dos vax …

你需要了解操作系统发展历程

本文我们大概回顾计算机操作系统发展历程,这里不会记录关于操作系统的完整历史记录,只是记录那些里程碑事件,看看各位接触计算机时,操作系统发展正处于哪个年代起初没有操作系统,没有编程语言或编译器,甚至…

基于 abp vNext 和 .NET Core 开发博客项目 - 使用Redis缓存数据

上一篇文章完成了项目的全局异常处理和日志记录。在日志记录中使用的静态方法有人指出写法不是很优雅,遂优化一下上一篇中日志记录的方法,具体操作如下:在.ToolKits层中新建扩展方法Log4NetExtensions.cs。//Log4NetExtensions.cs using log4…

第一讲 工作区和GOPATH

此为 《极客时间&Go语言核心36讲》 个人笔记,具体课程详见极客时间官网。 Table of Contents generated with DocToc 第一讲 工作区和GOPATH 1. 环境变量配置2. 配置GOPATH的意义 2.1 Go语言源码的组织方式2.2 源码安装后的结果(归档文件、可执行文…

开发大会上,前微软CEO放出的狠话!.NET开发随时起飞,你准备好了吗?

“开发者,开发者,开发者,开发者”,微软前任CEO史蒂夫鲍尔默(Steve Ballmer)用这种略带疯狂、又唱又跳的方式表达他对开发者的热爱。不夸张的说,相比二十年前那个如日中天的巨无霸微软,现在的微软比以往任何…

程序员过关斩将--为微服务撸一个简约而不简单的配置中心

点击上方蓝字 关注我们毫不犹豫的说,现代高速发展的互联网造就了一批又一批的网络红人,这一批批网红又极大的催生了特定平台的一大波流量,但是留给了程序员却是一地鸡毛,无论是运维还是开发,每天都会担心服务器崩溃&a…

Just a Hook HDU - 1698(查询区间求和+最基础模板)

题意: 给你一个1~n的区间,起始区间内均为1,然后对子区间进行值更新,最后求区间和。 题目: In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. The hook is ma…

DDIA笔记——数据复制

Table of Contents generated with DocToc 此篇为《数据密集型应用系统设计》(DDIA)读书笔记,笔记可能存在遗漏,建议直接阅读原书。 第五章 数据复制 主从复制 复制滞后复制滞后带来的问题 多主节点复制 适用场景处理写冲突拓扑结…

基于 abp vNext 和 .NET Core 开发博客项目 - 集成Hangfire实现定时任务处理

上一篇文章成功使用了Redis缓存数据,大大提高博客的响应性能。接下来,将完成一个任务调度中心,关于定时任务有多种处理方式,如果你的需求比较简单,比如就是单纯的过多少时间循环执行某个操作,可以直接使用.…

Docker基本组成 和 基本命令

此篇为Docker笔记,文章可能存在疏忽,建议直接观看原视频。 视频地址:https://www.bilibili.com/video/BV1og4y1q7M4?spm_id_from333.999.0.0 Docker基本组成 和 基本命令 镜像 image:就好比一个模板,可以通过这个模板…

Docker镜像讲解

此篇为Docker笔记,文章可能存在疏忽,建议直接观看原视频。 视频地址:https://www.bilibili.com/video/BV1og4y1q7M4?spm_id_from333.999.0.0 参考:https://blog.csdn.net/11b202/article/details/21389067 Docker镜像讲解 镜像是…

Making the Grade POJ - 3666(离散化+dp)

题意: 给你n个山的高度,单独的一个数可以任意加减,让经过对每座山峰任意加减高度后变成递增或递减的序列时,求对每个数的相加或相减的数目的最小和。 题目: A straight dirt road connects two fields on FJ’s far…

Kubernetes的安全性怎么解?从4个方面为你列出方案清单

导语Kubernetes中的安全性是一个多维问题,必须从各个不同的角度来解决才算完善,这篇文章将从4个方面为读者列出安全清单。正文Kubernetes,经过更快的采用和社区的更多贡献,正日益攀登到新的高度。不过,安全性仍然是Kub…