规范的Docker图像标记采用以下形式:
[[registry-address]:port/]name:tag
可以省略地址和端口,在这种情况下,Docker会转到默认注册表,即Docker Hub。例如,以下内容均有效:
ubuntu:latest
nixos/nix:1.10
localhost:5000/myfirstimage:latest
localhost:5000/nixos/nix:latest
我需要一些能够将此字符串可靠地解析为其组件部分的代码。但是,似乎不可能明确地这样做,因为“name”组件可以包含斜杠。例如,以下标记含糊不清:
localhost/myfirstimage:latest
这可能是Docker Hub上名为localhost/myfirstimage
的图像,也可能是在地址myfirstimage
上运行的注册表中名为localhost
的图像。
有人知道Docker本身如何解析这样的输入吗?
答案 0 :(得分:0)
我相信它确实可以毫不含糊地解析。
根据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)。
实现此功能的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
}
(虽然我没有详细调查过它)