Docker 图像和它的存储库什么时候会有不同的名称?
When would a Docker image and its repository have different names?
docker tag
命令的标准用法是:
docker tag <image> <username>/<repository>:<tag>
例如:docker tag friendlyhello john/get-started:part1
.
来自Java-land,我习惯Maven/Gradle-style坐标group:artifact:version
,所以对我来说,image
和repository
成为同一个:
image
是您正在生成的工件,在 Java 领域中,生成的工件与其代码所在的源代码库之间通常存在 1:1 关系.所以对我来说,命令只是:
更有意义
docker tag <username>/<repository>:<tag>
例如:docker tag john/get-started:part1
,其中 john
是 username/group,get-started
是 artifact/repo,part1
是 tag/version.
要清楚:我不是问图像和存储库之间的区别!我知道存储库是存储图像的位置,我知道图像是一个 Docker 可执行文件,由 Docker 化的应用程序及其依赖项组成。但是从命名的角度来看,我很困惑 why/when 它们应该彼此不同。
所以我问:从命名约定的角度来看,image
和 repository
有什么区别?例如,如果我想制作自己的 MySQL Docker 图像,我会选择制作名为“myapp-db”的图像,这样也会是它所在的存储库的名称(smeeb/myapp-db:v1
、smeeb/myapp-db:v2
等)。
那么在什么情况下are/should image
和repository
名字会不同呢?
一种情况下,如果您使用的图像已过时,则图像的标签可能与存储库名称不同。
例如,您下载 运行 一张 MySQL:5 图片。当您拉取更新版本的 MySQL:5 图像时,此容器仍然是 运行ning。那时旧图像将被取消标记(只能通过其哈希识别),但不会被删除,因为它仍在被 运行ning MySQL 容器使用。
另一种情况是,您可以在构建新图像时使用中间图像。基本上每一行都会作为一个新图像提交,但它们不会以您指定的名称命名为最终图像名称。
使用 docker tag
时,您甚至不必将图像名称用作第一个参数。您甚至可以使用要标记的图像的哈希值作为第一个参数,因此它比 namespace/repository:tag.
更灵活
必须说明图像和存储库之间的区别:
图像是标记的存储库。这就是 仅 的区别。 <username>
是存储库名称的一部分。
来自overview of the Docker Registry Distribution API:
Classically, repository names have always been two path components
where each path component is less than 30 characters. The V2 registry
API does not enforce this. The rules for a repository name are as
follows:
A repository name is broken up into path components. A component of a
repository name must be at least one lowercase, alpha-numeric
characters, optionally separated by periods, dashes or underscores.
More strictly, it must match the regular expression
[a-z0-9]+(?:[._-][a-z0-9]+)*. If a repository name has two or more
path components, they must be separated by a forward slash ("/"). The
total length of a repository name, including slashes, must be less
than 256 characters.
只需为您的图片和标签使用有意义的名称。你可以有 smeeb/myapp
和 smeeb/myapp-db
。对于标签,惯例是使用版本标签和一个 latest
标签。
首先是先决条件:标签是指向图像的指针,图像是 docker 用于制作容器的配置和层清单的 sha256 引用。这意味着 friendlyhello
不是图像的名称,它是指向图像的标签。图片是id,类似于c75bebcdd211....
.
接下来,每个图像可以有零个、一个或多个标签都指向它。当它没有任何指向它的标签时,这被称为悬挂图像。如果您构建带有标签的图像,然后重建它,就会发生这种情况。之前的图像现在未标记,因为标记指向新图像。同样,您可以让标签 image:latest
、image:v1
、image:1.0.1
和 myrepo:5000/image:1.0
都指向相同的图像 ID。
标签有双重用途。它们可以是为了方便。但是 docker push
和 docker pull
也使用它们来查找发送或检索包裹的位置。如果你不做推或拉,那么你可以随意命名,没有人会知道其中的区别。但是,如果您确实想将其存储在注册表中,则标签需要标识哪个注册表或默认的 docker 集线器。并且该标记还需要标识注册表上的路径,称为存储库,以及冒号后的版本控制。
一个令人困惑的地方是存储库名称末尾的短名称通常称为 "image name",而冒号后的版本控制通常称为 "tag",我认为这如果您忘记了这些术语曾经像那样超载,就更容易理解。
现在有了所有这些背景(抱歉,内容太多),这里是对问题的一些更正:
而不是:
docker tag <image> <username>/<repository>:<tag>
将语法视为:
docker tag <source> <tag>
其中 <source>
可以是图像 ID,或其他标签名称。这意味着以下命令没有意义:
docker tag <username>/<repository>:<tag>
因为 docker tag
需要一个来源来标记,并且它对您当前正在处理的图像没有上下文感。
最后,为什么要为图像使用存储库名称以外的名称,以下是我遇到的几个原因:
图像不会被推送到存储库。它可能用于本地测试,或工作流程中的中间步骤,或者您在同一系统上构建和 运行 您的图像。
同一张图片可以有多个名称。 registry/repo/image:v1
和 registry/repo/image:v1.0.1
是一个常见的例子。我还将在特定环境中使用 registry/repo/image:STAGE
标记当前图像,以注意它已通过开发和 CI 并且现在处于暂存环境中。
您可能在注册表之间移动图像。我们从 hub.docker.com 中提取图像并使用本地注册表在本地重新标记它们。这既为我们提供了本地缓存,也为我们提供了一种控制何时将基础图像更新到下一个版本的方法。这比在产品发布过程中更新映像更可取。
我还使用标签来覆盖上游图像。因此,我无需针对上游图像的问题更改所有构建脚本,而只需进行更改并使用上游名称对其进行标记即可。然后只要我不 运行 拉那个 docker 主机,构建就会 运行 使用我修改后的基础映像。
docker tag
命令的标准用法是:
docker tag <image> <username>/<repository>:<tag>
例如:docker tag friendlyhello john/get-started:part1
.
来自Java-land,我习惯Maven/Gradle-style坐标group:artifact:version
,所以对我来说,image
和repository
成为同一个:
image
是您正在生成的工件,在 Java 领域中,生成的工件与其代码所在的源代码库之间通常存在 1:1 关系.所以对我来说,命令只是:
docker tag <username>/<repository>:<tag>
例如:docker tag john/get-started:part1
,其中 john
是 username/group,get-started
是 artifact/repo,part1
是 tag/version.
要清楚:我不是问图像和存储库之间的区别!我知道存储库是存储图像的位置,我知道图像是一个 Docker 可执行文件,由 Docker 化的应用程序及其依赖项组成。但是从命名的角度来看,我很困惑 why/when 它们应该彼此不同。
所以我问:从命名约定的角度来看,image
和 repository
有什么区别?例如,如果我想制作自己的 MySQL Docker 图像,我会选择制作名为“myapp-db”的图像,这样也会是它所在的存储库的名称(smeeb/myapp-db:v1
、smeeb/myapp-db:v2
等)。
那么在什么情况下are/should image
和repository
名字会不同呢?
一种情况下,如果您使用的图像已过时,则图像的标签可能与存储库名称不同。
例如,您下载 运行 一张 MySQL:5 图片。当您拉取更新版本的 MySQL:5 图像时,此容器仍然是 运行ning。那时旧图像将被取消标记(只能通过其哈希识别),但不会被删除,因为它仍在被 运行ning MySQL 容器使用。
另一种情况是,您可以在构建新图像时使用中间图像。基本上每一行都会作为一个新图像提交,但它们不会以您指定的名称命名为最终图像名称。
使用 docker tag
时,您甚至不必将图像名称用作第一个参数。您甚至可以使用要标记的图像的哈希值作为第一个参数,因此它比 namespace/repository:tag.
必须说明图像和存储库之间的区别:
图像是标记的存储库。这就是 仅 的区别。 <username>
是存储库名称的一部分。
来自overview of the Docker Registry Distribution API:
Classically, repository names have always been two path components where each path component is less than 30 characters. The V2 registry API does not enforce this. The rules for a repository name are as follows:
A repository name is broken up into path components. A component of a repository name must be at least one lowercase, alpha-numeric characters, optionally separated by periods, dashes or underscores. More strictly, it must match the regular expression [a-z0-9]+(?:[._-][a-z0-9]+)*. If a repository name has two or more path components, they must be separated by a forward slash ("/"). The total length of a repository name, including slashes, must be less than 256 characters.
只需为您的图片和标签使用有意义的名称。你可以有 smeeb/myapp
和 smeeb/myapp-db
。对于标签,惯例是使用版本标签和一个 latest
标签。
首先是先决条件:标签是指向图像的指针,图像是 docker 用于制作容器的配置和层清单的 sha256 引用。这意味着 friendlyhello
不是图像的名称,它是指向图像的标签。图片是id,类似于c75bebcdd211....
.
接下来,每个图像可以有零个、一个或多个标签都指向它。当它没有任何指向它的标签时,这被称为悬挂图像。如果您构建带有标签的图像,然后重建它,就会发生这种情况。之前的图像现在未标记,因为标记指向新图像。同样,您可以让标签 image:latest
、image:v1
、image:1.0.1
和 myrepo:5000/image:1.0
都指向相同的图像 ID。
标签有双重用途。它们可以是为了方便。但是 docker push
和 docker pull
也使用它们来查找发送或检索包裹的位置。如果你不做推或拉,那么你可以随意命名,没有人会知道其中的区别。但是,如果您确实想将其存储在注册表中,则标签需要标识哪个注册表或默认的 docker 集线器。并且该标记还需要标识注册表上的路径,称为存储库,以及冒号后的版本控制。
一个令人困惑的地方是存储库名称末尾的短名称通常称为 "image name",而冒号后的版本控制通常称为 "tag",我认为这如果您忘记了这些术语曾经像那样超载,就更容易理解。
现在有了所有这些背景(抱歉,内容太多),这里是对问题的一些更正:
而不是:
docker tag <image> <username>/<repository>:<tag>
将语法视为:
docker tag <source> <tag>
其中 <source>
可以是图像 ID,或其他标签名称。这意味着以下命令没有意义:
docker tag <username>/<repository>:<tag>
因为 docker tag
需要一个来源来标记,并且它对您当前正在处理的图像没有上下文感。
最后,为什么要为图像使用存储库名称以外的名称,以下是我遇到的几个原因:
图像不会被推送到存储库。它可能用于本地测试,或工作流程中的中间步骤,或者您在同一系统上构建和 运行 您的图像。
同一张图片可以有多个名称。
registry/repo/image:v1
和registry/repo/image:v1.0.1
是一个常见的例子。我还将在特定环境中使用registry/repo/image:STAGE
标记当前图像,以注意它已通过开发和 CI 并且现在处于暂存环境中。您可能在注册表之间移动图像。我们从 hub.docker.com 中提取图像并使用本地注册表在本地重新标记它们。这既为我们提供了本地缓存,也为我们提供了一种控制何时将基础图像更新到下一个版本的方法。这比在产品发布过程中更新映像更可取。
我还使用标签来覆盖上游图像。因此,我无需针对上游图像的问题更改所有构建脚本,而只需进行更改并使用上游名称对其进行标记即可。然后只要我不 运行 拉那个 docker 主机,构建就会 运行 使用我修改后的基础映像。