码头图像名称是如何分析的?
在执行Docker docker push
或拉取图像时,Docker如何确定映像名称中是否存在注册服务器,或者它是否为默认注册表(例如Docker Hub)上的路径/用户名?
我从1.1图像规格中看到以下内容:
标签
标签用于将描述性的用户给定名称映射到任何单个图像ID。 标记值仅限于字符集[a-zA-Z_0-9]。
知识库
在一个公共前缀下分组的标签集合(在:)之前的名称组件)。 例如,在名称为my-app:3.1.4的图像中,my-app是名称的Repository组件。 存储库名称由斜杠分隔的名称组件组成,可选地以DNS主机名作为前缀。 主机名必须遵守标准DNS规则,但不得包含_字符。 如果存在主机名,则可以选择使用格式为8080的端口号。 名称组件可能包含小写字符,数字和分隔符。 分隔符定义为句点,一个或两个下划线或一个或多个破折号。 名称组件不能以分隔符开始或结束。
对于DNS主机名,它是否需要完全限定点,或者是“my-local-server”是有效的注册表主机名? 对于名称组件,我将周期视为有效,这意味着“team.user / appserver”是有效的图像名称。 如果注册表服务器在端口80上运行,因此图像名称中的主机名不需要端口号,似乎主机名和注册表服务器上的路径之间会有不明确的地方。 我很好奇Docker如何解决这个模糊问题。
TL; DR:主机名必须包含一个.
dns分隔符或第一个/
之前的a :
port分隔符,否则代码将假定您需要默认注册表。
在深入了解代码之后,我遇到了以下分发/参考/ reference.go:
// Grammar
//
// reference := name [ ":" tag ] [ "@" digest ]
// name := [hostname '/'] component ['/' component]*
// hostname := hostcomponent ['.' hostcomponent]* [':' port-number]
// hostcomponent := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
// port-number := /[0-9]+/
// component := alpha-numeric [separator alpha-numeric]*
// alpha-numeric := /[a-z0-9]+/
// separator := /[_.]|__|[-]*/
//
// tag := /[w][w.-]{0,127}/
//
// digest := digest-algorithm ":" digest-hex
// digest-algorithm := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]
// digest-algorithm-separator := /[+.-_]/
// digest-algorithm-component := /[A-Za-z][A-Za-z0-9]*/
// digest-hex := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
实际的实现是通过distribution / reference / regexp.go中的正则表达式。
但也有一些挖掘和戳,我发现还有另一项检查除此之外,正则表达式(你会得到一个大写的主机名的错误,如果你不不包括.
或:
)。 我在docker / reference.go中追踪了以下名称的实际拆分:
func splitHostname(name string) (hostname, remoteName string) {
i := strings.IndexRune(name, '/')
if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
hostname, remoteName = DefaultHostname, name
} else {
hostname, remoteName = name[:i], name[i+1:]
}
if hostname == LegacyDefaultHostname {
hostname = DefaultHostname
}
if hostname == DefaultHostname && !strings.ContainsRune(remoteName, '/') {
remoteName = DefaultRepoPrefix + remoteName
}
return
}
对我来说,重要的部分是检查.
和:
在第一个/
在第一个if语句之前。 有了它,主机名将从第一个/
之前分离出来,如果没有它,整个名称将传递给默认的注册表主机名。
https://github.com/moby/moby/blob/master/image/spec/v1.1.md中的image-spec现在已经更新,说明标记限制为128个字符。
PR线程在https://github.com/docker/distribution/issues/2248
一些Ruby代码在这里https://github.com/cyber-dojo/runner/blob/master/server/src/valid_image_name.rb
一些Ruby测试在这里https://github.com/cyber-dojo/runner/blob/master/server/test/src/valid_image_name_test.rb
链接地址: http://www.djcxy.com/p/92257.html