原文作者:Jeff Hale
原文地址:https://towardsdatascience.co…
翻译:付新圆
在本文中,您将学习如何放慢 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 命令,心愿对你有帮忙。