site logo

Marico's space

从 S3 迁移到 Google Cloud Storage?我把两边的命令对照了一遍

服务器技术 2026-04-20 12:44:47 9

从 S3 迁移到 Google Cloud Storage?我把两边的命令对照了一遍

最近折腾了一下 Google Cloud Storage(GCS),说实话之前一直泡在 AWS 里,S3 用得贼熟,换到 GCP 那边多少有点不适应。踩了几个坑之后,决定把 S3 和 GCS 的概念及命令做个对照,方便有同样需求的朋友少走弯路。

先说结论:如果你的业务已经在 GCP 上(用着 Cloud Run、GKE 或者 Compute Engine),GCS 确实是更顺滑的选择——IAM、KMS、日志这条链路不用跨云折腾,体验会很舒服。但如果你的主战场还在 AWS,那也没必要硬换。

概念速查:S3 → GCS

先把两边的核心概念对上号,看懂这张表就懂了一半:

AWS S3Google Cloud Storage
BucketBucket(一样)
ObjectObject(一样)
前缀 / "文件夹"Object name prefix(虚拟的,和 S3 一样)
S3 VersioningObject Versioning
S3 Lifecycle RulesLifecycle Management
Bucket Policy / IAMCloud IAM policies(推荐)
ACLsACLs(也支持,但一般不推荐用)
SSE-S3 / SSE-KMSGoogle 管理的加密 / CMEK(Cloud KMS)
Pre-signed URLSigned URL
S3 Event NotificationsPub/Sub Notifications + Eventarc

核心逻辑是一样的——对象存储,用 bucket 装,用 policy 控制权限。迁移成本其实比想象低,关键是别被细节唬住。

创建 Bucket

S3 里是 aws s3 mb s3://...,GCS 用 gcloud 命令,差不多一个套路:

PROJECT_ID="your-project-id"
BUCKET_NAME="your-unique-bucket-name"
LOCATION="us-central1"

gcloud storage buckets create gs://$BUCKET_NAME \
 --project=$PROJECT_ID \
 --location=$LOCATION

几个注意点:Bucket 名称全球唯一(和 S3 一样),位置可以选单区域、双区域或多区域,存储类别也有 Standard、Nearline、Coldline、Archive 之分。建议一开始就想好命名规范,后面改起来麻烦。

上传、下载、列举

操作上比 AWS CLI 顺手一点点,语法很直观:

# 上传
echo "hello gcs" > hello.txt
gcloud storage cp hello.txt gs://$BUCKET_NAME/hello.txt

# 列举
gcloud storage ls gs://$BUCKET_NAME

# 下载
gcloud storage cp gs://$BUCKET_NAME/hello.txt hello.txt
cat hello.txt

权限控制:IAM vs ACLs(重点)

这里和 S3 有个挺大的区别,值得重点说说。

S3 那边大家习惯用 bucket policy 或者直接给 IAM 角色,但 ACL 也能用,很多人混着用。GCS 这边推荐的玩法是:IAM + Uniform bucket-level access(UBLA),尽量别碰 object-level ACL,除非你有特别细粒度的需求。

开启 UBLA:

gcloud storage buckets update gs://$BUCKET_NAME --uniform-bucket-level-access

然后通过 IAM 授权,干净利落。举个例子,给某个用户只读权限:

USER_EMAIL="dev@example.com"

gcloud storage buckets add-iam-policy-binding gs://$BUCKET_NAME \
 --member="user:$USER_EMAIL" \
 --role="roles/storage.objectViewer"

类比 S3 的话,这更像是用 IAM policy 控制访问,而不是靠 object ACL 逐个授权。统一层级访问在生产环境里管理起来也省心得多。

公开访问:小心别踩坑

公开 bucket 是个大坑,我见过不少人在这里翻车。如果只是放静态网站资源,建议走 Cloud CDN 或者 Load Balancer,别直接裸开公开访问。

确实需要公开读的话,命令不复杂:

gcloud storage buckets add-iam-policy-binding gs://$BUCKET_NAME \
 --member="allUsers" \
 --role="roles/storage.objectViewer"

这和 S3 的 s3:GetObject"Principal": "*" 开放的 bucket policy 是一个意思。生产环境里务必配合组织策略、安全审查和日志告警一起用,别图省事。

签名 URL:Pre-signed URL 的等价物

签名 URL 的场景很常见——让用户在不登录的情况下下载私有文件,或者直接往存储里上传文件而不暴露服务凭证。GCS 的 Signed URL 实现方式和 AWS 略有不同,但思路是一样的。

通常的做法是:

  1. 创建一个有签名权限的服务账号
  2. 用这个账号生成带过期时间的签名 URL

具体用哪个语言实现要看你的技术栈,Node.js、Python、Go 都有现成的库支持。如果你想看哪个语言的示例,留言告诉我。

生命周期规则:管住成本

生命周期规则主要是帮你省钱——自动删掉超过一定时间的对象,或者把它们迁移到更便宜的存储类别。GCS 这边用 JSON 配置:

# lifecycle.json
{
 "rule": [
  {
   "action": { "type": "Delete" },
   "condition": { "age": 30 }
  }
 ]
}

# 应用
gcloud storage buckets update gs://$BUCKET_NAME --lifecycle-file=lifecycle.json

这个 JSON 结构比 S3 的 XML 直观多了,30天自动清理不用手动管。建议早点配,别等账单来了再后悔。

版本控制:防止手滑覆盖

开启版本控制可以避免误删或覆盖文件,和 S3 的 Versioning 几乎一样:

gcloud storage buckets update gs://$BUCKET_NAME --versioning

开了之后,每次覆盖或删除都会保留历史版本,配合生命周期规则可以自动清理旧版本,不然存储成本会悄悄涨上来。

加密:默认够用,想要更严用 CMEK

GCS 默认就加密存储数据,大多数场景够用了。如果有合规要求或者需要自己管密钥轮换,可以上 CMEK(Customer-Managed Encryption Keys),这和 S3 的 SSE-KMS 是一个路数。

这块如果有人想看详细步骤(包括 KMS 密钥的最小权限 IAM 配置),可以留言,我可以单独写一篇。

日志和审计:别忽略这个

生产环境里,存储访问日志一定要看。主要用到两个服务:

  • Cloud Audit Logs:追踪谁在什么时间访问了什么
  • Cloud Logging:聚合日志,方便查异常行为(比如短时间内大量删除操作,或者来自陌生身份的访问)

这块 S3 用 CloudWatch Logs,GCS 用自己的日志体系,思路相同,工具不同。

S3 用户迁移常踩的坑

最后总结几个我亲眼见过的坑:

  1. Bucket 名称全局唯一:和 S3 一样,名称抢注的问题依然存在,想好了名字就早点注册。
  2. "文件夹"是假的:前缀只是逻辑上的,实际存储还是扁平结构,别被 UI 迷惑了。
  3. IAM 和 ACL 别混用:开了 UBLA 之后,ACL 就失效了,混用会把自己搞晕。
  4. 公开访问要谨慎:生产环境别图方便直接开 allUsers,出事了很麻烦。
  5. 存储成本要关注:存储类别、操作次数和出网流量都算钱,尽早上生命周期规则。

小结

说实话,会用 S3 的话,GCS 百分之八十的概念都是相通的。最大的差异其实在权限控制这块——GCP 这边更推荐统一走 IAM + UBLA,而不是混着用各种机制。搞懂了这个,迁移成本比想象低很多。

如果你正在考虑从 S3 迁移到 GCS,或者刚好在踩这个坑,希望这篇文章有点帮助。有问题欢迎留言,踩过的坑也可以说出来,大家一起避雷。