我应该使用Dockerfiles还是映像提交?


81

我对这两个选项有些困惑。它们似乎是相关的。但是,它们并不是真正兼容的。

例如,似乎使用Dockerfiles意味着您不应该真正提交映像,因为您实际上应该只在git中跟踪Dockerfile并对其进行更改。那么什么是权威性就没有歧义。

但是,图像提交看起来确实不错。太好了,您可以直接修改容器并标记更改以创建另一个图像。我了解您甚至可以从映像提交历史记录中获得类似文件系统差异的信息。太棒了 但是,您不应该使用Dockerfiles。否则,如果您提交了映像,则必须返回到Dockerfile并进行一些更改,以代表您的所作所为。

所以我很伤心。我喜欢图像提交的想法:您不必在Dockerfile中表示图像状态-您可以直接对其进行跟踪。但是,我对于放弃某种清单文件的想法感到不安,该清单文件使您可以快速概览图像中的内容。同样在同一软件包中看到两个似乎不兼容的功能也令人不安。

有人对此有任何想法吗?使用图像提交是否被认为是不好的做法?还是我应该放开我的附件来存放人偶时代的清单文件?我该怎么办?

更新资料

对于所有认为这是基于意见的问题的人,我不确定。它具有一些主观上的特质,但我认为这主要是一个客观问题。此外,我相信就该主题进行良好的讨论将提供信息。

最后,我希望阅读本文的任何人都能对Dockerfile和映像提交之间的相互关系有更好的了解。

更新-2017/7/18

我最近才发现图像提交的合法用途。我们只是在公司建立了一条CI管道,在管道的一个阶段中,我们的应用程序测试在容器内运行。在测试运行程序进程在容器的文件系统中生成覆盖结果之后,我们需要从已存在的容器中检索覆盖结果。我们使用图像提交来执行此操作,方法是提交已停止的容器以创建新图像,然后运行显示覆盖文件并将其转储到stdout的命令。所以拥有这个很方便。除了这种非常具体的情况之外,我们使用Dockerfiles定义我们的环境。


2
这里有很多哲学,人们的哲学也不尽相同,这对于SO来说可能是个坏问题。不过,我自己的哲学是-您始终想确切地知道如何复制给定的图像,并确保可以做到。使用黄金图像,很容易不知道某人是如何从状态A进入状态B的,而使用自动化来驱动构建过程,则无法忘记。因此,就我个人而言,是的,我将Dockerfiles称为“正确的事情”,并且映像提交(就像任何依靠手动干预来构建的金色映像一样)都是邪恶的。但这就是我,还有YMMV。
查尔斯·达菲

@CharlesDuffy如果这个问题不属于SO,应该去哪里?
David Sanders 2014年

1
@CharlesDuffy顺便说一句,我不同意这是一个基于观点的问题。如果不是一个正确的答案,这取决于更多的上下文,那么这里应该有一个正确的答案。仅供参考,我确实投票过将问题移到Serverfault。
大卫·桑德斯

2
... *耸肩*。我可以列举我偏爱的具体原因,但这是否使它们比别人为他们的具体原因更正确?我曾与那些拥护黄金形象方法的人一起工作,并且并非总是可以通过引用事实来赢得某人,因为当事方可以在不同程度上对解决方案中的不同特征进行估价,因此完全有可能就事实达成共识但不同意结论。这是一个基于观点的问题的标志,也是我期望看到的是否真的有金色的图像爱好者出现在这里。
查尔斯·达菲

1
我一直在想同样的事情,而我的印象(可能是完全错误的)是,它与vms的情况相同->您不想不知道如何重新创建vm映像。以我为例,我要安装常规的.sh脚本,并且想知道为什么我不能仅维护它们,运行docker并有效地调用它们,并以这种方式创建黄金版本映像。我的脚本可以将其安装在本地PC上,而我想使用docker的原因是要处理多个程序实例的冲突/拥有干净的文件系统/等
Bradford Medeiros,2017年

