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

时间:2017-06-12 13:11:37

标签: docker docker-image

docker tag命令的标准用法是:

docker tag <image> <username>/<repository>:<tag>

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

来自Java-land,我已经习惯了group:artifact:version的Maven / Gradle风格坐标,所以对我来说,imagerepository是有意义的一个在同一个:

image是您正在制作的工件,而在Java-land中,生成的工件与其代码所在的源代码之间通常存在1:1的关系。所以对我而言,命令更有意义:

docker tag <username>/<repository>:<tag>

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

要清楚:询问图片与存储库之间的区别!我知道存储库是存储图像的位置,我知道图像是Docker可执行文件,包含您的Dockerized应用程序及其依赖项。但从命名的角度来看,我很困惑为什么/什么时候彼此不同。

所以我问:从命名约定的角度来看,imagerepository之间有什么区别?例如,如果我想创建自己的MySQL Docker镜像,我会选择将图像命名为“ myapp-db ”,这也是它所在的存储库的名称({ {1}},smeeb/myapp-db:v1等。)

那么在什么情况下/ smeeb/myapp-db:v2image名称应该不同?

3 个答案:

答案 0 :(得分:1)

如果您的图像在使用中已过时,则可以使用与存储库名称不同的图像的一种情况。

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

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

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

答案 1 :(得分:1)

首先是先决条件:标签是指向图像的指针,图像是sha256对do​​cker用于制作容器的配置和图层清单的引用。这意味着friendlyhello不是图像的名称,它是指向图像的标记。图像是id,类似于c75bebcdd211....

接下来,每个图像都可以包含指向它的零个,一个或多个标记。当它没有指向它的任何标签时,它被称为悬空图像。如果您使用标记构建图像,然后重建它,就会发生这种情况。之前的图像现在未标记,因为标记指向新图像。同样,您可以将标记image:latestimage:v1image:1.0.1myrepo:5000/image:1.0都指向相同的图片ID。

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

令人困惑的一点是,存储库名称末尾的短名称通常称为&#34;图像名称&#34;,冒号后的版本控制通常称为&#34;标记&#34;如果你忘了那些术语曾经像那样重载,我认为这更容易理解。

现在有了所有背景(抱歉,这很多),这里有一些问题的更正:

而不是:

docker tag <image> <username>/<repository>:<tag>

将语法想象为:

docker tag <source> <tag>

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

docker tag <username>/<repository>:<tag>

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

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

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

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

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

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

答案 2 :(得分:0)

必须说明图像和存储库之间的区别:

图像是标记的存储库。这只是唯一的区别。 <username>是存储库名称的一部分。

来自overview of the Docker Registry Distribution API

  

传统上,存储库名称一直是两个路径组件   其中每个路径组件少于30个字符。 V2注册表   API不会强制执行此操作。存储库名称的规则如下   如下:

     

存储库名称被分解为路径组件。一个组件   存储库名称必须至少为一个小写,字母数字   字符,可选地用句点,破折号或下划线分隔。   更严格一点,它必须与正则表达式匹配   [A-Z0-9] +(?:[._-] [A-Z0-9] +)*。如果存储库名称有两个或更多   路径组件,它们必须用正斜杠分隔(&#34; /&#34;)。该   存储库名称的总长度(包括斜杠)必须更小   超过256个字符。

只需为图像和标签使用有意义的名称。您可以smeeb/myappsmeeb/myapp-db。对于标签,惯例是使用版本化标签和latest标签。