从Google Artifact Registry拉取镜像至Container-Optimized OS VM遇权限错误
问题背景
我尝试通过Google Cloud Build在Container-Optimized OS Compute Engine虚拟机上拉取并运行Artifact Registry中的镜像,使用的cloudbuild.yaml配置如下:
steps: - name: 'gcr.io/cloud-builders/gcloud' args: - compute - ssh - --zone - "us-central1-a" - $_SSH_STRING - --project - $PROJECT_ID - -- - docker pull us-central1-docker.pkg.dev/$PROJECT_ID/us/$_IMAGE_NAME:latest && - docker run -d -p 1338:1338 us-central1-docker.pkg.dev/$PROJECT_ID/us/$_IMAGE_NAME:latest
执行gcloud builds submit --config cloudbuild.yaml .后,虚拟机内部返回权限错误:
Error response from daemon: Head "https://us-central1-docker.pkg.dev/v2/myProjectId/us/imageName/manifests/latest": denied: Permission "artifactregistry.repositories.downloadArtifacts" denied on resource "projects/myProjectId/locations/us-central1/repositories/us" (or it may not exist)
已确认PROJECTNUMBER-compute@developer.gserviceaccount.com(Compute Engine默认服务账号)已配置Artifact Registry Reader、甚至Administrator角色,以及包含artifactregistry.repositories.downloadArtifacts权限的自定义角色,但问题依旧。手动SSH到虚拟机执行相同命令也会触发同样错误,且镜像确实存在。
补充:错误发生在虚拟机内部,并非Cloud Build权限问题;Ubuntu系统可通过安装Cloud SDK并执行gcloud auth configure-docker $_ARTIFACT_ZONE-docker.pkg.dev配置凭证助手解决,但Container-Optimized OS需要适配方案。
解决方案
1. 为Container-Optimized OS配置Docker凭证助手
Container-Optimized OS预装了精简版Cloud SDK,可直接在虚拟机内配置Docker访问Artifact Registry的凭证。将配置步骤加入Cloud Build的SSH命令中,修改后的cloudbuild.yaml如下:
steps: - name: 'gcr.io/cloud-builders/gcloud' args: - compute - ssh - --zone - "us-central1-a" - $_SSH_STRING - --project - $PROJECT_ID - -- - gcloud auth configure-docker us-central1-docker.pkg.dev --quiet && - docker pull us-central1-docker.pkg.dev/$PROJECT_ID/us/$_IMAGE_NAME:latest && - docker run -d -p 1338:1338 us-central1-docker.pkg.dev/$PROJECT_ID/us/$_IMAGE_NAME:latest
--quiet参数用于跳过交互确认,适配自动化执行场景。
2. 验证虚拟机服务账号绑定
虽然已配置权限,仍需确认目标虚拟机确实使用了配置好权限的服务账号:
- 进入GCE控制台,找到目标虚拟机
- 查看详情页的服务账号字段,确认使用的是
PROJECTNUMBER-compute@developer.gserviceaccount.com - 如果绑定的是其他服务账号,需为对应账号配置Artifact Registry下载权限
3. 启用Workload Identity(长期方案推荐)
若需要虚拟机长期稳定访问Artifact Registry,建议配置Workload Identity,避免依赖临时凭证:
- 创建或使用现有服务账号,赋予
Artifact Registry Reader角色 - 在GCE虚拟机配置中启用Workload Identity,将虚拟机关联到该服务账号
- 配置Artifact Registry仓库的IAM权限,允许该服务账号下载镜像
- 在虚拟机内配置Docker使用Workload Identity凭证:
gcloud auth configure-docker us-central1-docker.pkg.dev --workload-identity --quiet
4. 检查仓库与镜像信息的准确性
确认命令中的仓库区域(us-central1)、仓库名称(us)和镜像名称与实际配置完全一致,避免因拼写错误导致权限检查失败。
内容的提问来源于stack exchange,提问作者Adham

