在没有 gcloud 客户端的情况下访问 google 容器注册表

Posted

技术标签:

【中文标题】在没有 gcloud 客户端的情况下访问 google 容器注册表【英文标题】:Access google container registry without the gcloud client 【发布时间】:2015-05-31 05:50:45 【问题描述】:

我有一个 CoreOS docker 主机,我想开始在其上运行容器,但是当尝试使用 docker 命令从 google 容器私有注册表 (https://cloud.google.com/tools/container-registry/) 获取图像时,我得到了 403。我做了一些搜索,但我不确定如何附加身份验证(或在哪里生成用户+密码包以与 docker login 命令一起使用)。

有没有人从谷歌私人容器中拉出来的运气?我无法安装 gcloud 命令,因为 coreos 没有附带 python,这是必需的

docker run -p 80:80 gcr.io/prj_name/image_name
Unable to find image 'gcr.io/prj_name/image_name:latest' locally
Pulling repository gcr.io/prj_name/image_name
FATA[0000] HTTP code: 403

更新:在得到@mattmoor 和@Jesse 的答复后:

我从中提取的机器确实有 devaccess

curl -H 'Metadata-Flavor: Google' http://metadata.google.internal./computeMetadata/v1/instance/service-accounts/default/scopes
https://www.googleapis.com/auth/bigquery
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/compute
https://www.googleapis.com/auth/datastore
----> https://www.googleapis.com/auth/devstorage.read_only
https://www.googleapis.com/auth/logging.admin
https://www.googleapis.com/auth/sqlservice.admin
https://www.googleapis.com/auth/taskqueue
https://www.googleapis.com/auth/userinfo.email

另外,我尝试使用_token登录方法

jenkins@riskjenkins:/home/andre$ ACCESS_TOKEN=$(curl -H 'Metadata-Flavor: Google' 'http://metadata.google.internal./computeMetadata/v1/instance/service-accounts/default/token' | cut -d'"' -f 4)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   142  100   142    0     0  14686      0 --:--:-- --:--:-- --:--:-- 15777
jenkins@riskjenkins:/home/andre$ echo $ACCESS_TOKEN
**************(redacted, but looks valid)
jenkins@riskjenkins:/home/andre$ docker login -e not@val.id -u _token -p $ACCESS_TOKEN http://gcr.io
Login Succeeded
jenkins@riskjenkins:/home/andre$ docker run gcr.io/prj_name/image_name
Unable to find image 'gcr.io/prj_name/image_name:latest' locally
Pulling repository gcr.io/prj_name/image_name
FATA[0000] HTTP code: 403

【问题讨论】:

【参考方案1】:

Google Container Registry 身份验证方案是简单地使用:

username: '_token'
password: oauth access token

在 Google Compute Engine 上,您可以不使用 gcloud 登录:

$ METADATA=http://metadata.google.internal./computeMetadata/v1
$ SVC_ACCT=$METADATA/instance/service-accounts/default
$ ACCESS_TOKEN=$(curl -H 'Metadata-Flavor: Google' $SVC_ACCT/token \
    | cut -d'"' -f 4)
$ docker login -e not@val.id -u '_token' -p $ACCESS_TOKEN https://gcr.io

关于 asia,eu,us,b.gcr.io 的更新

要访问托管在本地化存储库中的存储库,您应该在上述docker login 命令中登录到相应的主机名。

关于 _token 的引用更新

从 docker 1.8 版开始,docker login 需要 -u 选项在 qoutes 中或以字母开头。

一些诊断提示...

通过以下方式检查您是否拥有 Cloud Storage 范围:

$ curl -H 'Metadata-Flavor: Google' $SVC_ACCT/scopes
...
https://www.googleapis.com/auth/devstorage.full_control
https://www.googleapis.com/auth/devstorage.read_write
https://www.googleapis.com/auth/devstorage.read_only
...

注意:“docker pull”需要“read_only”,但“docker push”需要“read_write”。

要让这个机器人访问另一个项目中的存储桶,有几个步骤。

首先,通过以下方式找出 VM 服务帐户(又名机器人)的身份:

$ curl -H 'Metadata-Flavor: Google' $SVC_ACCT/email
1234567890@developer.gserviceaccount.com

接下来,要更新三个重要的 ACL:

1) Bucket ACL(需要列出对象等)

PROJECT_ID=correct-answer-42
ROBOT=1234567890@developer.gserviceaccount.com
gsutil acl ch -u $ROBOT:R gs://artifacts.$PROJECT_ID.appspot.com

2) 存储桶默认 ACL(未来 #3 的模板)

gsutil defacl ch -u $ROBOT:R gs://artifacts.$PROJECT_ID.appspot.com

3) 对象ACL(仅当bucket非空时才需要)

gsutil -m acl ch -R -u $ROBOT:R gs://artifacts.$PROJECT_ID.appspot.com

我们的官方文档中尚未包含此内容的部分原因是我们想要一个更好的高级故事,但我们尊重 GCS ACL。

【讨论】:

