Docker入门系列之四:Docker镜像
在本文中,您将学习如何加快Docker构建周期并创建轻量级镜像。遵循之前的文章中的食物隐喻,我们将沙拉隐喻为Docker镜像,同时减少Docker镜像的数量。
在本系列的第3部分中,我们介绍了十几个Dockerfile指令。如果您错过了,请在这里查看文章:
《Docker-第3部分:十二个Dockerfile指令》。
FROM
—指定基本(父)图像。
LABEL
—提供元数据,包括维护者信息。
ENV
—设置持久性环境变量。
RUN
—运行命令并创建图像层,用于将软件包安装到容器中。
COPY
-将文件和目录复制到容器。
ADD
-将文件和目录复制到容器,可以支持本地.tar文件。
CMD
—为执行中的容器提供命令和参数,可以覆盖参数,只能有一个CMD。
WORKDIR
—为以下说明设置工作目录。
ARG
—定义在构建时传递给Docker的变量。
ENTRYPOINT
—为执行中的容器提供命令和参数。争论依然存在。
EXPOSE
—暴露端口。
VOLUME
—创建目录安装点以访问和存储持久数据。
现在让我们来看看如何设计Dockerfiles,以节省开发镜像和拉取容器时的时间。
缓存
Docker的优势之一是它提供了缓存,帮助您更快地迭代镜像构建。
构建镜像时,Docker会按顺序执行每一个Dockerfile中的指令。在检查每个指令时,Docker在其缓存中寻找一个现有的中间镜像,该中间镜像可以重复使用,而不是创建一个新的(重复的)中间镜像。
如果缓存失效,则使缓存失效的指令和所有后续的Dockerfile指令都会生成新的中间镜像。一旦缓存失效,Dockerfile中的其余指令就都失效了。
因此,从Dockerfile的顶部开始,如果基本镜像已经在缓存中,就会重复使用它。否则,缓存将失效。
图:击中
然后,将下一条指令与从该基本镜像派生的缓存中的所有子镜像进行比较。比较每个缓存的中间镜像,以查看指令是否找到缓存命中。如果是缓存未命中,则缓存无效。重复相同的过程,直到到达Dockerfile的末尾。
大多数新指令都只是与中间图像中的指令进行比较。如果存在匹配项,则使用缓存的副本。
例如,当RUN pip install -r requirements.txt
在Dockerfile中找到一条指令时,Docker会在其本地缓存的中间镜像中搜索同一条指令,不比较旧的和新的*requirements.txt*文件的内容。
如果您更新要求,则此行为可能会出现问题*requirements.txt*带有新软件包的文件并使用RUN pip install
并使用新的软件包名称重新运行软件包安装。我将在稍后展示一些解决方案。
与其他Docker指令不同,ADD和COPY指令需要Docker查看文件的内容,以确定是否存在缓存命中。将引用文件的校验和与现有中间镜像中的校验和进行比较。如果文件内容或元数据已更改,则缓存失效。
下面是一些有效使用缓存的技巧:
- 可以通过传递
--no cache=True
关闭docker build
。 - 如果要对指令进行更改,则随后的每一层都将被频繁重建。要利用缓存,请在Dockerfile中放置可能变化尽可能小的指令。
- Chain
RUN apt-get update
和apt-get install
命令以避免缓存未命中问题。 如果使用的是包安装程序(如pip)并带有*requirements.txt*文件,则请遵循以下模型,以确保您不会因使用*requirements.txt*中列出的旧软件包而收到陈旧的中间镜像。
CCOPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt
COPY . /tmp/
这些是有效使用Docker构建缓存的建议。
缩小尺寸
Docker镜像会变大,所以需要将它们保持的较小,以便可以快速拉出来并使用很少的资源。
让我们瘦下来的物品!
图:沙拉
Alpine基本镜像是一个完整的Linux发行版,没有太多其他内容。下载通常小于5MB,但它需要花费更多的时间来编写构建一个工作应用程序所需的依赖项的代码。
图:阿尔卑斯山
如果您的容器中需要Python,则可以使用Python Alpine构建。它包含Linux和Python,其他大部分都由您提供。
使用最新的Python Alpine构建并带有print(“ hello world”)脚本构建的图像重78.5 MB,这是Dockerfile:
FROM python:3.7.2-alpine3.8
COPY . /app
ENTRYPOINT [“python”, “./app/my_script.py”, “my_var”]
在Docker Hub网站上,基本镜像被列为29 MB。构建子镜像后,它会下载并安装Python,使其变得更大。 除了使用Alpine基本镜像外,另一种减小图像大小的方法是使用多级构建,该技术技术增加了Dockerfile的复杂性。
多阶段构建
图:一个阶段+另一个阶段=多阶段
多级构建使用多个FROM指令。您可以有选择地将文件(成为构建工件)从一个阶段复制到另一个阶段,可以在最后的图像中留下任何你不想要的内容。此方法可以减小整体图像大小。
每个FROM指令
- 开始构建的新阶段;
- 保留了先前阶段中创建的任何状态;
- 可以使用其他基础;
以下是Docker docs中多级构建的修改示例:
FROM golang:1.7.3 AS build
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=build /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
注意,我们通过在FROM指令后添加名称来命名第一阶段。然后,COPY --from=
稍后在Dockerfile 中的指令中引用命名的阶段。 多阶段构建在某些情况下是有意义的,可以在生产中制造大量的容器。多级构建可以从图像大小中挤出最后一盎司(如果用公制计算的话,则为克)。但是,有时多级构建会增加复杂性,使图像难以维护。
相比之下,每个人都应该使用.dockerignore文件来帮助保持其Docker镜像的外观。
.dockerignore
.dockerignore文件是您应该知道的一些知识。
.dockerignore类似于.gitignore。这是一个包含模式列表的文件,Docker可以使用这些模式与文件名进行匹配,并在制作镜像时将其排除。
图:.dockerginore
将.dockerginore文件与Dockerfile和其他构建上下文放在同一个文件夹中。
当您运行docker build
创建镜像时,Docker会检查.dockerignore文件。如果找到一个,它将逐行遍历文件并使用Go的filepath.Match规则 ,以及Docker的一些规则,匹配要排除的文件名考虑Unix风格的glob模式,而不是正则表达式。
因此*.jpg
将排除扩展名为*.jpg*的文件,并且videos
将排除视频文件夹及其内容。
您可以用以#
开头的注释来解释您在.dockrignore中所做的工作。
使用.dockergnore从Docker镜像中排除不需要的文件是一个好方法。.dockerignore可以:
- 帮助你保守秘密。没有人想要在图像中输入密码。
- 缩小图像大小。更少的文件意味着更小更快的图像。
- 减少生成缓存失效。如果日志或其他文件正在更改,而您的镜像因此而使其缓存失效,则会减慢构建周期。
这些就是使用.dockerignore文件的原因。
尺寸检查
如何从命令行找到Docker图像和容器的大小。
- 要查看正在运行的容器的大致大小,可以使用命令
docker container ls-s
。 - 运行
docker image ls
显示图像的大小。 - 要查看构成您的图像的中间图像的大小
docker image history my_
image:my_tag
。 - 运行
docker image inspect my_
image:tag
将显示有关图像的许多信息,包括每一 层的大小。图层与构成整个图像的图像有细微的不同。但在大多数情况下,你可以把它们看作是相同的。 - 安装和使用dive包可以很容易地查看层内容。
现在,让我们看一些简化操作的最佳实践。
八种减少图像大小和构建时间的最佳实践
- 尽可能使用官方的基本图像。官方图片定期更新,比f非官方图片更安全;
- 尽可能使用Alpine图像,以保持图像的轻量化。
如果使用apt,请在同一条指令中结合RUN apt get update和apt get install,然后在该指令中链接多个软件包。用
\
字符在多行按字母顺序列出包。例如:RUN apt-get update && apt-get install -y \
package-one \
package-two
&& rm -rf /var/lib/apt/lists/*
这种方法减少了要构建的层数,并保持了事物的整洁。
在RUN指令的末尾包含
&& rm -rf /var/lib/apt/lists/*
,以清理apt缓存,使其不存储在层中。通过在Dockerfile中较低位置的指令来使用缓存。
使用.dockerignore文件将不需要的和不必要的文件排除在图像之外。
检查 dive - 一个非常酷的工具,用于检查Docker图像层。
不要安装不需要的软件包。
结尾
以上就是Docker镜像快速构建,以及快速下载并且不占用太多空间的内容。学习是成功的一半。在本系列的下一篇文章中,将深入探讨基本的Docker命令,希望对你有帮助。
原文作者:Jeff Hale
原文地址:https://towardsdatascience.com/learn-enough-docker-to-be-useful-1c40ea269fa8
翻译:猪齿鱼技术团队
本文由猪齿鱼技术团队原创,转载请注明出处:猪齿鱼官网
关于猪齿鱼
猪齿鱼Choerodon全场景效能平台,提供体系化方法论和协作、测试、DevOps及容器工具,帮助企业拉通需求、设计、开发、部署、测试和运营流程,一站式提高管理效率和质量。从团队协同到DevOps工具链、从平台工具到体系化方法论,猪齿鱼全面满足协同管理与工程效率需求,贯穿端到端全流程,助力团队效能更快更强更稳定。戳此处试用猪齿鱼
Docker入门系列之四:Docker镜像的更多相关文章
- Docker入门系列之三:如何将dockerfile制作好的镜像发布到Docker hub上
这个系列的前两篇文章,我们已经把我们的应用成功地在Docker里通过nginx运行了起来,并且用dockerfile里制作好了一个镜像. Docker入门系列之一:在一个Docker容器里运行指定的w ...
- Docker入门系列(一):目标和安排
Docker入门系列(一) 这个系列的教程来源于docker的官方文档,此文档的目的在于一步一步学习docker的使用方法. 这一系列的教程有如下几篇文档: docker安装启动 构建第一个docke ...
- SpringBoot Docker入门,SpringBoot Docker安装
SpringBoot Docker入门,SpringBoot Docker安装 ================================ ©Copyright 蕃薯耀 2018年4月8日 ht ...
- Docker入门系列之五:15个 Docker 命令
在这篇文章中,我们将学习15个Dockers CLI命令.如果你还不了解Docker,请查看这个系列的其他部分进行学习,Docker概念,生态系统,Dockerfile,Docker镜像. Docke ...
- docker入门——安装(CentOS)、镜像、容器
Docker简介 什么是docker 官方解释: Docker is the company driving the container movement and the only container ...
- Docker入门系列2 安装
可以从 Docker 社区直接下载可用的模版或镜像. Docker容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多. 其次,Docker对系统资源的利用率很高,一台主机上可以同时运行数千个Do ...
- Docker入门系列1:简介
可以实现快速部署. 比如一台 16 核 32G 内存的虚拟机上,需要跑 500+ 个用户的应用(每个应用的功能可以认为是一个网站 + 一系列的 RESTful API),有两个事情很重要: 资源隔离: ...
- Docker入门系列之一:什么是Docker?
原文作者:Jeff Hale 原文地址:https://towardsdatascience.com/learn-enough-docker-to-be-useful-b7ba70caeb4b 翻译: ...
- docker入门(二)容器与镜像的理解
10张图带你深入理解Docker容器和镜像 申明:此篇文章是转载的(原文地址http://dockone.io/article/783),今天意外发现已经有人转载了(复制了),希望大家关注原创 原本打 ...
- docker入门(二)容器与镜像的关系
[编者的话]本文用图文并茂的方式介绍了容器.镜像的区别和Docker每个命令后面的技术细节,能够很好的帮助读者深入理解Docker. 这篇文章希望能够帮助读者深入理解Docker的命令,还有容器(co ...
随机推荐
- 大数据时代下,App数据隐私安全你真的了解么?
简介:你是否有过这样的经历:你和朋友聊天表达你近期想要购买某件商品,第二天当你打开某购物软件时,平台向你推送的商品正是你想要购买的:或者,你是否接到过陌生来电,他们准确的报出了你的名字和年龄.... ...
- 云效Codeup代码评审中的代码协同
简介: 云效 Codeup 汇集了阿里巴巴最新的代码托管.代码协同技术,希望能够造福更多中国和世界的开发者. 大神说:"Show me the code",于是就有了代码评审. & ...
- 配置审计(Config)配合开启OSS防盗链功能
简介: 本文作者:紫极zj 本文将主要介绍利用[配置审计]功能,如何快速发现企业上云过程中,针对未配置防盗链的 OSS Bucket 定位及修复案例. 前言 配置审计(Config)将您分散在各地域的 ...
- [Kali] Kali 信息收集
网络空间测绘. 网络空间测绘是2016年出现的一个概念,主要指用一些技术方法,来探测全球互联网空间上的节点分布情况和网络关系索引,构建全球互联网图谱的一种方法. nmap端口扫描. 子域名爆破. ...
- WPF 通过 WindowsAppSDK 使用 WinRT 的手写识别功能
本文告诉大家如何在基于 .NET 6 的 WPF 使用 WinRT 的手写识别功能 在开始之前需要先创建 WPF 项目,创建完成之后,可替换 csproj 项目文件为以下代码,用来安装初始化环境 &l ...
- Ubuntu RDP服务
这里先简单了解一下rdp和vnc的区别 VNC 就像我们使用向日葵一下远程操作别的电脑一下,只能有一人在操作 RDP 是无感式操作,在别人没知觉的情况下控制新的桌面 这是我个人的理解,有不对的地方望各 ...
- C语言程序设计-笔记5-数据类型和表达式
C语言程序设计-笔记5-数据类型和表达式 例6-1 大小写英文字母转换.输入一样字符,将其中的大写字母转换为相应的小写字母后输出,小写字母转换为相应的大写字母后输出,其他字符按原样输出. #incl ...
- vue--v-if和v-show的区别(个人项目中的理解应用)
在面试的时候,一道vue基础到不能再基础的面试题叫做v-if与v-show的区别,当然答案网上一搜一大堆,基本两句话就能说明: 1.相同点:都是根据指令是否渲染该组件 2.不同点:v-if仅重新渲染当 ...
- webapi授权认证
webapi授权认证 一.需要类包 Microsoft.AspNetCore.Authentication.JwtBearer 二.相关名词 Authentication(认证):标识用户的身份,一般 ...
- SAP集成技术(六)技术、标准和协议
本文链接:https://www.cnblogs.com/hhelibeb/p/17849837.html 内容摘录自<SAP Interface Management Guide>. W ...