EBS / EFS / S3:AWS 儲存三兄弟
你的資料該放哪?EC2 的本地磁碟重開機就沒了、S3 便宜但不能當硬碟掛、EFS 方便但貴——三種儲存各有各的坑。
先講結論
EBS 是 Block Storage,掛在單台 EC2 上當硬碟用,適合 DB 和需要低延遲 I/O 的場景。EFS 是 File Storage(NFS),多台 EC2 / ECS 可以同時掛,適合共享檔案。S3 是 Object Storage,幾乎無限容量、按用量計費,適合靜態檔案、備份、Log。90% 的場景你會用 S3,需要當硬碟用才選 EBS,需要共享才選 EFS。
EBS:你的雲端硬碟
EBS 就是掛在 EC2 上的虛擬硬碟。EC2 本身的 Instance Store 在 stop/terminate 後會消失,所以重要資料一定要掛 EBS。
Volume 類型
| 類型 | IOPS | 吞吐量 | 場景 |
|---|---|---|---|
| gp3 | 3,000(可加到 16,000) | 125 MB/s(可加到 1,000) | 通用,大多數場景 |
| io2 | 64,000 | 1,000 MB/s | 高 IOPS DB(Oracle、大型 PG) |
| st1 | 500 | 500 MB/s | 大量循序讀寫(Log、Data Warehouse) |
| sc1 | 250 | 250 MB/s | 冷資料、備份 |
2026 年的建議:除非有特殊需求,一律用 gp3。gp3 比 gp2 便宜 20%,而且 IOPS 和吞吐量可以獨立調整。
# 建立 gp3 Volume
aws ec2 create-volume --volume-type gp3 \
--size 100 --iops 3000 --throughput 125 \
--availability-zone ap-northeast-1a \
--tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=db-data}]'
# 掛載到 EC2
aws ec2 attach-volume --volume-id vol-xxx --instance-id i-xxx --device /dev/xvdf
# SSH 進 EC2 後格式化 + 掛載
sudo mkfs -t xfs /dev/xvdf
sudo mkdir /data
sudo mount /dev/xvdf /data
# 設定開機自動掛載(nofail 很重要)
echo '/dev/xvdf /data xfs defaults,nofail 0 2' | sudo tee -a /etc/fstab
nofail很重要——萬一 volume 沒掛上,加了這個參數機器還是能正常開機,不加的話整台會卡住。
EBS Snapshot:備份利器
# 建立 Snapshot
aws ec2 create-snapshot --volume-id vol-xxx \
--description "db-data daily backup" \
--tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=db-data-backup}]'
# 從 Snapshot 還原
aws ec2 create-volume --snapshot-id snap-xxx \
--volume-type gp3 --availability-zone ap-northeast-1a
# 自動化:用 Data Lifecycle Manager
aws dlm create-lifecycle-policy --description "Daily DB backup" \
--state ENABLED \
--execution-role-arn arn:aws:iam::123456789012:role/AWSDataLifecycleManagerRole \
--policy-details '{
"PolicyType": "EBS_SNAPSHOT_MANAGEMENT",
"ResourceTypes": ["VOLUME"],
"TargetTags": [{"Key": "Backup", "Value": "daily"}],
"Schedules": [{
"Name": "DailySnapshot",
"CreateRule": {"Interval": 24, "IntervalUnit": "HOURS", "Times": ["03:00"]},
"RetainRule": {"Count": 7}
}]
}'EFS:多台機器共享的 NFS
EFS 是託管的 NFS,多台 EC2 / ECS Task 可以同時讀寫同一個檔案系統。
# 建立 EFS
aws efs create-file-system --performance-mode generalPurpose \
--throughput-mode bursting \
--tag Key=Name,Value=shared-storage
# 建立 Mount Target(每個 AZ 一個)
aws efs create-mount-target --file-system-id fs-xxx \
--subnet-id subnet-private-1a --security-groups sg-efs
aws efs create-mount-target --file-system-id fs-xxx \
--subnet-id subnet-private-1c --security-groups sg-efs
# 在 EC2 上掛載
sudo yum install amazon-efs-utils -y
sudo mkdir /shared
sudo mount -t efs fs-xxx:/ /sharedEFS 的坑:費用
EFS 的單價是 EBS gp3 的 3 倍。如果你只是單台 EC2 需要儲存,用 EBS。EFS 只在你真的需要多台機器共享時才值得。
| EBS gp3 | EFS Standard | S3 Standard | |
|---|---|---|---|
| 價格 (GB/月) | $0.08 | $0.30 | $0.023 |
| 存取方式 | Block (mount) | NFS (mount) | API (GET/PUT) |
| 延遲 | <1ms | ~ms | ~100ms |
| 共享 | 單台 EC2 | 多台 EC2/ECS | 無限 |
| 容量上限 | 64 TB | 無限 | 無限 |
S3:無限容量的物件儲存
S3 不是硬碟,它是物件儲存。你不能 mount 它、不能隨機讀寫——你只能 PUT 和 GET 整個檔案。但它便宜、耐用(11 個 9)、幾乎無限容量。
常見用途
- 靜態網站 / CDN Origin
- 應用程式上傳的檔案(圖片、影片、文件)
- 備份(DB dump、EBS snapshot)
- Log 歸檔
- Data Lake
基本操作
# 建立 Bucket
aws s3 mb s3://my-app-uploads-prod --region ap-northeast-1
# 上傳檔案
aws s3 cp backup.sql.gz s3://my-app-uploads-prod/backups/
# 同步整個目錄
aws s3 sync ./dist s3://my-app-uploads-prod/static/ --delete
# 設定 Lifecycle Rule:30 天後轉到 IA、90 天後轉到 Glacier
aws s3api put-bucket-lifecycle-configuration \
--bucket my-app-uploads-prod \
--lifecycle-configuration '{
"Rules": [{
"ID": "archive-old-files",
"Status": "Enabled",
"Filter": {"Prefix": "logs/"},
"Transitions": [
{"Days": 30, "StorageClass": "STANDARD_IA"},
{"Days": 90, "StorageClass": "GLACIER"}
],
"Expiration": {"Days": 365}
}]
}'S3 儲存等級
| 等級 | 價格 (GB/月) | 取用費 | 適合 |
|---|---|---|---|
| Standard | $0.023 | 免費 | 經常存取的資料 |
| Standard-IA | $0.0125 | $0.01/GB | 偶爾存取(備份) |
| Glacier Instant | $0.004 | $0.03/GB | 很少存取但要快 |
| Glacier Deep | $0.00099 | $0.02/GB + 12hr | 法規歸檔 |
經驗談:Log 先丟 Standard,30 天自動轉 IA,90 天轉 Glacier,一年後刪除。光這一條 Lifecycle Rule 就能省 70% 的 Log 儲存費。
S3 安全:預設全鎖
# 擋掉公開存取(預設就是擋的,但確認一下)
aws s3api put-public-access-block --bucket my-app-uploads-prod \
--public-access-block-configuration \
'BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true'
# 開 Server-Side Encryption
aws s3api put-bucket-encryption --bucket my-app-uploads-prod \
--server-side-encryption-configuration '{
"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}]
}'自架 vs AWS
| 面向 | 自架 | AWS |
|---|---|---|
| Block Storage | LVM + XFS/EXT4 | EBS |
| File Storage | NFS Server / GlusterFS | EFS |
| Object Storage | MinIO | S3 |
| 備份 | rsync + cron | EBS Snapshot / S3 Lifecycle |
| 容量規劃 | 自己買硬碟擴充 | 線上調整、無上限 |
| 耐用性 | RAID + 備份 | 11 個 9(S3) |
如果你在 Infra 系列讀過 MinIO,S3 就是 MinIO 的原型——API 相容、概念相同,但 AWS 幫你管好了底層。Container Registry 選擇的相關討論,看 Cloud 系列 Container Registry。
K8s 映射
| AWS Storage | K8s 對應 |
|---|---|
| EBS | PersistentVolume (EBS CSI Driver) |
| EFS | PersistentVolume (EFS CSI Driver) |
| S3 | 沒有直接對應(用 S3 SDK / s3fs-fuse) |
| EBS Snapshot | VolumeSnapshot (CSI) |
| Storage Class (gp3/io2) | StorageClass |
在 EKS 上,用 EBS CSI Driver 讓 PVC 自動建立 EBS Volume。詳見 K8s Storage。
系列導覽
儲存的選擇不是「哪個最好」,而是「你的資料多常被讀、多久不碰、能不能丟」。