gpt4 book ai didi

docker - 交换一层容器图像

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

我想知道是否有可能将一个容器镜像的层换成另一个。这是我的情况:
我有一个执行以下操作的 docker 文件:

  • 它拉动.net核心3.1 debian slim(buster)图像
  • 生成应用程序的源代码,并将其作为.net核心镜像
  • 之上的一层添加

    当出现新版本的.net core 3.1运行时镜像时,我想创建一个具有该新版本但在其顶部具有相同应用程序层的新镜像。
    我不想找到用于构建应用程序并重新构建的代码的确切版本。
    想法是复制机器和运行时的升级,但不对应用程序进行任何更改(较少测试升级)。
    是否存在可用于交换图像层的docker命令?

    最佳答案

    该答案分为两个不同的部分:

  • 第一部分:从源代码构建:解释为什么不应该执行此想法。
  • 第二部分:概念验证实现的CLI工具:我专门针对此问题实现的CLI工具,并进行了演示。

  • 如果不需要担心潜在的副作用,则可以跳过第一部分。

    第一部分:从源代码构建
    ,可能没有 docker命令-可能永远不会,因为技术问题很多。即使通过设计,这也不意味着平凡。图像和图层在构建后是不可变的。强烈建议改用原始来源的应用程序镜像,但通过修改 FROM命令使用新的基础镜像重建。
    有很多一致性问题使此想法不明智,以下列出其中一些:
  • 某些Dockerfile命令实际上并不创建图层,它们会更新最终图层的内部 list 和图像的 list 。声明Removing intermediate container XXXXXXXXXXXX的命令实际上是在更新上述 list ,而不是创建新层。从旧基础镜像交换到新基础镜像时,这需要正确更新唯一相关的更改;例如协调ENV/LABEL/MAINTAINER/EXPOSE/CMD/ENTRYPOINT命令中的更改。
  • 从先前基础镜像中继承的变量更改应用程序镜像配置的
  • ENV命令可能无法正确更新。例如,在应用程序镜像中,可能存在以下命令ENV命令:
    ENV PATH="/path:${PATH}"
    如果应用程序镜像的旧基础镜像层已换出,而新基础镜像包含另一个${PATH}变量,则在开发人员不手动决定的情况下,如何协调差异是不明确的。
  • 如果使用apt/apt-get/apk/yum安装Linux软件包,则这些软件包将作为后续层安装在应用程序镜像中。如果基础操作系统或可执行文件在新基础镜像层中发生更改,则不能保证已安装的软件包与新基础镜像兼容。

  • 第二部分:概念验证实现的CLI工具
    在技​​术上,可以通过对已构建的Docker应用程序镜像的镜像存档进行直接操作来“升级”镜像的基础。但是,我不能足够重申- ,甚至不应该尝试编辑现有图像的底层。认真地-停止它,寻求帮助。我90%确信这是 war 罪。
    为了彻底解决这个问题, 我在我的GitHub项目concision/docker-base-image-swapper 上开发了用Java编写的概念验证CLI工具,该工具旨在交换基本图像(但不是任意层)。我为解决各种一致性问题而做出的设计选择是对应该采取何种措施的“最佳猜测”。
    包括一个演示,该演示用于将已构建的Java应用程序镜像的基础镜像从JDK8交换到JDK11,并在 demo/demo.sh 脚本中实现。所有核心代码都在隔离的Docker容器中运行,因此只有Bash和Docker是主机上运行本演示所必需的依赖项。该演示应用程序镜像仅在JDK 8上构建一次,但是运行两次-一次在原始JDK 8镜像上运行,另一次在基于交换基础的JDK 11镜像上运行。
    如果您在使用该工具时遇到技术困难,则可能可以解决该问题。这个项目很快就被黑客入侵,并且代码质量很差;此外,它可能遭受各种无法解释的边缘情况的困扰。我可能会在接下来的一两个月内用Rust将其彻底重写,重点是可维护性和处理所有极端情况。

    Warning: I still do not advise trying to edit images; the use of the tool is at your own risk.


    这个概念
    此过程中有三张相关的图像,所有图像均已构建(即不需要原始资源):
  • 应用程序图像:当前基于旧基础图像的应用程序图像,但是需要交换到较新的基础图像。
  • 旧基础镜像:使用原始FROM中的Dockerfile命令,应用程序镜像所基于的旧基础镜像。
  • 新的基础图像:应该替代仅从FROM old-base-image层继承的应用程序图像层的较新的基础图像。

  • 通过知道应用程序镜像的哪些层和配置是从旧基础镜像继承的,可以将它们替换为新基础镜像中的层和配置。使用 docker save命令,可以将所有图像图层和 list 作为tar存档获得。借助所有相关的三个图像的存档,一个工具可以分析之间的差异

    关于替代品的警告
    谨防仅从旧应用程序镜像中执行 COPY --from=...,因为原始应用程序的镜像配置(通过 CMDENTRYPOINTENVEXPOSELABELUSERVOLUMEWORKDIR)将无法正确复制。

    关于docker - 交换一层容器图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64123071/

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