[参考美国儿童童话《可以的小引擎》 - 大约。 车道]*
如何根据您的需求自动创建小型 Docker 镜像
不寻常的痴迷
在过去的几个月里,我一直痴迷于一个问题:Docker 镜像可以有多小,并且应用程序仍然可以运行?
我明白,这个想法很奇怪。
在讨论细节和技术细节之前,我想解释一下为什么这个问题让我如此困扰,以及它与您有何关系。
为什么尺寸很重要
通过减少 Docker 镜像的内容,我们从而减少了漏洞列表。 此外,我们使图像更清晰,因为它们仅包含运行应用程序所需的内容。
还有一个小优点 - 图像下载速度稍快一些,但是,在我看来,这并不是那么重要。
请注意:如果您担心尺寸,Alpine 外观本身较小,可能会适合您。
无 Distroless 图像
pip
и apt
不会起作用:
FROM gcr.io/distroless/python3
RUN pip3 install numpy
使用 Python 3 distroless 镜像的 Dockerfile
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM gcr.io/distroless/python3
---> 556d570d5c53
Step 2/2 : RUN pip3 install numpy
---> Running in dbfe5623f125
/bin/sh: 1: pip3: not found
图像中没有 Pip
通常这个问题可以通过多阶段构建来解决:
FROM python:3 as builder
RUN pip3 install numpy
FROM gcr.io/distroless/python3
COPY --from=builder /usr/local/lib/python3.7/site-packages /usr/local/lib/python3.5/
多阶段组装
结果是大小为 130MB 的图像。 还不错! 作为比较:默认的 Python 镜像大小为 929MB,“较薄”的镜像大小 (3,7-slim
) - 179MB,高山图像 (3,7-alpine
)为 98,6MB,而示例中使用的基本 distroless 映像为 50,9MB。
公平地说,在前面的示例中,我们正在复制整个目录 /usr/local/lib/python3.7/site-packages
,其中可能包含我们不需要的依赖项。 尽管很明显,所有现有Python基础镜像的大小差异各不相同。
在撰写本文时,Google distroless 不支持很多图像:Java 和 Python 仍处于实验阶段,Python 仅存在于 2,7 和 3,5 版本。
微小的图像
回到我对创建小图像的痴迷。
总的来说,我想看看 distroless 图像是如何构建的。 distroless 项目使用 Google 的构建工具 bazel
。 然而,安装 Bazel 并编写自己的镜像需要做很多工作(说实话,重新发明轮子既有趣又具有教育意义)。 我想简化较小图像的创建:创建图像的行为应该非常简单, 平庸的。 这样就不需要您的配置文件,只需在控制台中输入一行: просто собрать образ для <приложение>
.
所以,如果你想创建自己的镜像,那么就知道:有这样一个独特的 docker 镜像, scratch
。 Scratch 是一个“空”图像,其中没有文件,尽管默认情况下它的重量 - 哇! - 77 字节。
FROM scratch
划痕图像
临时镜像的想法是,您可以将任何依赖项从主机复制到其中,然后在 Dockerfile 中使用它们(这就像将它们复制到 apt
并从头开始安装),或者稍后在 Docker 镜像实现后安装。 这可以让你完全控制Docker容器的内容,从而完全控制镜像的大小。
现在我们需要以某种方式收集这些依赖项。 现有的工具如 apt
允许你下载软件包,但它们与当前机器绑定,毕竟不支持 Windows 或 MacOS。
因此,我开始构建自己的工具,该工具可以自动构建尽可能最小尺寸的基础映像并运行任何应用程序。 我使用 Ubuntu/Debian 软件包,进行选择(直接从存储库获取软件包)并递归地找到它们的依赖项。 该程序应该自动下载最新的稳定版本的软件包,尽可能地降低安全风险。
我给这个工具起了个名字 fetchy
,因为他...找到并带来...需要的东西[源自英语“取”,“带来” - 大约。 车道]。 该工具通过命令行界面工作,但同时提供 API。
使用以下方式组装图像 fetchy
(这次我们使用Python图像),你只需要像这样使用CLI: fetchy dockerize python
。 可能会要求您提供目标操作系统和代号,因为 fetchy
目前仅使用基于 Debian 和 Ubuntu 的软件包。
现在您可以选择根本不需要哪些依赖项(在我们的上下文中)并将其排除。 例如,Python 依赖于 perl,尽管在没有安装 Perl 的情况下它也能正常工作。
结果
使用命令创建的Python图像 fetchy dockerize python3.5
重量仅为 35MB(我非常确定将来它可以做得更轻)。 事实证明,我们成功地从 distroless 镜像中又削减了 15 个 WW。
您可以看到迄今为止收集的所有图像
项目 -
如果您缺少功能,只需创建一个请求 - 我很乐意提供帮助:)更重要的是,我目前正在努力将其他包管理器集成到 fetchy 中,以便不需要多阶段构建。
来源: habr.com