如何确定GKE集群使用的IAM服务账号
GKE Pod访问GCS权限报错时溯源实际使用服务账号的方法
1. Pod侧直接查询当前生效的身份
这是最直接的验证方式,不需要依赖日志:
- 进入异常Pod的容器内部,执行命令调用GCP元数据服务,直接获取默认凭证对应的服务账号邮箱:
curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/email
返回结果就是当前容器内走默认ADC(应用默认凭证)链的请求使用的GCP服务账号。
- 检查Pod的K8s资源配置,确认Workload Identity绑定关系:
执行命令导出Pod配置:
重点核对两个配置项:kubectl get pod <故障Pod名称> -n <Pod所在命名空间> -o yamlspec.serviceAccountName:Pod绑定的Kubernetes服务账号(KSA)- 元数据annotations下的
iam.gke.io/gcp-service-account字段:该字段标注的是当前KSA映射的GCP服务账号(GSA),如果该字段不存在,Pod会默认继承所在节点池绑定的计算引擎服务账号。
- 若Pod未配置Workload Identity,查询对应节点池的服务账号:
返回结果中gcloud container node-pools describe <Pod所在节点池名称> \ --cluster <GKE集群名称> \ --region <集群所属地域>config.serviceAccount字段的值,就是节点VM使用的默认服务账号。
注意:如果容器内配置了GOOGLE_APPLICATION_CREDENTIALS环境变量指向本地密钥文件,或者应用代码里硬编码了其他密钥,元数据接口返回的结果不会生效,需要额外检查容器环境变量和应用配置。
2. GCS侧通过审计日志溯源请求主体
如果无法登录Pod排查,可以直接从请求落盘的审计日志定位身份:
- 进入Cloud Logging日志查询页面,针对目标存储桶筛选权限拒绝的请求日志,过滤条件如下:
resource.type="gcs_bucket" resource.labels.bucket_name="<目标存储桶名称>" protoPayload.status.code=7
其中code=7对应IAM权限拒绝的请求类型。
- 找到和故障时间完全匹配的日志条目,展开
protoPayload.authenticationInfo字段:principalEmail字段的值就是发起该次请求的实际账号- 如果
principalEmail格式为serviceAccount:<项目号>-compute@developer.gserviceaccount.com,说明请求使用的是GCE默认服务账号 - 如果
principalEmail格式为system:serviceaccount:<命名空间>/<KSA名称>,说明Workload Identity的角色绑定缺失,KSA没有权限模拟对应的GSA,请求直接以K8s服务账号身份发起。
3. 常见配置偏差校验点
- 若确认使用的是预期绑定的GSA但仍报权限错误,检查该GSA是否被授予了
roles/iam.workloadIdentityUser角色,且角色信任主体必须为格式正确的KSA全限定名:serviceAccount:<项目号>.svc.id.goog[<命名空间>/<KSA名称>] - 检查节点池是否开启了Workload Identity特性,未开启的节点池无法正常使用GKE Workload Identity能力,Pod会强制回退使用节点服务账号
- 检查集群是否配置了工作负载身份的命名空间注解,部分场景下命名空间级别的注解缺失会导致Pod无法正确挂载GSA身份凭证
内容的提问来源于stack exchange,提问作者William Moran
相关产品推荐
相关产品推荐

