将Docker图像标记解析为组件

时间:2017-02-08 14:26:52

标签: docker docker-registry

规范的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本身如何解析这样的输入吗?

1 个答案:

答案 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.goservice.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
}

(虽然我没有详细调查过它)