Google Cloud S3 팁

@Pfaffman 이 Google Cloud 관련 정보를 따로 분리해 두었습니다. 원문(OP)에 꼭 포함되지 않아도 되지만, Google Cloud에서 문제를 겪고 있는 사람들을 위해 보관해 두면 좋겠습니다.


안녕하세요,

팁에 감사하지만, 역할을 Storage Legacy Object Owner에서 Storage Legacy Bucket Owner로 변경하기 전까지는 저에게는 작동하지 않았습니다.

역할을 선택할 때 툴팁에 구체적으로 이렇게 적혀 있습니다:

Storage Legacy Object Owner

목록 표시 없이 기존 객체에 대한 읽기/쓰기 접근 권한.

Storage Legacy Bucket Owner

객체 목록 표시/생성/삭제를 포함하여 기존 버킷에 대한 읽기 및 쓰기 접근 권한.

이제 목록 표시 기능이 포함되도록 작동하며, 이를 통해 자동 백업이 가능합니다! 드디어 성공 !!

3개의 좋아요

Google Buckets에서 S3 사용에 대해:

여기서 언급했듯이:
https://meta.discourse.org/t/using-object-storage-for-uploads-s3-clones/148916/334
버킷에 Storage Legacy Bucket Owner Role이 있는 서비스 계정을 사용하면 목록 조회가 작동하고 자동 백업도 정상적으로 작동한다는 것을 확인했습니다.

Google Bucket에 S3를 사용할 경우 Amazon과 Google에서 동일한 이름을 가진 Region만 선택할 수 있음을 유의하십시오.
백엔드 검증이 포함된 드롭다운 메뉴(성공적으로 시도하지 못한 API 조작을 시도했습니다)에서 선택해야 하는 대신 직접 입력할 수 없다는 점이 어리석게 느껴집니다.

이것은 예를 들어 유럽의 버킷을 사용할 수 없음을 의미합니다. Amazon에서는 접두어가 EU인 반면 Google에서는 EUROPE이며, 멀티리전도 사용할 수 없습니다.

AWS:

Region Name Code
US East (Ohio) us-east-2
US East (N. Virginia) us-east-1
US West (N. California) us-west-1
US West (Oregon) us-west-2
Africa (Cape Town) af-south-1
Asia Pacific (Hong Kong) ap-east-1
Asia Pacific (Jakarta) ap-southeast-3
Asia Pacific (Mumbai) ap-south-1
Asia Pacific (Osaka) ap-northeast-3
Asia Pacific (Seoul) ap-northeast-2
Asia Pacific (Singapore) ap-southeast-1
Asia Pacific (Sydney) ap-southeast-2
Asia Pacific (Tokyo) ap-northeast-1
Canada (Central) ca-central-1
China (Beijing) cn-north-1
China (Ningxia) cn-northwest-1
Europe (Frankfurt) eu-central-1
Europe (Ireland) eu-west-1
Europe (London) eu-west-2
Europe (Milan) eu-south-1
Europe (Paris) eu-west-3
Europe (Stockholm) eu-north-1
Middle East (Bahrain) me-south-1
South America (São Paulo) sa-east-1

Google:

Continent Region Name Region Description
North America
NORTHAMERICA-NORTHEAST1 Montréal leaf icon Low CO2
NORTHAMERICA-NORTHEAST2 Toronto leaf icon Low CO2
US-CENTRAL1 Iowa leaf icon Low CO2
US-EAST1 South Carolina
US-EAST4 Northern Virginia
US-EAST5 Columbus
US-SOUTH1 Dallas
US-WEST1 Oregon leaf icon Low CO2
US-WEST2 Los Angeles
US-WEST3 Salt Lake City
US-WEST4 Las Vegas
South America
SOUTHAMERICA-EAST1 São Paulo leaf icon Low CO2
SOUTHAMERICA-WEST1 Santiago
Europe
EUROPE-CENTRAL2 Warsaw
EUROPE-NORTH1 Finland leaf icon Low CO2
EUROPE-SOUTHWEST1 Madrid leaf icon Low CO2
EUROPE-WEST1 Belgium leaf icon Low CO2
EUROPE-WEST2 London
EUROPE-WEST3 Frankfurt
EUROPE-WEST4 Netherlands
EUROPE-WEST6 Zürich leaf icon Low CO2
EUROPE-WEST8 Milan
EUROPE-WEST9 Paris leaf icon Low CO2
Asia
ASIA-EAST1 Taiwan
ASIA-EAST2 Hong Kong
ASIA-NORTHEAST1 Tokyo
ASIA-NORTHEAST2 Osaka
ASIA-NORTHEAST3 Seoul
ASIA-SOUTH1 Mumbai
ASIA-SOUTH2 Delhi
ASIA-SOUTHEAST1 Singapore
Indonesia
ASIA-SOUTHEAST2 Jakarta
Australia
AUSTRALIA-SOUTHEAST1 Sydney
AUSTRALIA-SOUTHEAST2 Melbourne

또한 이러한 옵션을 Files Settings에서 설정해야 한다는 것도 어리석게 생각합니다. 저는 파일 업로드에 S3를 사용하지 않았으며, 백업에만 사용합니다. 업로드와 백업에는 서로 다른 버킷이 필요하지만, 리전을 설정할 수 있는 곳은 Files Settings에만 하나뿐입니다.

이 정보가 다른 누군가가 이 문제를 파악하는 데 시간을 절약하는 데 도움이 되기를 바랍니다.

