我在一个Google Compute VM上,并试图将容器从那里推送到工件注册表。我是项目的所有者/管理员。
当我运行docker push时...我得到错误
denied: Permission "artifactregistry.repositories.uploadArtifacts" denied on resource "projects/<MY_PROJECT>/locations/<MY_LOCATION>/repositories/<MY_REPOSITORY>" (or it may not exist)
运行gcloud auth list
显示服务帐户*****-compute@developer.gserviceaccount.com
。
运行gcloud auth configure-docker
显示了似乎正在配置的docker
{
"credHelpers": {
"<MY_LOCATION>-docker.pkg.dev": "gcloud",
"gcr.io": "gcloud",
"us.gcr.io": "gcloud",
"eu.gcr.io": "gcloud",
"asia.gcr.io": "gcloud",
"staging-k8s.gcr.io": "gcloud",
"marketplace.gcr.io": "gcloud"
}
}
最后,运行gcloud artifacts docker images list <MY_REPOSITORY>
does 返回一个当前工件的列表,因此显然该帐户具有读取权限。
编辑:我尝试了几个其他的方法。我已经进入虚拟机的页面并启用Allow full access to all Cloud APIs
,重新启动虚拟机,但仍然被阻止。我甚至试图通过在虚拟机上设置google auth登录来使用我的项目所有者凭据(在虚拟机外工作正常)。仍然被阻止。
我已经为服务帐户设置了读/写角色,我已经重新启动了我的VM,但没有任何工作。请帮助!
解决:需要的步骤是
1.转到Google compute上的VM示例,并确保选择了Allow full access to all Cloud APIs
1.转到IAM并将Artifact Registry的权限设置为写入(包括隐式读取)。
1.在虚拟机内部,运行gcloud auth configure-docker <YOUR_LOCATION>
。最后一部分是关键的。看起来这个命令仍然默认为gcr,并且还没有为Artifact注册表更新。
1条答案
按热度按时间1aaf6o9v1#
解决这个问题的关键是在Compute Engine中运行时理解授权。有两种授权方法:服务帐户和ADC(应用程序默认凭据)。
默认情况下,会为每个Compute Engine示例分配一个服务帐户。在您的示例中,已为VM分配
*****-compute@developer.gserviceaccount.com
。此外,计算引擎具有
Access Scopes
。此功能将限制分配给服务帐户的权限。VM访问范围不授予权限。这些权限经常与OAuth Access Scopes
混淆。它们相似,但用于不同的目的。转到Google Cloud Console,编辑VM,然后选择
Allow full access to all Cloud APIs
。该选择并不意味着VM现在可以访问所有内容。它实际上意味着服务帐户不再受限制,权限现在由分配给服务帐户的IAM角色管理。接下来,将所需的IAM角色添加到服务帐户,以便您可以上传到Artifact Registry。IAM角色的列表在这里。所需的权限是
artifactregistry.repositories.uploadArtifacts
。在这种情况下使用的一个好角色是Artifact Registry Writer
(roles/artifactregistry.writer)。更多细节在这里。在这个答案的开头,请注意授权方法ADC(应用程序默认凭据)。ADC是一种搜索凭据的方法。在Compute Engine上运行时,除非直接指定,否则Google Cloud工具和SDK库将搜索凭据。CLI命令
gcloud auth application-default login
link允许您设置要使用的凭据,而不是Compute Engine服务帐户。ADC将在服务帐户创建的凭据之前选择CLI存储的凭据。(VM服务帐户或应用程序默认凭据)既是便利功能,也是安全问题。通过只使用服务帐户凭据,您可以锁定虚拟机。如果您与具有强大权限的用户一起使用gcloud auth ..
,则绕过了服务帐户的安全功能。如果您选择使用ADC,则在完成后执行此命令:
gcloud auth application-default revoke