
最近折腾了一下 Google Cloud Storage(GCS),说实话之前一直泡在 AWS 里,S3 用得贼熟,换到 GCP 那边多少有点不适应。踩了几个坑之后,决定把 S3 和 GCS 的概念及命令做个对照,方便有同样需求的朋友少走弯路。
先说结论:如果你的业务已经在 GCP 上(用着 Cloud Run、GKE 或者 Compute Engine),GCS 确实是更顺滑的选择——IAM、KMS、日志这条链路不用跨云折腾,体验会很舒服。但如果你的主战场还在 AWS,那也没必要硬换。
先把两边的核心概念对上号,看懂这张表就懂了一半:
| AWS S3 | Google Cloud Storage |
|---|---|
| Bucket | Bucket(一样) |
| Object | Object(一样) |
| 前缀 / "文件夹" | Object name prefix(虚拟的,和 S3 一样) |
| S3 Versioning | Object Versioning |
| S3 Lifecycle Rules | Lifecycle Management |
| Bucket Policy / IAM | Cloud IAM policies(推荐) |
| ACLs | ACLs(也支持,但一般不推荐用) |
| SSE-S3 / SSE-KMS | Google 管理的加密 / CMEK(Cloud KMS) |
| Pre-signed URL | Signed URL |
| S3 Event Notifications | Pub/Sub Notifications + Eventarc |
核心逻辑是一样的——对象存储,用 bucket 装,用 policy 控制权限。迁移成本其实比想象低,关键是别被细节唬住。
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
这里和 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 的场景很常见——让用户在不登录的情况下下载私有文件,或者直接往存储里上传文件而不暴露服务凭证。GCS 的 Signed URL 实现方式和 AWS 略有不同,但思路是一样的。
通常的做法是:
具体用哪个语言实现要看你的技术栈,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
开了之后,每次覆盖或删除都会保留历史版本,配合生命周期规则可以自动清理旧版本,不然存储成本会悄悄涨上来。
GCS 默认就加密存储数据,大多数场景够用了。如果有合规要求或者需要自己管密钥轮换,可以上 CMEK(Customer-Managed Encryption Keys),这和 S3 的 SSE-KMS 是一个路数。
这块如果有人想看详细步骤(包括 KMS 密钥的最小权限 IAM 配置),可以留言,我可以单独写一篇。
生产环境里,存储访问日志一定要看。主要用到两个服务:
这块 S3 用 CloudWatch Logs,GCS 用自己的日志体系,思路相同,工具不同。
最后总结几个我亲眼见过的坑:
allUsers,出事了很麻烦。说实话,会用 S3 的话,GCS 百分之八十的概念都是相通的。最大的差异其实在权限控制这块——GCP 这边更推荐统一走 IAM + UBLA,而不是混着用各种机制。搞懂了这个,迁移成本比想象低很多。
如果你正在考虑从 S3 迁移到 GCS,或者刚好在踩这个坑,希望这篇文章有点帮助。有问题欢迎留言,踩过的坑也可以说出来,大家一起避雷。