GCP Cloud Build构建Dockerfile时无法访问GCS桶文件的权限问题
错误原因
你遇到的401权限错误,核心是执行gsutil cp操作的身份缺少GCS对象的storage.objects.get权限,具体分为两种场景:
1. Cloud Build默认服务账号缺少权限
Cloud Build构建任务默认使用专属服务账号:[你的项目编号]@cloudbuild.gserviceaccount.com。在Cloud Build环境中,元数据服务器会自动为这个账号提供凭据,可能会覆盖你在Dockerfile中设置的GOOGLE_APPLICATION_CREDENTIALS环境变量,导致实际访问GCS用的是Cloud Build服务账号而非你提供的project-key.json对应的账号。如果这个服务账号未被赋予GCS对象的读取权限,就会触发匿名访问的权限拒绝错误。
需要给该服务账号添加Storage Object Viewer角色(包含storage.objects.get权限),或者更精细地授予特定存储桶的storage.objects.get权限。
2. 构建上下文未包含project-key.json文件
如果执行Cloud Build构建时,你的构建上下文目录(即运行gcloud builds submit时指定的目录)里没有project-key.json,或者该文件被.dockerignore/.gcloudignore排除,那么Dockerfile中的COPY project-key.json /app/project-key.json命令会失败,导致GOOGLE_APPLICATION_CREDENTIALS指向的文件不存在。此时gsutil无法获取有效凭据,只能以匿名身份访问GCS,从而触发权限错误。
解决方法
给Cloud Build服务账号添加权限:
执行以下命令为Cloud Build服务账号添加Storage Object Viewer角色:gcloud projects add-iam-policy-binding 你的项目ID \ --member="serviceAccount:$(gcloud projects describe 你的项目ID --format='value(projectNumber)')@cloudbuild.gserviceaccount.com" \ --role="roles/storage.objectViewer"检查构建上下文文件:
确认project-key.json在构建上下文目录中,同时检查.dockerignore和.gcloudignore文件,确保没有排除该文件。
内容的提问来源于stack exchange,提问作者David Radianu

