映像和存储库有啥区别?
Posted
技术标签:
【中文标题】映像和存储库有啥区别?【英文标题】:What is the difference between an image and a repository?映像和存储库有什么区别? 【发布时间】:2015-09-15 21:10:08 【问题描述】:我是 Docker 的新手,关注 Getting Started tutorial。在第 7 步它说
键入
docker images
命令并按回车键。该命令列出本地系统上的所有图像。您应该会在列表中看到docker/whalesay
。$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE docker/whalesay latest fb434121fc77 3 hours ago 247 MB hello-world latest 91c95931e552 5 weeks ago 910 B
但第一列清楚地写着“存储库”,而不是例如“图像名称”。我还注意到在其他人的机器上,因为一个图像可以有多个标签,这个列表通常包含重复的条目——每个标签一个。那么这是图像列表、存储库列表、图像标签组合列表还是其他内容?镜像和存储库有什么区别?
另外,鉴于图像和存储库是不同的东西,我该如何列出我的存储库?
这与容器无关。
【问题讨论】:
Docker image vs container的可能重复 不要混淆图像和图像名称。一个镜像可以有多个名称:一个(唯一的)镜像 ID,它是一个散列,以及许多不同的存储库标签组合。 (这很令人困惑,因为“存储库”对于图像名称的第一部分来说是一个非常糟糕的命名选择。) @LutzPrechelt 我仍然对“repostiory”这个词的含义感到困惑。它是本地事物还是与特定图像有关?在这一点上,我什至可能对“图像”这个词现在的含义感到困惑。 @CharlieParker 存储库是多个图像的容器。映像基础名称是存储库名称。图像标签区分图像的不同“版本”(并且 docker 没有意见“版本”应该是什么意思,版本可以包含完全不同的图像)。不同的标签可以引用同一个容器中的同一个图像。 @LutzPrechelt 你能给我一个参考,说“图像基础名称是存储库名称”吗?我在 Docker 文档中找不到它.... 【参考方案1】:是的,这是一个非常混乱的术语。
最简单的答案:
图像:单个图像。
存储库:图像的集合。
详情:
图像:由 Image ID
唯一引用,12 位十六进制代码(例如 91c95931e552)。 [1]
存储库:包含一个或多个图像。所以hello-world
存储库可以包含两个不同的图像:91c95931e552
和1234abcd5678
。
Image alias
- 我将定义image alias
表示引用特定图像的别名。 image alias
的格式是 repository:tag
。这样一来,您就可以使用对人类友好的别名,例如 hello-world:latest
,而不是 12 位代码。
示例:
假设我有这些图片:
REPOSITORY TAG IMAGE ID
docker/whalesay latest fb434121fc77
hello-world latest 91c95931e552
hello-world v1.1 91c95931e552
hello-world v1.0 1234abcd5678
存储库是:docker/whalesay
、hello-world
。
图片为fb434121fc77
、91c95931e552
、1234abcd5678
。请注意,第 2 行和第 3 行具有相同的Image ID
,因此它们是相同的图像。
图像别名是:
docker/whalesay:latest
hello-world:latest
hello-world:v1.1
hello-world:v1.0
所以hello-world:latest
和hello-world:v1.1
只是同一张图片的两个别名。
其他详情:
Repository name
格式还可以预先添加可选的用户或命名空间,这在使用像 Docker Hub 这样的公共注册表时很有用。例如。 docker/whalesay
。否则,您将有很多存储库名称冲突。
如果在引用图像别名时省略tag
,它将自动添加:latest
。所以当你指定hello-world
时,它会被解释为hello-world:latest
。警告:latest
实际上并没有什么特别的意思,它只是一个默认标签。
[1] 实际上,完整的 Image ID 是一个 64 位的十六进制代码,截断为 12 位,但您无需关心。
李>【讨论】:
【参考方案2】:引用自 Docker 官方文档:
存储库可能包含图像的多个变体。
(见:https://docs.docker.com/userguide/dockerimages)
这意味着: Docker 映像可以属于一个存储库,例如当它被推送到 Docker 注册表时(使用docker push my/reporitory:version1
)。另一方面,存储库包含图像的多个版本(= 不同的标签)。因此,当您构建映像的新版本时,您可以给它一个标签 (docker tag 518a41981a6a my/reporitory:version2
) 并将其作为下一个版本 (docker push my/reporitory:version2
) 推送到您的存储库。
这是 Docker 文档中的一个示例(请参阅上面的链接)。如您所见,它显示了一个名为 ouruser/sinatra
的存储库,其中包含同一图像的各种版本(latest
、devel
、v2
):
$ docker images ouruser/sinatra
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ouruser/sinatra latest 5db5f8471261 11 hours ago 446.7 MB
ouruser/sinatra devel 5db5f8471261 11 hours ago 446.7 MB
ouruser/sinatra v2 5db5f8471261 11 hours ago 446.7 MB
在您的示例中,您有两个存储库(docker/whalesay
和 hello-world
),其中仅包含一个标记图像(称为 latest
,这意味着实际上没有标记并且显示了最新图像)。
【讨论】:
那么这三张图片是否有可能是不同的,即使它们具有相同的 ID? 是的。您可以执行以下操作:您有一个 ID 为5db5f8471261
的图像。现在您可以使用一些新版本标记此图像:docker tag 5db5f8471261 ouruser/sinatra:myversion
。这将向现有存储库 (ouruser/sinatra
) 添加一个新版本 (myversion
)。如果您调用docker images
,您将看到一个更多条目,但是图像ID 将是相同的(5db5f8471261
),因为图像没有改变,它只是“一个新名称”。
版本和标签有什么区别?
“存储库”这个词是什么意思?我觉得这很令人困惑。
Docker 存储库是具有相同名称、不同标签的不同 Docker 映像的集合。标签是存储库中图像的字母数字标识符。【参考方案3】:
在这里定义几个术语是最简单的,因为它们都是相互关联的:
图像:这是用于以运行容器的方式打包应用程序的文件系统层和元数据。每个图像都必须在 docker 引擎上有一个 ID。
参考:这是指向图像的指针。有不同类型的引用,或者只是图像 ID,通常是存储库和标签,有时您会使用 sha256 哈希而不是可变标签固定到特定的校验和。重要的部分是您可以有多个指向同一个图像的指针,并且除了图像 ID 之外,没有必要对图像进行任何引用。当您删除一个引用时,docker 只会删除该指针,除非它是指向该图像 ID 的最后一个指针。
注册表:这是一个保存图像的服务器。与 Git 服务器保存源代码或二进制文件的工件服务器的方式类似,注册表是您推送和拉取图像的地方。
存储库:注册表服务器上的图像目录的路径是存储库。如果您不使用默认的 Docker Hub 注册表,这包括注册表主机名和端口。在图像参考中,此存储库是最后一个冒号和标记之前的部分。
标签:存储库中的特定图像。如果不指定标签,docker 将默认使用标签名称“latest”。这是最后一个冒号之后的部分,通常用于版本号。
举个例子参考:
registry-server:5000/team/service-a:build-42
“registry-server:5000”是您将在其中推送/拉取此映像的注册表服务器名称(和端口)。
“registry-server:5000/team/service-a”是存储库。
“build-42”是标签。
“registry-server:5000/team/service-a:build-42”是一个参考。
与其他系统不同,在其他系统中,您将推送和拉取到服务器,然后指定要发送到那里的文件,向注册服务器推送和拉取 docker 映像使用包含存储库和以该名称标记。因此,要将镜像推送到不同的位置,您需要创建一个新的引用(使用 docker tag
命令)到具有新存储库和标签的同一镜像,然后针对该引用运行您的推送命令。
通常,当有人提到“图像名称”时,他们指的是存储库名称(如果您想单独指定标签)或可用于拉取或推送图像的完整参考。
我怎样才能列出我的存储库?
docker image ls --format '.Repository' | sort -u
我包含sort -u
以对输出进行去重,因为您可能有多个图像具有相同的存储库和不同的标签。
【讨论】:
【参考方案4】:图像是通过使用给定的Dockerfile
运行docker build
构建的,并由它们的ID 标识。
存储库和标签只是在有意义的层次结构/架构中命名和组织图像的方法。
一个存储库通常包含多个相关图像
一个图像可以进入多个存储库
以下来自this SO answer,详细解释了docker images
output(这可能是他们应该放在文档中的内容):
图像 ID 是图像真实标识符的前 12 个字符。您可以为给定图像创建多个标签,但它们的 ID 将 都一样(如上)。
REPOSITORY 列中的值来自
标签的完整形式是docker build
命令的-t
标志,或来自docker tag
-ing 现有图像。 您可以使用有意义的命名法来标记图像 你,但知道 docker 将使用标签作为注册表位置docker push
或docker pull
。[REGISTRYHOST/][USERNAME/]NAME[:TAG]
。对于上面的ubuntu
,REGISTRYHOST 被推断为registry.hub.docker.com
。因此,如果您打算存储名为my-application
在docker.example.com
的注册表中,您应该标记 那张图片docker.example.com/my-application
。 TAG 列只是 full 标记的 [:TAG] 部分。这是一个令人遗憾的术语。
【讨论】:
【参考方案5】:我将尝试以非常尖锐和清晰的方式解释这一点。
Docker 映像名称
Docker Image 实际上并没有名字。它有一个ID、Repository和一个Tag(根据 Docker 文档,它代表 Target Image,而不是英文单词 tag)。因此,每次我们提到 Docker Image 名称(无论是创建、运行、删除、拉取等),我们实际上是指 Image Repository:Tag (目标图像)。我们经常碰巧省略了标记部分(只写存储库名称,我们认为它是一个图像名称),那就是 docker假定默认标记为:latest
(即目标图像最新)
Docker 存储库
Docker 在构建/创建映像时,会为该映像创建 存储库 和 Image 本身,然后将当前(:latest
标记)映像添加到该存储库中。根据 Marko Luksa 的 Kubernetes in Action 的说法,图像标签使我们能够在同一图像名称下拥有同一图像的多个版本(标签)。所以我们可能有 myapp:latest、myapp:v1、myapp:v2 都在一个标识符下,这里的每个标签都指向一个特定的目标图像,即同一应用程序的特定快照/版本。这就是为什么 docker 命名图像存储库并将区分工作留给 标记,因为一个存储库应该(并且必须)可能包含不同版本的相同的应用程序。
所以,如果我们运行 docker build -t A .
,docker 实际上会创建一个 Image Repository A 和 Image 本身 (使用 :latest强>标签)。然后它会将该图像添加到存储库 A 中。稍后,我们将能够推送/拉取该图像的特定快照。
P。 S.
我们习惯于调用 Docker Image 名称的方式,实际上是(并且可以假定为)Docker Image Repository[:tagname],后者是可选的,默认情况下:latest
您可以测试所有这些并通过尝试删除图像而不为其指定标签以及该图像存储库中没有默认的 :latest 图像来向自己证明。只需运行docker rmi myimage
,您就会看到,docker 会抱怨说Error: No such image: myiamge
默认情况下(当您不提供标签时)它假定并暗示 :latest em> 标签。
希望这能更清楚地说明这个话题。
【讨论】:
很好的增强,你设法提供了一些新信息;-) 您在哪里看到“标签”代表“目标图像”?你能提供一个链接吗? 我现在试图在 Docker 的网站上找到它,但我找不到。什么是真的,我记得我在某本书中读过.. 但即使这不是正确的参考(如果我找不到该文档,我会编辑并从这个答案中删除该行),这个想法我在这里所说的仍然是真实和正确的。标记图像实际上是赋予它完全限定名称的原因,然后我们使用它来识别/引用图像。即使我们省略了显式标签,docker 也会在那里假定默认标签。以上是关于映像和存储库有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章