PS: https://discourse.example.com/logs/ 를 사용하여 디버깅했습니다.
…
Failed to list backups from S3: The specified location constraint is not valid. → Region 문제
…
Failed to list backups from S3: Access denied. → Storage Legacy Object Owner 대신 Storage Legacy Bucket Owner

1개의 좋아요

OP에서 설명한 대로 ENV 변수를 사용하여 설정하고 DISCOURSE_S3_ENDPOINT를 권장대로 설정하면 DISCOURSE_S3_REGION은 무시되므로 이 문제는 더 이상 존재하지 않습니다.

2개의 좋아요

감사합니다.
문제는 제가 Google Cloud 마켓플레이스의 Bitnami VM 원클릭 설치 기능을 사용하고 있다는 점입니다.
환경 변수를 사용자 지정하는 것은 가능할 수 있지만, 그 과정이 간단하지는 않습니다.
UI에서 엔드포인트를 설정해도 리전이 무시되지 않습니다.

어쨌든 감사합니다.

감사합니다!
실제로 스니펫을 추가하는 것을 잊었습니다.

불행히도 다음과 같은 오류가 발생합니다:

Aws::S3::Errors::InvalidArgument: Invalid argument.

웹 UI를 사용할 때 발생한 오류와 매우 일치하지만, 문제를 해결할 만한 단서가 별로 없습니다…

Amazon S3와 Google Storage 간 호환성 문제가 있을 수 있다는 것을 시사하는 이 스레드를 찾았습니다.

Google Storage에서 깨진 것일 수 있나요?

작업을 수동으로 실행할 때의 전체 스택:

root@discourse-2-app:/var/www/discourse# sudo -E -u discourse bundle exec rake s3:upload_assets --trace
** Invoke s3:upload_assets (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke s3:ensure_cors_rules (first_time)
** Invoke environment 
** Execute s3:ensure_cors_rules
Installing CORS rules...
skipping
** Execute s3:upload_assets
Uploading: assets/docker-manager-app-ecd2975f42c4096057a046c086d6a43905c8a18442900d5293ae9a3489422bb0.js
rake aborted!
Aws::S3::Errors::InvalidArgument: Invalid argument.
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/raise_response_errors.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/sse_cpk.rb:24:in `call'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/dualstack.rb:27:in `call'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/accelerate.rb:56:in `call'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/checksum_algorithm.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/jsonvalue_converter.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/idempotency_token.rb:19:in `call'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/param_converter.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/request_callback.rb:71:in `call'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/response_paging.rb:12:in `call'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/response_target.rb:24:in `call'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-core-3.130.2/lib/seahorse/client/request.rb:72:in `send_request'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/client.rb:12369:in `put_object'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/object.rb:1472:in `put'
/var/www/discourse/lib/s3_helper.rb:75:in `upload'
/var/www/discourse/lib/tasks/s3.rake:37:in `block in upload'
/var/www/discourse/lib/tasks/s3.rake:36:in `open'
/var/www/discourse/lib/tasks/s3.rake:36:in `upload'
/var/www/discourse/lib/tasks/s3.rake:192:in `block (2 levels) in <main>'
/var/www/discourse/lib/tasks/s3.rake:191:in `each'
/var/www/discourse/lib/tasks/s3.rake:191:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `block in execute'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `each'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `execute'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `invoke_with_call_chain'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:188:in `invoke'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:160:in `invoke_task'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `each'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block in top_level'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:125:in `run_with_threads'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:110:in `top_level'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:83:in `block in run'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:186:in `standard_exception_handling'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:80:in `run'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.7.0/bin/rake:25:in `load'
/var/www/discourse/vendor/bundle/ruby/2.7.0/bin/rake:25:in `<top (required)>'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli/exec.rb:58:in `load'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli/exec.rb:58:in `kernel_load'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli/exec.rb:23:in `run'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli.rb:485:in `exec'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli.rb:31:in `dispatch'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/cli.rb:25:in `start'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/exe/bundle:48:in `block in <top (required)>'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/lib/bundler/friendly_errors.rb:120:in `with_friendly_errors'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.3.20/exe/bundle:36:in `<top (required)>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'
Tasks: TOP => s3:upload_assets

P.S. 버킷을 변경하는 것은 고려하지 않고 있지만, VM 디스크에 이미 업로드된 이미지들은 어떻게 될지 궁금합니다.

수정 (해결됨):
@gerhard @Falco
http_wire_trace를 활성화하여 문제의 원인을 찾았습니다.
googleapis에서 반환된 잘못된 인자 응답이 이를 설명합니다:
일괄 버킷 수준 액세스가 활성화된 상태에서는 객체에 레거시 ACL을 삽입할 수 없습니다. 자세한 내용은 Uniform bucket-level access  |  Cloud Storage  |  Google Cloud Documentation 를 참조하세요.

업로드 시 설정되는 헤더가 공개적(public)임을 지정하기 때문에, 일괄 ACL 대신 버킷에 세분화된 ACL을 활성화했습니다. (일괄 ACL을 사용하면서 전체 버킷을 공개로 설정해 두었던 상태였습니다.)

OP를 업데이트할 권한은 없지만, Google 버킷이 작동하려면 서비스 계정에 Storage Legacy Bucket Owner 역할이 있어야 하고 업로드 버킷에는 세분화된 ACL을 사용해야 한다는 점을 언급해야 한다고 생각합니다.

이것이 커뮤니티의 시간을 절약하는 데 도움이 되기를 바랍니다.
여기서 도움을 주신 @Falco @pfaffman @gerhard @tuanpembual 에게 다시 한번 감사드립니다.

2개의 좋아요