Answers:


47

Dockerfiles是用于创建映像的工具。

运行的结果docker build .是带有提交的映像,因此无法在未创建提交的情况下使用Dockerfile。问题是,每次发生任何变化时,您是否都要手动更新图像,从而注定自己会遭受黄金图像的诅咒

黄金图像的诅咒是一个可怕的诅咒,对那些必须继续使用漏洞百出的安全漏洞和基础图像来运行其软件的人们来说,这是一个可怕的诅咒,因为创建该图像的人很久以前就被古代的人吞噬(或转移到新工作),没人知道他们从哪里获得了进入该图像的imagemagic版本。这是唯一可以与老板的儿子三年前雇用的顾问提供的c ++模块链接的东西,无论如何都没关系,因为即使您弄清楚了imagemagic来自于libstdc ++所使用的版本, JNI在支持工具中称创建长发的实习生仅存在于不受支持的ubuntu版本中。


3
在我看来,这实际上似乎是问题的核心。如果仅使用图像提交,那么您将无法使用基本图像。您可以对图像进行远程升级,但这听起来像一场噩梦。在Dockerfile中干净地呈现这种信息似乎更可取。我认为Docker不应该将映像提交作为其公共API的一部分公开。除了介绍性文档中的说明目的外,似乎对它们没有任何合法用途。
大卫·桑德斯

7
我不只是把那个例子编造出来... :-(
Arthur Ulfeldt

22

知道解决方案的优点和不便之处是一个好的开始。因为将两者混合可能是一种有效的方法。

缺点:避免黄金形象死角:

如果您不了解如何重建映像,则仅使用提交是不好的。您不想处于无法重建映像的状态。这种最终状态在这里称为黄金形象因为该图像将是您在每个阶段的唯一参考,起点和终点。如果您松开它,将会遇到很多麻烦,因为您无法重建它。致命的死角是有一天您需要重建一个新的一天(例如,因为所有系统库都已过时),而且您也不知道要安装什么...最终会浪费大量时间。

附带说明一下,如果历史记录日志像git一样容易使用(请咨询diff,并在其他图像上重复它们),那么使用commits而不是commits会更好:您会注意到git没有这个难题。

专业版:精巧升级可分发

另一方面,分层提交在分布式升级方面(因此在带宽和部署时间方面)具有相当可观的优势。如果您是在面包师正在处理煎饼时开始处理docker映像(这正是docker所允许的),或者想要立即部署测试版本,则您会更愿意以小提交(而不是小提交)的形式发送小更新全新的形象。特别是在与客户进行持续集成的情况下,应尽快并经常部署错误修复程序。

尝试充分利用两个世界:

在这种情况下,您可能需要标记图像的主要版本,它们应该来自Dockerfiles。由于基于标记版本的提交,因此您可以提供连续的集成版本。这缓解了Dockerfile和分层提交场景的优点和不便之处。在这里,关键是您永远不会通过限制允许对图像进行的提交次数来跟踪图像。

因此,我想这取决于您的情况,您可能不应尝试找到一条规则。但是,无论解决方案如何,您都应避免使用某些实际的死胡同(最终以“黄金形象”场景结束)。


从修改过的Dockerfile重建后,Docker不会智能地重建映像,以致您不需要下拉整个新映像来进行部署吗?
大卫·桑德斯

1
@DavidSanders您不会以下载全新的图像而告终,您是对的。但是,任何结果变化的早期指导将使随后的整个层次失效。众所周知,“ ADD”或任何依赖指令通常是您最后可以执行一次新提交的指令,但是如果重新构建Dockerfile,它将生成全新的层。围绕'ADD'做出了一些努力,使其变得更加聪明github.com/docker/docker/issues/880,另请参见 jpetazzo.github.io/2013/12/01/docker-python-pip-requirements
vaab 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.