gpt4 book ai didi

docker - 为什么主机的行为可能比 docker 容器更具确定性?

转载 作者:行者123 更新时间:2023-12-02 17:55:02 24 4
gpt4 key购买 nike

我们使用 Docker 来很好地定义构建环境并帮助确定性构建,但在我的机器上,我使用 Docker 的构建结果发生了微小的变化,但不使用 Docker 时则没有。

我做了相当广泛的测试并且没有想法:(

我在以下系统上进行了测试:

  • 一个 : 我的新电脑没有 Docker
  • AD1 :我的新 PC 和 Docker,使用基于 ubuntu:18.04 的 Dockerfile 编译“一年前”
  • AD2 : 我的新 PC 和 Docker,使用我们基于 ubuntu:19:10 的 Dockerfile 现在编译
  • :我的笔记本电脑(我已经将磁盘复制到我的新电脑上)没有 Docker
  • BD :我的带 Docker 的笔记本电脑
  • CD1 : 同事的笔记本电脑上的 Docker,使用我们基于 ubuntu:18.04 的 Dockerfile,“一年前”编译
  • CD2 : 同事的笔记本电脑和 Docker,使用我们基于 ubuntu 的 Dockerfile:19:10 现在编译
  • DD : 一个带有我们基于 ubuntu:18.04 的 Dockerfile 的 Digital Ocean VPS

  • 在所有场景中,我们都得到了两个构建结果中的任何一个,我将命名变体 X 和 Y。
  • 我们使用 A、B、CD1、CD2 和 DD 得到了变体 X。
  • 我们使用 AD1、AD2 和 BD 得到了变体 Y。

  • 自我们的 Android 应用程序发布多个版本以来,该问题一直可以 100% 重现。当我将 Docker 从 19.03.6 更新到 19.03.8 以匹配我同事的版本时,它并没有消失。那时我们都有 Ubuntu 19.10,而我现在不断遇到 Ubuntu 20.04 的问题。

    我总是将我们的项目新克隆到一个新文件夹中,使用disorderfs 来消除文件系统排序问题并将文件夹安装到docker 容器中。

    我怀疑它是否相关,但我们正在使用这个 Dockerfile:
    FROM ubuntu:18.04

    RUN dpkg --add-architecture i386 && \
    apt-get update -y && \
    apt-get install -y software-properties-common && \
    apt-get update -y && \
    apt-get install -y wget \
    openjdk-8-jre-headless=8u162-b12-1 \
    openjdk-8-jre=8u162-b12-1 \
    openjdk-8-jdk-headless=8u162-b12-1 \
    openjdk-8-jdk=8u162-b12-1 \
    git unzip && \
    rm -rf /var/lib/apt/lists/* && \
    apt-get autoremove -y && \
    apt-get clean

    # download and install Android SDK
    ARG ANDROID_SDK_VERSION=4333796
    ENV ANDROID_HOME /opt/android-sdk
    RUN mkdir -p /opt/android-sdk && cd /opt/android-sdk && \
    wget -q https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_VERSION}.zip && \
    unzip *tools*linux*.zip && \
    rm *tools*linux*.zip && \
    yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses

    还有 here是我运行并得到不同结果的构建指令。可以找到差异本身 here .

    编辑:我也将它归档为 bug on the docker repo .

    最佳答案

    Docker 并不完全独立于架构。对于不同的架构,您可能会有或多或少的细微差别。通常它不应该影响任何重要的事情,但可能会改变编译器的一些优化决策等等。如果您尝试使用非常不同的 CPU,例如 AMD64 与 ARM,则更明显。对于 Java 来说,这应该无关紧要,但似乎至少有时很重要。

    另一件事是网络和DNS。当您执行 apt-get、wget 和其他此类操作时,它会从网络下载代码或二进制文件。它可能会因您使用的 DNS 不同而有所不同(这可能会导致不同的服务器或不同的 repo url),并且可能会有一些细微的差异。理论上应该没有区别,但实际上有时会存在差异,例如当他们推出新版本时,它仅在某些节点上可见,或者发生了一些不好的事情,或者中间有一些缓存/代理并通过它连接并缓存等。

    后者也会造成出现时间上的差异。就像 app 是在一个月内编译的,有人试图在几周或几个月后进行验证,而 apt-get 会安装其他版本的库,实际上存在细微差别。

    我不确定哪个适用于此,但我有一些想法:

  • 可能会尝试对应用程序进行一些小的更改,因此实际上它会在大多数流行的 CPU 上再次构建相同的应用程序,进行广泛的测试,然后列出可以对其进行验证的架构
  • 使验证过程更加复杂和非免费,因此用户必须运行具有指定架构的服务器实例(在 AWS 或 Google 或 Azure 或 Rackspace 或其他上)并在那里构建和验证 - 可以尝试并指定在哪些类型的机器上结果将是相同的,最低要求是什么(因为它可能会或可能不会在免费计划实例上运行)
  • 检查创建的图像内容的差异(不仅是 apk,还有完整的系统图像),也许不同机器上的 docker 图像之间会有一些重要的不同,从而产生不同的结果
  • 尝试找到尽可能小的初始镜像,并且不允许 apt-get 或其他东西自动安装最新版本的依赖项,而是指定所有依赖项及其版本
  • 关于docker - 为什么主机的行为可能比 docker 容器更具确定性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61947996/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com