6

我正在使用 google 容器注册表来托管我的 docker 映像。我也在使用 golang 的 moby 客户端与之交互。我正在使用JSON 服务密钥方法,该方法似乎与 RegistryLogin 配合良好。响应文本是登录成功。但是,我不知道如何将返回的身份验证密钥与 ImagePull 一起使用。在后台设置 RegistryAuth 似乎设置了作为 X-Registry-Auth 标头传递的任何字符串,Google 似乎没有在任何地方提及这一点。

我尝试将返回的密钥作为 RegistryAuth 传递,我尝试运行 RegistryLogin,然后在没有 RegistryAuth 的情况下进行拉取。我已经尝试过 base64 编码我的身份验证配置并将其发送到 RegistryAuth。无论我尝试什么,我都会收到“来自守护进程的错误响应:找不到存储库 xxx:不存在或没有拉取访问权限”。运行 docker login 然后 docker pull 使用相同的详细信息在 cli 上运行良好。我的代码是:

authConfig := types.AuthConfig{
    Username:      "_json_key",
    Password:      string(decodedKey),
    ServerAddress: "https://gcr.io",
}

_, err = engine.Client.RegistryLogin(ctx, authConfig)
if err != nil {
    return err
}

responseBody, err := engine.Client.ImagePull(ctx, image, types.ImagePullOptions{
})
defer responseBody.Close()

if err != nil {
    return err
}

decodedKey 是 JSON 密钥文件内容。任何想法如何让它发挥作用?

4

1 回答 1

2

(我假设你已经想通了或者想出了另一种方法,但我会在这里为下一个人记录下来)

您需要将其编组为 JSON,然后对其进行 base64 编码除了docker cli 的代码之外,我还没有在任何地方看到这个文档。

不幸的是,当我尝试包含时,github.com/docker/cli/cli/command我得到了这个错误,由于 cli repo 的供应商目录被包含在 go 的包源路径中的方式:

./gcp.go:73:47: cannot use authc (type "github.com/docker/docker/api/types".AuthConfig)
as type "github.com/docker/cli/vendor/github.com/docker/docker/api/types".AuthConfig
in argument to command.EncodeAuthToBase64

Go 编译器无法识别它们是同一类型,这很烦人。但是复制功能很简单:

buf, _ = json.Marshal(authConfig)

regauth := base64.URLEncoding.EncodeToString(buf)

pullopts := types.ImagePullOptions{RegistryAuth:regauth}

responseBody, err := engine.Client.ImagePull(ctx, image, pullopts)

...

*恕我直言,更好的实现是在 pullopts 中有一个types.RequestPrivilegeFunc来动态获取access_token字段http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token。这样就无需担心应用程序凭据的安全性。我自己还没有尝试过。

希望这会有所帮助,尽管晚了 18 个月。:)

FWIW,Google 支持无法提供有关此的任何信息,gcr.io 和 docker 文档也没有提供太多信息。解决方案是设置 cli auth,然后破解 docker cli 工具的自定义版本,这样我就可以看到真正发生了什么。

*编辑:所以我尝试了这个,但是PrivilegeFunc在 PullOptions 中声明的函数永远不会被调用。我不知道为什么。太糟糕了,这似乎是一个更清洁的解决方案。不过,上面的程序代码对我有用。

于 2018-12-31T03:53:42.277 回答