【问题标题】:How to do deterministic builds of Docker images?如何进行 Docker 镜像的确定性构建?
【发布时间】:2019-04-16 17:19:47
【问题描述】:

我正在尝试构建 Docker 映像,我希望我的 Docker 映像具有确定性。令我惊讶的是,我发现即使是一个微不足道的 Dockerfile,例如

FROM scratch
ENV a b

使用docker build --no-cache .重复构建时产生不同的ID

如何使我的构建具有确定性以及导致图像 ID 变化的原因是什么?启用缓存后,会生成相同的 ID。

我试图获得这种可重复性的原因是为了能够在分布式构建环境中生成相同的层。我无法控制构建运行的位置,因此我不知道缓存中有什么。 此外,Docker 构建使用 wget 从 ftp 下载文件,该文件可能已更改也可能未更改,目前我无法轻易地从 Dockerfile 中告诉 Docker,如果 RUN 的结果应该使缓存无效。因此,如果我可以为相同的层生成相同的 ID(当不使用缓存时),这些层就不必再次“推”和“拉”。

还有这里列出的所有原因:https://reproducible-builds.org/

【问题讨论】:

  • 你为什么想要这种行为?如果您只想确定引用图像,请使用docker build -t tag . 标记它
  • 这种行为对您有什么影响?
  • 启用缓存时,我认为守护进程不会创建新图像。守护进程检测到层是相同的,因此它不会构建新图像。
  • 我编辑了问题并提供了我的用例。
  • 但是为什么你需要告诉Docker缓存是否应该失效呢? Docker 可以自己解决这个问题

标签: docker


【解决方案1】:

AFAIK,目前 docker 图像不散列到字节精确散列,因为元数据当前包含状态信息,例如创建日期。您可以查看design doc from 1.10。不幸的是,历史元数据似乎是图像有效性和识别的重要组成部分。

不要误会我的意思,我只关注可重现的构建。但是,我不认为哈希精确度是衡量 docker 图像可重复性的最佳标准。泊坞窗图像不是已编译的二进制文件。没有办法保证一个阶段的结果能够被复制,所以即使没有日期时间元数据,它也不能保证可复制的构建。举这个病态的例子:

RUN curl "https://www.random.org/strings/?num=1&len=20&digits=on&unique=on&format=plain&rnd=new" -o nonce.txt

【讨论】:

  • hash-exactness 的好处在于它暗示了其他形式的准确性,并且很容易测试。与说“相同的行为”相比,这有时是一个停止问题!
  • 没错。 Docker 镜像是一种支持再现性的方式。它们更便携(比本地编译)、更少耦合(比系统动态链接库)、更可重现,但它们不是绝对可移植、解耦或可重现的,因为就像你说的那样,这需要定义绝对行为,这是一个不完整的Entscheidungsproblem:p
  • 大声笑,“在本文中,我们通过展示图灵机上相同的程序产生相同的输出来解决停机问题的受限变体”:)
【解决方案2】:

图像 ID 是图像配置对象的 SHA256(当您执行 docker image inspect 时得到的)。使用您正在创建的图像运行此程序,您将看到它们之间的差异。

【讨论】:

    猜你喜欢
    • 2020-10-06
    • 1970-01-01
    • 2019-06-22
    • 2020-06-02
    • 1970-01-01
    • 2017-12-22
    • 2022-11-11
    • 1970-01-01
    • 2021-02-27
    相关资源
    最近更新 更多