这看起来很有希望,我明天试试 FWIW,我们需要 GCS 读取范围才能使其工作。您可以通过以下方式进行检查: curl -H 'Metadata-Flavor: Google' metadata.google.internal./computeMetadata/v1/instance/… /default/scopes GCE 实例确实有 devstorage 只读能力,虽然登录成功,但无法拉取镜像。我根据您和@Jesse 的建议尝试编辑了原始问题。如果您有任何其他建议,请告诉我 你好像有“http://gcr.io” 可以试试https吗? 我尝试使用 https 登录,但我得到了同样的错误【参考方案2】:

在创建 VM 时,是否为其提供了必要的范围以便能够从注册表中读取?

gcloud 计算实例创建实例 \ --scopeshttps://www.googleapis.com/auth/devstorage.read_write

如果您这样做了,则不需要进一步的身份验证。

【讨论】:

我不认为这是真的,因为“如果未提供此标志,则使用以下范围:googleapis.com/auth/devstorage.read_only,googleapis.com/auth/logging.write”我从 repo 中提取,所以 read_only 应该是够了,但我还是得到了 403【参考方案3】:

我开发了一个 jenkins 插件,它允许在 GCE 上运行的从站使用@mattmoor 的解决方案登录到谷歌的注册表。它可能对其他人有用。 :)

可通过https://github.com/Byclosure/gcr.io-login-plugin 获取。

【讨论】:

请不要只发布链接的答案,因为链接可能会中断【参考方案4】:

官方发布了Google Container Registry Auth Plugin。欢迎您试用并留下反馈/报告问题。

【讨论】:

谢谢,我试试看。通过使用访问令牌登录到gcr 和gcr 端点,我能够使其达到足够好的状态。出于某种原因,我需要同时登录 @Andre:您是在使用 Google Container Registry Auth Plugin 和 Docker Build Step 插件还是其他插件?我也对您的陈述“同时登录 gcr 和 gcr 端点”感到有些困惑。你能澄清一下吗?如果您将 Docker Build Step 插件与 GCR auth 插件一起使用,则需要将提供的凭据添加到每个单独的 Docker Build Step 命令。【参考方案5】:

这里的答案涉及从 Google Compute Engine 实例中访问 docker。

如果您想使用 vanilla docker 在不在 Google Compute Engine 中(即本地)的机器上使用 Google Container Registry,您可以follow Google's instructions。

两种主要方法是使用访问令牌或 JSON 密钥文件。

请注意,_token_json_key 是您为用户名 (-u) 提供的实际值

访问令牌

$ docker login -e 1234@5678.com -u _token -p "$(gcloud auth print-access-token)" https://gcr.io

JSON 密钥文件

$ docker login -e 1234@5678.com -u _json_key -p "$(cat keyfile.json)" https://gcr.io

要创建密钥文件,您可以按照以下说明操作:

    打开凭据页面。 要设置新的服务帐户,请执行以下操作: 点击添加凭据 > 服务帐户。 选择是将服务帐号的公钥/私钥下载为标准 P12 文件,还是可以由 Google API 客户端库加载的 JSON 文件。 您的新公钥/私钥对已生成并下载到您的计算机;它用作此密钥的唯一副本。您有责任安全地存储它。

你可以view Google's documentation on generating a key file here。

【讨论】:

你提供的这个答案给了我一些希望,我可以让事情正常进行,在冲洗一天或更长时间之后尝试做一些简单的事情,比如将图像推送到 repo,但仍然没有运气。 我做到了!!!我认为部分问题在于 gcr.io 与 grc.com 非常相似,Steve Gibson/Security Now 的网站。可能错字很多次了。当我最终做对时,访问令牌意味着对我有用。【参考方案6】:

有two official ways:

    $ docker login -e 1234@5678.com -u oauth2accesstoken -p "$(gcloud auth print-access-token)" https://gcr.io $ docker login -e 1234@5678.com -u _json_key -p "$JSON_KEY" https://gcr.io

注意:邮箱没有用到,随便放什么都可以。

gcr.io 更改为Google Container Registry 中显示的任何域(例如eu.gcr.io)。

选项 (1) 仅提供临时标记,因此您可能需要选项 (2)。得到那个$JSON_KEY

    转到API Manager > Credentials 点击“创建凭据”> 服务帐户密钥: 服务帐户:新服务帐户 姓名:任何你想要的,比如Docker Registry (read-only) 角色:存储(向下滚动)> 存储对象查看器 密钥类型:JSON 下载为keyfile.json JSON_KEY=$(cat keyfile.json | tr '\n' ' ') 现在您可以使用它了。

登录后,您只需运行docker pull。您也可以复制更新后的~/.dockercfg 以保留设置。

【讨论】:

unknown shorthand flag: 'e' in -e See 'docker login --help'.

以上是关于在没有 gcloud 客户端的情况下访问 google 容器注册表的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有选择意图的情况下直接打开Goog le Play商店应用[重复]

在没有 SVN 客户端的情况下应用 TortoiseSVN 补丁

如何在没有邮件接收客户端的情况下验证 Mandrill 自定义发送域?

如何在没有客户端的情况下使用 facebook 的护照在 node.js 中构建 REST 服务?

使用哪种授权类型来验证第三方客户端的 API 访问权限?

如何检测人员在客户端的非屏蔽字段中输入 SSN 数据?