长话短说:本次原创将向您展示在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的后部。

“阅读全文,体验更佳”

掌握了Docker Layer Caching才敢自称精通Dockerfile相关推荐

  1. Nervos:链外扩容 + Layer 2才是区块链的未来(上)

    5月14日晚,密码极客邀请到了Nervos的联合创始人兼COO吕国宁先生做客"密码极客大咖直播间",为大家详细讲述了Nervos的链外扩容与Layer 2设计.吕国宁先生曾是全球最 ...

  2. 面试官:你说你精通 Docker,那你来详细说说 Dockerfile 吧

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 一. 带着问题学Dockerfile 1.疑问 我们都知道从远程仓 ...

  3. Docker学习文档之三 其他相关-Dockerfile指令

    ###Dockerfile指令 Docker可以从Dockerfile中一步一步的读取指令来自动的创建镜像,常使用Dockerfile来创建用户自定义的镜像.格式如下:# Comment INSTRU ...

  4. docker实践(2)常用命令和DockerFile详解

    <docker实践(1) 入门和springBoot实践部署> <docker实践(2)常用命令和DockerFile详解> <docker实践(3) 仓库registr ...

  5. Docker入门系列之三:如何将dockerfile制作好的镜像发布到Docker hub上

    这个系列的前两篇文章,我们已经把我们的应用成功地在Docker里通过nginx运行了起来,并且用dockerfile里制作好了一个镜像. Docker入门系列之一:在一个Docker容器里运行指定的w ...

  6. 系统制成docker镜像_docker镜像原理 镜像制作 dockerfile

    为什么一个centos镜像只有两百多兆,而tomcat镜像五百多兆 1.先说说操作系统 操作系统组成部分: 进程调度子系统 进程通信子系统 内存管理子系统 设备管理子系统 文件管理子系统 网络通信子系 ...

  7. Docker修炼第一招: 先从Dockerfile开始

    2019独角兽企业重金招聘Python工程师标准>>> Docker修炼第一招: 先从Dockerfile开始 百度AI开发者大赛带你边学边开发,赢100万奖金,加群:4185890 ...

  8. 盘点国内程序员不常用的热门iOS第三方库:看完,还敢自称”精通iOS开发”吗?

    综合github上各个项目的关注度与具体使用情况,涵盖功能,UI,数据库,自动化测试,编程工具等类型,看完,还敢自称"精通iOS开发"吗? https://github.com/s ...

  9. Docker 安装 Redis 方法一、通过 Dockerfile 构建 创建Dockerfile 首先,创建目录redis,用于存放后面的相关东西。 runoob@runoob:~$ mkdir -

    Docker 安装 Redis 方法一.通过 Dockerfile 构建 创建Dockerfile 首先,创建目录redis,用于存放后面的相关东西. runoob@runoob:~$ mkdir - ...

最新文章

  1. Content-Type: application/vnd.ms-excel
  2. 我的常用在线工具网站
  3. Spring中Quartz的配置
  4. 实现状态面板的显示与隐藏
  5. jQuery在页面加载的时候自动调用某个函数的方法(转载)
  6. python中运行错误: 'utf-8' codec can't decode byte 0xc8'
  7. Java 内存模型(JMM)
  8. InstallShield 软件打包完整教程
  9. 项目验收流程小TIPS
  10. Wowza 4.3.0安装和使用 并联合海康摄像头(RTSP)实现直播推流
  11. 硬盘测试软件看接口,检测硬盘的工具使用方法
  12. 关于国外硕博士论文搜索和下载的讨论
  13. 5G技术的原理(转)
  14. 微信小程序之获取百度语音合成
  15. Mobius反演方法
  16. tf.logging
  17. 一个相当有用的利器,提高检索匹配的效率!
  18. 【Multisim仿真】全波整流电路仿真
  19. CCleaner安装错误怎么办
  20. 咕噜:区块链的属性不仅是金融,还有社区

热门文章

  1. 构造不可变类及其优点
  2. px,em,rem,vw单位在网页和移动端的应用
  3. 原创:PHP内核研究:HASH表和变量
  4. 从基础开始:Qomo OpenProject中的一些关键词
  5. Teams Bot如何做全球化
  6. 计算机启动程序bios_如何构建自己的计算机,第三部分:准备BIOS
  7. 【前端基础进阶】JS-Object 功能详解
  8. shell脚本注意点
  9. Java8新的异步编程方式 CompletableFuture(三)
  10. Windows Azure 社区新闻综述(#69 版)