掌握了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。
但是,如果server.py更改了,但requirements.txt却没有更改,为什么我们必须重做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的后部。
DotnetCore福利时间
观看Visual Studio web项目默认脚手架形成的Dockerfile:
正是基于Docker Layer Caching思维,做了两次COPY命令。
掌握了Docker Layer Caching才敢自称精通Dockerfile的更多相关文章
- 盘点国内程序员不常用的热门iOS第三方库:看完,还敢自称”精通iOS开发”吗?【转载】
综合github上各个项目的关注度与具体使用情况,涵盖功能,UI,数据库,自动化测试,编程工具等类型,看完,还敢自称”精通iOS开发”吗? https://github.com/syedhali/EZ ...
- Docker入门系列之三:如何将dockerfile制作好的镜像发布到Docker hub上
这个系列的前两篇文章,我们已经把我们的应用成功地在Docker里通过nginx运行了起来,并且用dockerfile里制作好了一个镜像. Docker入门系列之一:在一个Docker容器里运行指定的w ...
- 面试官:你说你精通 Docker,那你来详细说说 Dockerfile 吧
接上一篇:30分钟快速上手Docker,看这篇就对了! 一. 带着问题学Dockerfile 1.疑问 我们都知道从远程仓库可以pull一个tomcat等镜像下来,然后docker run启动容器,然 ...
- Docker学习笔记之二,基于Dockerfile搭建JAVA Tomcat运行环境
前言 在第一篇文字中,我们完全人工方式,一个命令一个命令输入,实现一个 java tomcat运行环境,虽然也初见成效,但很累人.如果依靠依靠脚本构建一个Tomcat容器实例,一个命令可以搞定,何乐而 ...
- Docker 学习笔记(二):Dockerfile 定制镜像
镜像的定制实际上就是定制每一层所添加的配置.文件. 如果我们可以把每一层修改.安装.构建.操作的命令都写入一个脚本,用这个脚本来构建.定制镜像,那么之前提及的无法重复的问题.镜像构建透明性的问题.体积 ...
- Docker学习笔记(三):Dockerfile及多步骤构建镜像
Dockerfile指令 官方文档地址:https://docs.docker.com/engine/reference/builder/ Dockerfile是一个文本格式的配置文件,其内容包含众多 ...
- centos7下安装docker(3.3创建镜像--修改dockerfile)
1.我们在制作dockerfile的时候可能有些命令无法执行,导致镜像无法创建成功,这时我们可以修改dockerfile,从而达到我们的目的 查看Dockerfile内容 创建新的镜像,失败 Dock ...
- Docker学习之路(二)DockerFile详解
Dockerfile是一个镜像的表示,可以通过Dockerfile来描述构建镜像的步骤,并自动构建一个容器 所有的 Dockerfile 命令格式都是: INSTRUCTION arguments 虽 ...
- Docker入门系列之二:使用dockerfile制作包含指定web应用的镜像
实现题目描述的这个需求有很多种办法,作为入门,让我们从最简单的办法开始. 首先使用命令docker ps确保当前没有正在运行的Docker实例. 运行命令docker run -it nginx: 然 ...
随机推荐
- Android Studio快捷键动态演示
Android Studio出来很久了,大部分已经转过来了,相对于Eclipse又是毋庸置疑,更好的使用快捷键必定达到事半功倍的效果. 友情提示:某些电脑按F1-F12键需要先按住FN,比如我的Mac ...
- Redis(二):单机数据库的实现
概要 本部分内容主要是研究单机数据库.分别介绍单机数据库的实现原理,数据库的持久化,Redis事件,服务器维护管理客户端以及单机服务器的运作机制. 数据库 数据库结构 Redis数据库由redis.h ...
- 实战经验:CentOS 7.3安装完整开发环境
系统版本 CentOS 7.3(1611) 安装开发环境 1) 通过group安装 # yum groups mark install “Development Tools” # yum groups ...
- 数学--数论--HDU1576 A / B(逆元)
问题描述 要求(A / B)%9973,但由于A很大,我们只被告知n(n = A%9973)(我们给定的A必能被B整除,且gcd(B,9973)= 1). 输入项 数据的第一行是一个T,表示有T组数据 ...
- 06 ORM常用字段 关系字段 数据库优化查询
一.Django ORM 常用字段和参数 1.常用字段 models中所有的字段类型其实本质就那几种,整形varchar什么的,都没有实际的约束作用,虽然在models中没有任何限制作用,但是还是要分 ...
- java的Timer定时器任务
在项目开发中,经常会遇到需要实现一些定时操作的任务,写过很多遍了,然而每次写的时候,总是会对一些细节有所遗忘,后来想想可能是没有总结的缘故,所以今天小编就打算总结一下可能会被遗忘的小点: 1. pub ...
- centos8-django项目部署 nginx+uwsgi
1.虚拟环境virtualenv安装 1.安装virtualenv pip3 install virtualenv 2.创建目录,把项目文件传过来 mkdir My cd My 3.创建独立运行环境- ...
- Spring Boot 整合 Apache Dubbo
Apache Dubbo是一款高性能.轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现. 注意,是 Apache Dubb ...
- sshd: no hostkeys available — exiting
在开启SSHD服务时报错.sshd re-exec requires execution with an absolute path用绝对路径启动,也报错如下:Could not load host ...
- 09_CSS入门和高级技巧(7)
浏览器兼容问题 1.现在中国网民用什么浏览器? 中国流量最大的网站就是百度,百度在统计着每一个访问者的浏览器.地域.操作系统.分辨率等等信息. 百度流量研究院:http://tongji.baidu. ...