当前位置: 首页 > 面试题库 >

Dockerfile中的多运行与单链运行,哪个更好?

贲言
2023-03-14
问题内容

Dockerfile.1执行多个RUN

FROM busybox
RUN echo This is the A > a
RUN echo This is the B > b
RUN echo This is the C > c

Dockerfile.2 加入他们:

FROM busybox
RUN echo This is the A > a &&\
    echo This is the B > b &&\
    echo This is the C > c

每个RUN层都创建一个图层,因此我一直以为图层越少越好,因此Dockerfile.2越好。

当a RUN删除前一个RUN(即yum install nano && yum clean all)添加的内容时,这显然是正确的,但是在每个都RUN添加了内容的情况下,我们需要考虑以下几点:

  1. 层应该只是在前一层之上添加差异,因此如果后一层没有删除在前一层中添加的内容,那么这两种方法之间就没有太多的磁盘空间节省优势…

  2. 层是从Docker Hub并行拉出的,因此Dockerfile.1,尽管可能稍大一些,但理论上可以更快地下载。

  3. 如果添加第4句(即echo This is the D > d)并在本地重建,Dockerfile.1由于使用了缓存,构建起来会更快,但是Dockerfile.2必须再次运行所有4条命令。

所以,问题是: 哪种更好的方式来制作Dockerfile?


问题答案:

如果可能,我总是将创建文件的命令与将相同文件删除到同一RUN行的命令合并在一起。这是因为每一RUN行都在图像上添加了一层,输出实际上是文件系统更改,您可以docker diff在其创建的临时容器上查看该文件系统更改。如果删除在不同层中创建的文件,则联合文件系统所做的全部工作就是在新层中注册文件系统更改,该文件仍存在于上一层中,并通过网络运送并存储在磁盘上。因此,如果您下载源代码,将其解压缩,将其编译为二进制文件,然后最后删除tgz和源文件,则您确实希望所有这些操作都在单个层中完成以减小图像大小。

接下来,我根据图层在其他图像中可重复使用的潜力以及预期的缓存使用情况来将其拆分。如果我有4个映像,所有映像都具有相同的基本映像(例如debian),则可以将大多数这些映像的通用实用程序集合拉入第一个运行命令,以便其他映像可以从缓存中受益。

在查看映像缓存重用时,Dockerfile中的顺序很重要。我查看的是很少更新的任何组件,可能只有在基本映像更新并将其放在Dockerfile中时才会更新。在Dockerfile的末尾,我包含了所有将快速运行并且可能会经常更改的命令,例如,添加具有主机特定UID的用户或创建文件夹并更改权限。如果容器包含正在积极开发的解释代码(例如JavaScript),则将其添加到尽可能晚的位置,以便重建仅运行该单个更改。

在所有这些更改组中,我都尽力整合以最小化层。因此,如果有4个不同的源代码文件夹,则将它们放在单个文件夹中,以便可以使用单个命令将其添加。如果可能,从apt-
get之类的任何软件包安装都将合并到一个RUN中,以最大程度地减少软件包管理器的开销(更新和清理)。

多阶段构建的更新:

对于在多阶段构建的非最终阶段减小图像大小,我不必担心太多。如果没有标记这些阶段并将其传送到其他节点,则可以通过将每个命令拆分到单独的RUN行来最大程度地提高缓存重用的可能性。

但是,这不是挤压层的完美解决方案,因为您在阶段之间复制的全部是文件,而不是其余的图像元数据,例如环境变量设置,入口点和命令。而且,当您在Linux发行版中安装软件包时,库和其他依赖项可能分散在整个文件系统中,从而很难复制所有依赖项。

因此,我使用多阶段构建来代替在CI / CD服务器上构建二进制文件,因此我的CI / CD服务器仅需要具有运行的工具docker build,而没有jdk,nodejs,go和安装的任何其他编译工具。



 类似资料:
  • 我正在尝试在我的环境中测试和使用docker。这是我访问tomcat时的Dockerfile(),我发现这个问题。 注= 建筑 跑 Dockerfile 一件奇怪的事情是,如果我只设置而不设置,我就可以访问或我的应用程序我的文件中是否缺少任何内容? 谷歌搜索=

  • 我有一个大型java应用程序,在不同的类中有5个主要方法。我想将此应用程序作为docker容器运行。从DockerHub OpenJDK映像中,我启动了Dockerfile,如下所示 我想添加行来运行主要方法。没有Docker,我使用下面的行运行应用程序 是否可以在一个docker容器中运行上述场景?如果可能,当Dockerfile中只能有一条和指令时,如何实现这一点?

  • 问题内容: 我一直在阅读和学习有关Docker的知识,并试图正确选择要使用的Django设置。到目前为止,有: Docker Compose 或Dockerfile 我了解在中使用了,但是我不确定是否将所有内容放入一个大的Dockerfile中并用多个命令处理不同的映像是否是一个好习惯? 我想使用几个不同的图像,包括: 请提供关于使用 Docker 设置此类环境的最佳实践的建议。 如果有帮助,我在

  • 问题内容: 我正在尝试在Dockerfile的构建过程中运行脚本。但这似乎不起作用。 我尝试过这种方式: 也这样: 并且也执行我正在运行的容器: 似乎没有任何作用。 你知道怎么做吗? 问题答案: 和是执行脚本的两种不同方式。 意味着它将创建一个中间容器,运行脚本并将该容器的新状态冻结在新的中间映像中。此后该脚本将不再运行:您的最终图像应该反映出该脚本的结果。 表示您的映像(尚未执行脚本)将创建一个

  • 嗨,我是新的Docker和尝试写一个新的图像从头开始。我编写这个dockerFile是为了编译和运行一个在同一个目录中可用的简单java程序。 这是DockerFile。 Docker构建成功,如下所示

  • 问题内容: 如何在一台机器上运行多个JVM?您如何在其他JVM中调用方法? 问题答案: 如何在一台机器上运行多个JVM? 只需启动多个进程即可。 您如何在其他JVM中调用方法? 使用任何类型的RPC框架(RMI,EJB,Web服务等)。