我相信它确实可以被明确地解析。
根据this
当前用于识别图像的语法是这样的:
[registry_hostname[:port]/][user_name/](repository_name[:version_tag] | image_id)
...
localhost 是唯一允许的单名主机。所有其他必须包含一个端口(“:”)或多个部分(“foo.bar”,因此包含一个“.”)
实际上,这意味着如果您的 docker 镜像标识符以 localhost 开头,它将针对运行在 localhost:80
的注册表进行解析
>docker pull localhost/myfirstimage:latest
Pulling repository localhost/myfirstimage
Error while pulling image: Get http://localhost/v1/repositories/myfirstimage/images: dial tcp 127.0.0.1:80: getsockopt: connection refused
(使用 Docker 1.12.0 测试)
“也是一样。”
>docker pull a.myfirstimage/name:latest
Using default tag: latest
Error response from daemon: Get https://a.myfirstimage/v1/_ping: dial tcp: lookup a.myfirstimage on 127.0.0.1:53: no such host
和":"
>docker pull myfirstimage:80/name:latest
Error response from daemon: Get https://myfirstimage:80/v1/_ping: dial tcp: lookup myfirstimage on 127.0.0.1:53: no such host
所以你的解析代码应该查看第一个"/"之前的子字符串,并检查它是"localhost",还是包含"。 " 或以 ":XYZ" 结尾(一个端口号),在这种情况下它是一个 registry_hostname,否则它是一个 repository name(用户名/repository_name)。
实现此功能的 Docker 代码似乎位于此处:
reference.go 和 service.go
// splitReposSearchTerm breaks a search term into an index name and remote name
func splitReposSearchTerm(reposName string) (string, string) {
nameParts := strings.SplitN(reposName, "/", 2)
var indexName, remoteName string
if len(nameParts) == 1 || (!strings.Contains(nameParts[0], ".") &&
!strings.Contains(nameParts[0], ":") && nameParts[0] != "localhost") {
// This is a Docker Index repos (ex: samalba/hipache or ubuntu)
// 'docker.io'
indexName = IndexName
remoteName = reposName
} else {
indexName = nameParts[0]
remoteName = nameParts[1]
}
return indexName, remoteName
}
(虽然我没有更详细地研究它)