GKE中TeamCity容器推送镜像至GCR遇权限错误求助
我之前也碰到过一模一样的问题,这个报错的核心原因其实很好理解:Google Container Registry(GCR)本质是基于Cloud Storage构建的,当你第一次推送镜像到某个GCR仓库(比如eu.gcr.io/coopr-mod/myimage:1)时,GCP会自动尝试创建对应的Cloud Storage存储桶,而你的GKE节点使用的服务账号没有storage.buckets.create权限,所以才会触发这个报错。
下面是具体的解决步骤:
第一步:找到GKE节点池使用的服务账号
GKE节点默认会使用一个服务账号来访问GCP服务,我们需要先定位到这个账号:
方法一:通过GCP控制台操作
- 打开GCP控制台,进入「Kubernetes Engine」→「集群」,找到你的目标集群;
- 切换到「节点池」标签页,点击你正在使用的节点池;
- 在「节点配置」区域找到「服务账号」,记下这个账号的邮箱(格式类似
xxx@coopr-mod.iam.gserviceaccount.com)。
方法二:通过gcloud命令行操作
执行以下命令(替换占位符为你的集群信息):
gcloud container node-pools describe YOUR_NODE_POOL_NAME \ --cluster YOUR_CLUSTER_NAME \ --zone YOUR_CLUSTER_ZONE
在输出结果中找到serviceAccount字段,就是我们需要的服务账号邮箱。
第二步:给服务账号添加必要的权限
我们需要给这个服务账号添加能创建存储桶、读写镜像对象的权限,有两种方案可选:
方案一:快速解决(授予Storage Admin角色)
如果追求快速解决,直接给服务账号授予Storage Admin角色(这个角色包含了所有Cloud Storage相关的权限,足够覆盖GCR的推送需求):
控制台操作
- 进入「IAM & Admin」→「IAM」页面;
- 在搜索框输入刚才记下的服务账号邮箱,找到对应的条目;
- 点击条目右侧的「编辑」按钮,然后点击「添加另一个角色」;
- 在角色列表中搜索「Storage Admin」,选中后保存即可。
命令行操作
执行以下命令(替换占位符为你的服务账号邮箱):
gcloud projects add-iam-policy-binding coopr-mod \ --member serviceAccount:YOUR_NODE_SERVICE_ACCOUNT@coopr-mod.iam.gserviceaccount.com \ --role roles/storage.admin
方案二:最小权限原则(拆分角色)
如果你想遵循最小权限原则,可以添加两个更精细的角色:
roles/storage.bucketCreator:允许创建Cloud Storage存储桶(解决当前的storage.buckets.create权限报错);roles/storage.objectAdmin:允许读写存储桶中的镜像对象;
执行以下两条命令即可:
# 添加创建桶的权限 gcloud projects add-iam-policy-binding coopr-mod \ --member serviceAccount:YOUR_NODE_SERVICE_ACCOUNT@coopr-mod.iam.gserviceaccount.com \ --role roles/storage.bucketCreator # 添加读写镜像对象的权限 gcloud projects add-iam-policy-binding coopr-mod \ --member serviceAccount:YOUR_NODE_SERVICE_ACCOUNT@coopr-mod.iam.gserviceaccount.com \ --role roles/storage.objectAdmin
补充说明
你构建步骤中的gcloud auth configure-docker在GKE容器环境中其实不是必须的——GKE节点默认会挂载节点服务账号的凭证,Docker可以自动利用这个凭证访问GCR。如果后续你想给TeamCity容器单独分配更精细的权限,可以考虑配置Workload Identity,不过那是更进阶的配置,先解决当前问题的话,上面的步骤就足够了。
内容的提问来源于stack exchange,提问作者xetra11

