Docker图像会改变吗?如何确保他们不会?

Docker图像会改变吗?如何确保他们不会?,docker,Docker,Docker的主要优点之一是可复制性。例如,可以精确地指定安装哪些程序和库的方式和位置 然而,我正在努力想清楚这一点,我不能把我的头围绕着它。我对再现性的理解是,如果你要求某个标签,你每次都会收到相同内容的相同图像。然而,这有两个问题: 即使我尝试尽可能彻底地指定一个版本,例如python:3.8.3,我似乎也不能保证它指向一个静态的不改变的图像?一个新版本可以在任何时候推出 python:3.8.3是python:3.8.3-buster的同义词,它指的是它所基于的Debian-buster

Docker的主要优点之一是可复制性。例如,可以精确地指定安装哪些程序和库的方式和位置

然而,我正在努力想清楚这一点,我不能把我的头围绕着它。我对再现性的理解是,如果你要求某个标签,你每次都会收到相同内容的相同图像。然而,这有两个问题:

  • 即使我尝试尽可能彻底地指定一个版本,例如
    python:3.8.3
    ,我似乎也不能保证它指向一个静态的不改变的图像?一个新版本可以在任何时候推出
  • python:3.8.3
    python:3.8.3-buster
    的同义词,它指的是它所基于的Debian-buster操作系统映像。因此,即使Python没有改变,底层操作系统在某些包中也可能有改变,对吗?我查看了,它没有指定Debian Buster的特定版本或构建

如果您依赖外部docker图像,您的docker图像确实无法保证可复制性。解决方案是将Python:3.8.3映像导入您自己的Docker注册表,理想情况下是一个Docker注册表,可以防止标记重写(不变性),例如


但是,如果您的Docker图像比您导入的基础图像更硬,则会降低再现性。例如,如果您安装了一些pip软件包,而其中一个pip软件包没有锁定它们所依赖的软件包的版本,则您仍然无法保证重建Docker映像会导致相同的映像。在您自己的pip artifactory中托管这些python包也是这里的解决方案。

解决您的个人问题

  • 即使我尝试尽可能彻底地指定一个版本,例如python:3.8.3,我似乎也不能保证它指向一个静态不变的图像可以随时向其推送新版本。
我在对你的问题的评论中发表了这一点,但在这里也提到了这一点。大型软件包使用。为了使信任发挥作用,必须建立信任。这种版本控制方法为其他(有时是任意的)系统引入了信任和一致性

值得信赖的是,当他们上传
3.8.3
时,它将在未来尽可能保持不变。如果他们添加了另一个补丁,他们将上载
3.8.4
,如果他们添加了一个功能,他们将上载
3.9.0
,如果他们破坏了一个功能,他们将创建
4.0.0
。这可以确保您,即用户,
3.8.3
无论何时何地都是相同的

框架和操作系统通常使用后端口补丁。PHP就是因为这个而出名的。如果他们在v7中发现v5中存在的安全漏洞,他们将更新所有版本的v5。虽然所有v5版本都是从其原始发布版本更新而来,但功能保持不变。这很重要,这是信任

因此,除非你“利用”了这个安全漏洞来做你需要做的事情,或者依赖于一个bug,否则你应该相信DockerHub的
3.8.3
应该一直被使用

NodeJS就是一个很好的例子。为了存档,他们在Docker Hub中保留了所有不推荐的旧版本

我一直在工作和家庭的所有项目中使用Docker Hub的命名标签(不是
最新的
),而且我从来没有遇到过部署后项目因“脚下”发生变化而崩溃的问题。事实上,就在上周,我在一个旧版本的NodeJS(从4年前开始)上重新构建和更新了一些代码,该版本需要重新调用,并且因为它是一个命名版本(不是
最新的
),所以它完全按照预期工作

  • python:3.8.3是python:3.8.3-buster的同义词,它指的是它所基于的Debian-buster操作系统映像。因此,即使Python没有改变,底层操作系统可能在某些软件包中有所改变,对吗?我查看了官方Dockerfile,它没有指定Debian Buster的特定版本或版本
一旦子映像(python)是基于父映像(buster)构建的,它是不可变的。例外情况是,如果子映像(python)是在以后重建的,并且选择使用父映像(buster)的不同版本。但这被认为是不好的形式,偷偷摸摸,破坏了集装箱的用途。我不知道有哪个主要的软件包能做到这一点

这就像在更改了一些提交之后,在存储库上执行一个
git push--force
。这是非常糟糕的做法

该系统是在信任的基础上设计和构建的,为了让它得到使用、采用和发展,信任必须保持不变。始终检查要使用的任何容器的旧标记,并确保它们允许旧的不推荐的标记继续存在

因此,当您今天或两年后下载python:3.8.3时,它的功能应该完全相同

例如,如果您
docker拉python:2.7.8
,然后
docker检查python:2.7.8
,您会发现它与5年前创建的容器相同

        "Created": "2014-11-26T22:30:48.061850283Z",

诀窍可能是:使用自己的docker注册表。意思是:您无法控制位于internet某处服务器上的文件。但您可以完全控制自己的服务器。当然,这意味着您必须管理自己的服务器。Docker并不是要复制某个东西的精确克隆,而是要确保您的程序和服务之间具有相同的API兼容性。大多数大型软件包都遵循一个称为“语义版本控制”的概念。详情请访问semver.org。要点是,如果我发布v3.8.3,那么对v3.8.3的所有更新(安全更新、错误修复)都不能破坏v3.8.3。如果我添加了新功能,我将使用v3.9.0。如果我破坏了向后兼容性,我必须使用v4.0.0。这一过程确保