同项目GKE节点中Python访问GCS Bucket遇403权限错误,gsutil正常
问题描述
在同一GCP项目的GKE节点容器内,执行gsutil ls能正常列出GCS Bucket内容,但使用google-cloud-storage库的Python代码访问时触发403权限错误:
raise exceptions.from_http_response(response)
google.api_core.exceptions.Forbidden: 403 GET https://storage.googleapis.com/storage/v1/b/xxxxxxxx/o?maxResults=1&projection=noAcl&prefix=test%2F&prettyPrint=false: Caller does not have storage.objects.list access to the Google Cloud Storage bucket. Permission 'storage.objects.list' denied on resource (or it may not exist).
使用的Python代码如下:
import google.cloud.storage as gcs client = gcs.Client() BUCKET_NAME = "abc" blobs = client.list_blobs( BUCKET_NAME, prefix="xyz/", # <- 需要末尾的斜杠 delimiter="/", max_results=1, ) next(blobs, ...) # 强制加载blobs列表
排查与解决方案
1. 核对凭据使用差异
gsutil会自动适配GKE的身份机制(比如节点服务账号或工作负载身份),但Python客户端可能未正确获取到有效凭据:
- 检查容器内是否设置了
GOOGLE_APPLICATION_CREDENTIALS环境变量,若未设置,Python客户端会尝试使用GKE默认的工作负载身份凭据。 - 可在代码中明确指定项目ID,避免跨项目混淆:
client = gcs.Client(project="你的GCP项目ID")
2. 检查Pod服务账号权限
确保运行Pod的Kubernetes服务账号已正确配置权限:
- 如果使用工作负载身份:确认K8s服务账号已绑定拥有
storage.objects.list权限的GCP服务账号(可分配Storage Object Viewer或更精细的自定义角色)。 - 如果使用节点默认服务账号:确认节点的GCP服务账号已具备目标Bucket的
storage.objects.list权限(不推荐此方式,风险较高)。
3. 验证凭据有效性
在容器内执行以下命令验证当前凭据是否有权限访问Bucket:
# 获取默认应用凭据的token TOKEN=$(gcloud auth application-default print-access-token) # 调用GCS API测试 curl -H "Authorization: Bearer $TOKEN" "https://storage.googleapis.com/storage/v1/b/你的Bucket名/o?prefix=xyz/"
如果返回403,说明凭据确实缺少权限;若返回正常列表,则排查代码逻辑(比如Bucket名称是否拼写错误)。
4. 确认Bucket名称正确性
注意错误提示里也提到“资源可能不存在”,检查代码中BUCKET_NAME是否与实际Bucket名称完全一致(区分大小写)。
内容的提问来源于stack exchange,提问作者Anon1284712

