Docker 映像及其存储库何时会具有不同的名称?

sme*_*eeb 6 docker docker-image

docker tag命令的标准用法是:

docker tag <image> <username>/<repository>:<tag>
Run Code Online (Sandbox Code Playgroud)

例如:docker tag friendlyhello john/get-started:part1

来自 Java 领域,我习惯了 Maven/Gradle 风格的坐标group:artifact:version,所以对我来说,将 theimage和 therepository放在同一个是有意义的:

image是您正在生产的工件,在 Java 领域,生成的工件与其代码所在的源存储库之间通常存在 1:1 的关系。所以对我来说,命令更有意义:

docker tag <username>/<repository>:<tag>
Run Code Online (Sandbox Code Playgroud)

例如:docker tag john/get-started:part1,其中john是用户名/组,get-started是工件/存储库,part1是标签/版本。

明确:不是在问图像和存储库之间有什么区别!我了解存储库是存储图像的位置,并且我了解图像是 Docker 可执行文件,由 Dockerized 应用程序及其依赖项组成。但是从命名的角度来看,我很困惑为什么/何时它们应该彼此不同。

所以我问:从命名约定的角度来看,animage和 a之间有什么区别repository?例如,如果我想使自己的数据库码头工人的形象,我会选择做一个名为“图像的myapp-DB ”,这也将是在那里居住的存储库的名称(smeeb/myapp-db:v1smeeb/myapp-db:v2,等)。

那么在什么情况下/应该imagerepository名称不同?

BMi*_*tch 5

首先是先决条件:标签是指向图像的指针,图像是对 docker 用于创建容器的配置和层清单的 sha256 引用。这意味着这friendlyhello不是图像的名称,而是指向图像的标签。图像是 id,类似c75bebcdd211.....

接下来,每个图像可以有零个、一个或多个全部指向它的标签。当它没有任何标签指向它时,这被称为悬空图像。如果您构建带有标签的映像,然后重建它,则可能会发生这种情况。之前的图像现在已取消标记,因为标记指向新图像。同样,您可以让标签image:latestimage:v1image:1.0.1myrepo:5000/image:1.0全部指向相同的图像 ID。

标签有双重用途。它们可以是为了方便。但它们也被docker pushdocker pull用来查找发送或检索包裹的位置。如果你不做推或拉,那么你可以随意命名它,没有人会知道其中的区别。但如果您确实想将其存储在注册表中,则标签需要识别哪个注册表或默认的 docker hub。该标签还需要标识注册表上的路径(称为存储库)以及冒号后面的版本控制。

一个令人困惑的地方是,存储库名称末尾的短名称通常称为“图像名称”,而冒号后面的版本控制通常称为“标签”,我认为如果您忘记的话,这会更容易理解这些术语曾经像这样超载过。


现在有了所有这些背景(抱歉,太多了),以下是对这个问题的一些更正:

代替:

docker tag <image> <username>/<repository>:<tag>
Run Code Online (Sandbox Code Playgroud)

将语法视为:

docker tag <source> <tag>
Run Code Online (Sandbox Code Playgroud)

其中<source>可以是图像 ID 或其他标签名称。这意味着以下命令没有意义:

docker tag <username>/<repository>:<tag>
Run Code Online (Sandbox Code Playgroud)

因为docker tag需要一个源来标记,并且它对您当前正在使用的图像没有上下文感知。


最后,为什么要使用图像的存储库名称以外的名称,以下是我遇到的一些原因:

  1. 该图像不会被推送到存储库。它可以用于本地测试,或者工作流程中的中间步骤,或者您在同一系统上构建和运行图像。

  2. 同一个图像可能有多个名称。registry/repo/image:v1registry/repo/image:v1.0.1是一个常见的例子。我还将在特定环境中标记当前映像,并registry/repo/image:STAGE注意它已通过开发和 CI,现在处于暂存环境中。

  3. 您可能会在注册表之间移动图像。我们从 hub.docker.com 提取图像并使用本地注册表在本地重新标记它们。这为我们提供了本地缓存,也为我们提供了一种控制何时将基础映像更新到下一个版本的方法。这比在生产部署过程中更新更新映像更好。

  4. 我还使用标签来覆盖上游图像。因此,我不必更改所有构建脚本来解决上游映像的问题,而是可以进行更改并使用上游名称对其进行标记。然后,只要我不在该 docker 主机上运行拉取,构建就会使用我修改后的基础映像运行。


eaw*_*den 1

一种情况是,您使用的图像已过时,而图像的标签与存储库名称不同。

例如,您下载并运行 MySQL:5 映像。当您提取较新版本的 MySQL:5 映像时,此容器仍在运行。此时,旧映像将被取消标记(只能通过其哈希来识别),但不会被删除,因为它仍在由正在运行的 MySQL 容器使用。

另一种情况是,您可以在构建新映像时拥有中间映像。基本上每一行都会作为一个新图像提交,但它们不会以您指定的最终图像名称来命名。

使用时docker tag您甚至不必使用图像名称作为第一个参数。您甚至可以使用要标记的图像的哈希值作为第一个参数,因此它比命名空间/存储库更灵活:标记。