Google App Engine 应用无法访问 Google Cloud Storage 存储分区

Posted

技术标签:

【中文标题】Google App Engine 应用无法访问 Google Cloud Storage 存储分区【英文标题】:Google App Engine App failed to access Google Cloud Storage bucket 【发布时间】:2017-07-07 22:52:25 【问题描述】:

无法从 Appengine Project 访问默认的 Google Cloud Storage 存储分区。此项目是使用 1.9.0 之前的 App 引擎 SDK 版本创建的。我已经手动创建了存储桶,按照GCS Documentation,默认情况下,Appengine 项目可以访问存储桶,但在我的情况下它无法访问。这是尝试创建文件的代码 sn-p..

...
GcsService gcsService = GcsServiceFactory.createGcsService();
GcsFilename file = new GcsFilename(getGcsDefaultBucketName(), fileName);
GcsFileOptions.Builder builder = new GcsFileOptions.Builder();
GcsFileOptions options = builder.mimeType(mimeType).build();     
GcsOutputChannel channel = gcsService.createOrReplace(file, options); //erroring in this line
...

在日志中发现错误:

: com.google.appengine.tools.cloudstorage.NonRetriableException: java.lang.RuntimeException: Server replied with 403, verify ACLs are set correctly on the object and bucket: Request: POST https://storage.googleapis.com/1-ebilly.appspot.com/SERVICESTAGEREPORT-DEVICENAME-LYF2-CREATEDDATE-01012017-CREATEDDATE-19022017-.ZIP
: User-Agent: AppEngine-Java-GCS
: Content-Length: 0
: x-goog-resumable: start
: Content-Type: application/zip
: 
: no content: Response: 403 with 212 bytes of content
: X-GUploader-UploadID: AEnB2Upq0Lhtfy5pbt06pVib8J0-L0XiGqW4JpB0G9PL87keY3WV7RCMVLCPeclD-D4UATEddvvwpAG2qeeIxUJx--brKxdQFw
: Content-Type: application/xml; charset=UTF-8
: Content-Length: 212
: Vary: Origin
: <?xml version='1.0' encoding='UTF-8'?><Error><Code>AccessDenied</Code><Message>Access denied.</Message><Details>Caller does not have storage.objects.create access to bucket myprojectID.appspot.com.</Details></Error>
: 
:   at com.google.appengine.tools.cloudstorage.RetryHelper.doRetry(RetryHelper.java:120)
:   at com.google.appengine.tools.cloudstorage.RetryHelper.runWithRetries(RetryHelper.java:166)
:   at com.google.appengine.tools.cloudstorage.RetryHelper.runWithRetries(RetryHelper.java:156)
:   at com.google.appengine.tools.cloudstorage.GcsServiceImpl.createOrReplace(GcsServiceImpl.java:70)

PS:我尝试创建一个新的 Google Appengine 项目并部署了应用程序 init。该项目是使用默认的 GCS 存储桶自动创建的,并且相同的代码可以正常工作,没有任何错误。我的旧项目有很多数据库数据,我想保留这些数据并继续使用同一个项目而不对其进行处理。

请提出您的想法,以使 GCS 存储桶在旧项目中可访问。

【问题讨论】:

我怀疑您的旧存储桶与今天的默认存储桶没有相同的权限。尝试为旧项目创建一个新存储桶,并使用它来获取必要的权限,然后在需要时手动将其应用于旧存储桶。存储桶命名不匹配也是可能的,也许使用明确命名的存储桶(而不是默认应用程序的存储桶)可以解决这种情况。 感谢您的更新,问题已解决,详情请参阅我的回答。 【参考方案1】:

通过为 appengine 项目添加 IAM 许可解决了该问题。在阅读了IAM“项目级别的访问控制”文档并比较了旧项目和新项目的权限后,得知在旧项目中没有找到Appengine项目级权限。添加权限后,相同的代码开始访问默认存储桶。

IAM Permissions before fix screenshot

IAM Permissions after fix screenshot

【讨论】:

【参考方案2】:

试试这个:-

GcsService gcsService = GcsServiceFactory.createGcsService(RetryParams.getDefaultInstance());
GcsFileOptions options = new GcsFileOptions.Builder().mimeType(mime).build();
GcsFilename gcsfilename = new GcsFilename(BUCKET_NAME, fileName);
GcsOutputChannel outputChannel = gcsService.createOrReplace(gcsfilename, options);  

【讨论】:

以上是关于Google App Engine 应用无法访问 Google Cloud Storage 存储分区的主要内容,如果未能解决你的问题,请参考以下文章

Google App Engine 上的 Production App 突然无法访问 Google Cloud Storage

Google Cloud App Engine - gsutil 访问问题

通过 Google Cloud SDK 更新 App Engine 应用程序后无法启动它

Spring Boot 应用在部署到 Google App Engine 时无法连接到 Google Cloud SQL (PostgreSQL)

删除 Google App Engine 应用程序

使用 Google App Engine 时无法导入 Flask