Docker图像名称如何解析? [英] How are docker image names parsed?

查看:139
本文介绍了Docker图像名称如何解析?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当执行 docker push 或拉动图像时,Docker如何确定图像名称中是否存在注册表服务器,或者是否是路径/用户名默认注册表(例如Docker Hub)?

When doing a docker push or when pulling an image, how does Docker determine if there is a registry server in the image name or if it is a path/username on the default registry (e.g. Docker Hub)?

我从 1.1 image spec


标签

标签用于将描述性用户给定的名称映射到任何单个图像
ID。标签值仅限于字符集[a-zA-Z_0-9]。

A tag serves to map a descriptive, user-given name to any single image ID. Tag values are limited to the set of characters [a-zA-Z_0-9].

存储库

按公共前缀分组的标签集合(名称组件
之前:)。例如,在名为my-app:3.1.4的图像中,
my-app是名称的Repository组件。存储库名称为
,由斜杠分隔的名称组件组成,可选地以
DNS主机名前缀。主机名必须符合标准DNS规则
,但不能包含_个字符。如果存在主机名,则可以
后面跟着一个格式为8080的端口号。名称
组件可能包含小写字符,数字和分隔符。 A
分隔符定义为句点,一个或两个下划线,或一个或
更多的破折号。名称组件可能无法以分隔符开始或结尾。

A collection of tags grouped under a common prefix (the name component before :). For example, in an image tagged with the name my-app:3.1.4, my-app is the Repository component of the name. A repository name is made up of slash-separated name components, optionally prefixed by a DNS hostname. The hostname must follow comply with standard DNS rules, but may not contain _ characters. If a hostname is present, it may optionally be followed by a port number in the format :8080. Name components may contain lowercase characters, digits, and separators. A separator is defined as a period, one or two underscores, or one or more dashes. A name component may not start or end with a separator.

对于DNS主机名,是否需要使用点完全限定,还是my-local-server有效的注册表主机名?对于名称组件,我看到句点有效,这意味着team.user / appserver是一个有效的映像名称。如果注册表服务器在端口80上运行,因此在映像名称中的主机名上不需要端口号,那么主机名和注册表服务器上的路径似乎就会有歧义。我很好奇Docker如何解决这个歧义。

For the DNS host name, does it need to be fully qualified with dots, or is "my-local-server" a valid registry hostname? For the name components, I'm seeing periods as valid, which implies "team.user/appserver" is a valid image name. If the registry server is running on port 80, and therefore no port number is needed on the hostname in the image name, it seems like there would be ambiguity between the hostname and the path on the registry server. I'm curious how Docker resolves that ambiguity.

推荐答案

TL; DR:主机名必须包含一个 dns分隔符或端口分隔符在第一个 / 之前,否则代码假定你想要默认的注册表。

TL;DR: The hostname must contain a . dns separator or a : port separator before the first /, otherwise the code assumes you want the default registry.

在浏览代码之后,我遇到了一个 distribution / reference / reference.go ,其中包含以下内容:

After some digging through the code, I came across distribution/reference/reference.go with the following:

// 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

The actual implementation of that is via a regex in distribution/reference/regexp.go.

但是通过一些挖掘和戳戳,我发现还有一个超出正则表达式的检查(如果你不包含一个,你会得到大写主机名的错误。 code>或)。而且我在停泊港/参考资料.go

But with some digging and poking, I found that there's another check beyond that regex (you'll get errors with an uppercase hostname if you don't don't include a . or :). And I tracked down the actual split of the name to the following in 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语句之前的第一个 / 之前。使用它,主机名从第一个 / 之前拆分,没有它,整个名称将传递到默认注册表主机名。

The important part of that for me is the check for the . and : before the first / in the first if statement. With it, the hostname is split out from before the first /, and without it, the entire name is passed to the default registry hostname.

这篇关于Docker图像名称如何解析?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