无需使用gcloud客户端即可访问Google容器注册表

34

我有一台CoreOS的Docker主机,想要在上面运行容器,但当尝试使用docker命令从Google容器私有注册表(https://cloud.google.com/tools/container-registry/)获取镜像时,会出现403错误。我进行了一些搜索,但不确定如何附加身份验证(或者在哪里生成用户和密码包以用于docker登录命令)。

是否有人已经成功从谷歌私有容器中拉取过镜像?我无法安装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
6个回答

56

Google容器注册表的身份验证方案是简单地使用:

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选项用引号括起来或以字母开头。

一些诊断提示...

通过以下方式检查您是否具有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" 权限。

要让这个机器人访问另一个项目中的存储桶,需要执行以下几个步骤:

首先,通过以下命令找出虚拟机服务帐户(即机器人)的身份:

$ 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) Bucket默认ACL(未来第三个模板)

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

3) 对象 ACL(仅在桶非空时需要)

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

这个还没有被列入我们官方文档的原因之一是我们希望为它提供一个更好的高层次介绍,但简而言之,我们尊重GCS ACLs。


这看起来很有前途,我明天会试一试。 - Andre
值得一提的是,我们需要GCS读取范围才能使其正常工作。您可以使用以下命令进行检查: curl -H 'Metadata-Flavor: Google' http://metadata.google.internal./computeMetadata/v1/instance/service-accounts /default/scopes - mattmoor
GCE实例确实具有devstorage只读功能,尽管登录成功,但我无法拉取镜像。我编辑了原始问题,并尝试了您和@Jesse的建议。如果您有其他建议,请告诉我。 - Andre
我尝试使用https进行登录,但是我得到了相同的错误。 - Andre
我刚在GCE上的coreos-beta-633-1-0-v20150401镜像上进行了测试。除了stackoverflow添加到我的复制/粘贴中的换行符之外,它对我有效。我在登录之前得到了403错误,然后我登录成功并成功拉取。需要记住以下几点: 1)访问令牌会过期 2)VM必须在同一项目中(或者ACL必须相应更新)随时联系gcr-contact@google.com,我很乐意更同步地讨论这个问题以解决它。 - mattmoor
显示剩余5条评论

19

这里的答案涉及到如何从Google Compute Engine实例内部访问docker。

如果你想在不在Google Compute Engine(即本地)的计算机上使用vanilla docker与Google Container Registry一起使用,你可以按照Google的说明进行操作。

主要方法有两种,一种是使用访问令牌,另一种是使用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

要创建一个密钥文件,请按照以下步骤:

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

您可以在此处查看有关生成密钥文件的 Google 文档


你提供的答案给了我一些希望,让我相信我可以让事情正常运转。之前我浪费了一天甚至更长时间,试图做一些看似简单的事情,比如将一个图像推送到仓库,但是仍然没有成功。 - Randy L
我成功了!我认为问题的一部分是 gcr.io 和 Steve Gibson/Security Now 的网站 grc.com 非常相似。我可能打错了很多次。当我终于弄对了,访问令牌就能为我工作。 - Randy L

5

两种官方方式

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

注意:邮箱不会被使用,因此您可以随意填写。

gcr.io更改为您在Google容器注册表中显示的域名(例如:eu.gcr.io)。

选项(1)仅提供临时令牌,因此您可能需要选项(2)。要获取$JSON_KEY

  1. 进入API管理器>凭据
  2. 单击“创建凭据”>服务帐号密钥
    • 服务帐号:新服务帐号
      • 名称:任何您想要的名称,例如Docker Registry (read-only)
      • 角色:存储(向下滚动)>存储对象查看器
    • 密钥类型:JSON
  3. 下载为keyfile.json
  4. JSON_KEY=$(cat keyfile.json | tr '\n' ' ')
  5. 现在您可以使用它。

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


See 'docker login --help'.``` - Marc J. Schmidt

1
当您创建虚拟机时,是否为其提供了必要的范围以便能够从注册表中读取?如果是这样,就不需要进一步进行身份验证。
示例命令如下:

gcloud compute instances create INSTANCE \ --scopes https://www.googleapis.com/auth/devstorage.read_write


2
我不认为这是正确的,因为“如果未提供此标志,则使用以下范围:https://www.googleapis.com/auth/devstorage.read_only、https://www.googleapis.com/auth/logging.write”,我正在从回购中拉取,所以只读应该足够了,但仍然出现403。 - Andre

0

谢谢,我会试一下。我通过使用访问令牌登录https://gcr和http://gcr端点,将其调整到了足够好的状态。由于某种原因,我需要同时登录两个端点。 - Andre
@Andre:你是在使用Google容器注册表认证插件与Docker构建步骤插件或其他插件吗?我也有点困惑于你的说法“登录到gcr和gcr端点”。你能澄清一下吗?如果你正在使用带有GCR认证插件的Docker构建步骤插件,那么你需要将提供的凭据添加到每个单独的Docker构建步骤命令中。 - Wei

-1

请不要发表仅包含链接的答案,因为链接可能会失效。 - NathanOliver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接