
你的 AWS 帳單每個月都在長,但你不知道錢花在哪裡。等到月底看帳單已經太晚了——那些 NAT 流量費和忘記關的 dev 環境已經燒掉一大筆。
結論:三板斧大家都會,帳單失控的原因在別處
Reserved Instance、Spot、Budget Alert——每篇成本文章都講這三個,我後面也會講。但我看過的帳單失控,原因幾乎都不是沒買 RI,是有幾行錢從來沒人注意過:NAT 的處理費、跨 AZ 的流量、資料傳出、ALB 按用量計費、CloudWatch 收三次、還有忘記關的東西。
這篇不寫單價。理由有三:價格會變、依區域不同、而且沒來源的數字比沒有數字更糟。要數字的時候打開定價頁,那才是唯一權威。
最重要的不是任何技巧,是建立看帳單的習慣。每週一花 15 分鐘看 Cost Explorer,比任何省錢技巧都有效。
一、帳單的三類
| 類 | 特性 | 例 |
|---|---|---|
| 看得到的 | 開的時候就知道要錢 | EC2、Fargate vCPU、RDS 實例、S3 儲存 |
| 看不到的 | 沒人告訴你,帳單來了才發現 | NAT 處理費、跨 AZ 流量、傳出、ALB 用量、log 儲存 |
| 忘記的 | 曾經需要,現在沒人用 | 沒掛載的 EBS、舊快照、閒著的 EIP、測試環境 |
第一類架構師都會算。第二類是這篇的重點。 第三類靠掃描(第四節)。
二、六行看不到的錢
NAT 的處理費——而且我在第 2 篇講了一半
NAT gateway 除了每小時固定費,每處理 1 GB 流量再收一次。這是處理費;流量本身該付的資料傳輸費,照一般規則另外算(VPC 定價頁)。架構圖上 NAT 只是一個方塊,沒人想到「所有對外流量都經過它 = 所有對外流量都被計費一次」。放大點:從 private subnet 拉 ECR image、存 S3、送 log 到 CloudWatch——AWS 自家服務的流量預設也走 NAT。
我在 第 2 篇寫過「開 VPC Endpoint 讓這些流量不經 NAT」。寫完回頭查定價才發現講了一半——Endpoint 分兩種,帳單長得完全不一樣:
- Gateway 型——只有 S3 和 DynamoDB。官方文件原話:「使用 gateway endpoint 不另外收費」。這兩個直接開,沒有理由不開。
- Interface 型——ECR、Secrets Manager、CloudWatch、SQS……全是這種。定價頁的結構是每個 endpoint 在每個 AZ 按小時收費,加上按處理的 GB 收費。開六個服務 × 三個 AZ = 十八個按小時計費的 ENI(Interface endpoint 在每個 AZ 的子網路裡各放一張虛擬網卡,就是它)。
所以「開 Endpoint 省錢」對 S3 永遠成立,對其他服務要拿 NAT 處理費和 Interface endpoint 費用算過。流量小的環境,Interface endpoint 可能比 NAT 還貴。
# S3 Gateway endpoint:不另計費,直接開
aws ec2 create-vpc-endpoint --vpc-id vpc-xxx \
--service-name com.amazonaws.ap-northeast-1.s3 --route-table-ids rtb-private
# ECR Interface endpoint:按小時 × AZ + 按 GB,先算再開
aws ec2 create-vpc-endpoint --vpc-id vpc-xxx --vpc-endpoint-type Interface \
--service-name com.amazonaws.ap-northeast-1.ecr.dkr \
--subnet-ids subnet-private-1a subnet-private-1c --security-group-ids sg-endpoint跨 AZ 流量
同一區域內,資料從 AZ-a 送到 AZ-b 要錢。「高可用要多 AZ」是對的,但沒人講多 AZ 的流量代價:ALB 在 AZ-a 收到請求、轉給 AZ-b 的 task、task 再查 AZ-c 的資料庫——一個請求跨兩次。服務之間互打繞 ALB 的架構,跨 AZ 次數再翻倍。
而且「跨一次」不等於「收一次錢」。AWS 的帳單說明寫明:同一區域內跨 AZ 的傳輸,進和出各計一次。所以每次傳輸,帳單上會有兩筆 DataTransfer-Regional-Bytes(官方文件)。AWS 談託管資料庫傳輸成本的架構部落格,範例也是進、出各計。
例外也有:同一份文件提醒,有些服務的區域內流量不收費。哪一段收、哪一段不收,以該服務的定價頁為準;跨 AZ 收費的總原則見 AWS 的資料傳輸成本總覽。
所以估費用要算兩次:每跨一次 AZ,出去算一次,進來再算一次。
資料傳出
進 AWS 免費,出 AWS 收費(官方文件)。使用者下載檔案、API 回應、送資料給第三方,全算。多數人「知道」這項,但低估量——圖片、影片、大 JSON 回應累積起來很可觀。CloudFront 的傳出費率結構跟直接從 ALB 出去不同,這是加 CDN 的另一半理由。
ALB 按用量計費
ALB 不是「一台多少錢」。除了固定時費,還按 LCU(ALB 衡量用量的單位)計——取新連線數、活躍連線數、處理流量、規則評估次數四者中最高的那個(ELB 定價頁)。流量翻倍 LCU 翻倍;服務間互打也走 ALB 的話,內部呼叫也在燒 LCU。細節在 第 4 篇。
CloudWatch 收三次
送進去收一次、存著每月收、用 Logs Insights 查詢再按掃描量收一次。 「log 開 debug 等級」在自架環境是磁碟問題,在 AWS 是三重帳單。而且 CloudWatch log group 預設永不過期——建的時候不設保留期,它就一直存、一直算。高量的 log 可以改送 S3,要查的時候再用 Athena(直接對 S3 上的檔案下 SQL 的查詢服務)查。
閒置但計費的
沒掛載的 EBS(刪 EC2 時預設不刪 volume)、舊快照、沒綁東西的 EIP(Elastic IP,向 AWS 申請、固定不變的公有 IP)、忘關的 NAT(零流量照算時費)、週末也在跑的測試環境。
EIP 這項的規則在 2024 年 2 月改了。以前是綁著不用錢、閒置才收;現在公有 IPv4(含 EIP)不論綁著還是閒置,都按同一個費率每小時收費(公告、VPC 定價頁)。閒置的 EIP 還是要掃:它一樣在收錢,卻什麼都沒在用。
這些沒有一項是「設定錯」,全是「沒人記得」——所以只能靠掃。
三、三板斧,各講該講的那句
Savings Plan:只對穩定跑超過六個月的負載買,dev 環境和短期專案不要。Compute Savings Plan 比 Reserved Instance 彈性高(不綁 instance type),折扣幅度看定價頁。買之前先跑 AWS 自己的建議:
aws ce get-savings-plans-purchase-recommendation \
--savings-plans-type COMPUTE_SP --term-in-years ONE_YEAR \
--payment-option NO_UPFRONT --lookback-period-in-days SIXTY_DAYSSpot:用 AWS 的閒置容量,代價是隨時可能被收回。官方文件寫的是提前兩分鐘通知,透過 EventBridge 事件和 instance metadata——而且是「盡力而為」,不保證每次都有。所以只放能重跑的東西:CI build、有 checkpoint 的批次、後面有 ALB 接的無狀態 worker。資料庫和有狀態的不要。
ECS 上的做法是混:
aws ecs create-service --cluster prod-cluster --service-name worker \
--task-definition worker:1 --desired-count 5 \
--capacity-provider-strategy '[
{"capacityProvider": "FARGATE_SPOT", "weight": 4, "base": 0},
{"capacityProvider": "FARGATE", "weight": 1, "base": 1}
]'base=1 保證至少一個 task 在 On-Demand 上,Spot 全被收回時服務不會歸零。指定多種 instance type 也能降低被收回的機率。
Budget Alert:我建議設兩道——實際花費到 80% 提醒你注意,預測會超過 100%(AWS 依目前用量推估月底)就有人要看。
aws budgets create-budget --account-id 123456789012 \
--budget '{"BudgetName":"monthly-total","BudgetLimit":{"Amount":"500","Unit":"USD"},"TimeUnit":"MONTHLY","BudgetType":"COST"}' \
--notifications-with-subscribers '[
{"Notification":{"NotificationType":"ACTUAL","ComparisonOperator":"GREATER_THAN","Threshold":80,"ThresholdType":"PERCENTAGE"},
"Subscribers":[{"SubscriptionType":"EMAIL","Address":"ops@example.com"}]},
{"Notification":{"NotificationType":"FORECASTED","ComparisonOperator":"GREATER_THAN","Threshold":100,"ThresholdType":"PERCENTAGE"},
"Subscribers":[{"SubscriptionType":"EMAIL","Address":"ops@example.com"}]}
]'沒設等於「帳單來了才知道」——那時候錢已經花了。
四、標籤與掃描:沒有標籤,上面六項都分不出是誰的
帳單只會告訴你「NAT 花了多少」,不會告訴你「哪個專案的 NAT」。最少三個標籤,每個資源都要有:project、env、owner。強制手段:用 SCP(AWS Organizations 的服務控制政策,限制帳號裡能做哪些動作)擋「沒標籤的資源不能建」;或用 Config rule(AWS Config 的規則,檢查已經存在的資源合不合規定)在資源建好之後抓出沒標籤的。依我的經驗判斷,事後補標籤幾乎不可能——沒人記得那台是誰開的。
閒置資源每月掃一次,三條指令:
# 沒掛載的 EBS
aws ec2 describe-volumes --filters Name=status,Values=available \
--query "Volumes[*].[VolumeId,Size,CreateTime]" --output table
# 沒綁東西的 EIP
aws ec2 describe-addresses \
--query "Addresses[?AssociationId==null].[PublicIp,AllocationId]" --output table
# 舊快照
aws ec2 describe-snapshots --owner-ids self \
--query "Snapshots[?StartTime<='2025-01-01'].[SnapshotId,VolumeSize,StartTime]" --output tableDev 環境下班自動 stop EC2、scale ECS 到零——這條省的錢通常比任何 RI 都多。
五、每個架構決策,帳單上都多一行
| 架構選擇 | 帳單上多的 | 但省的 |
|---|---|---|
| NAT 每個 AZ 一個 | NAT 時費 × AZ 數 | 跨 AZ 流量費 |
| 加 CloudFront | CDN 費 | 傳出費、ALB LCU |
| 開 Interface endpoint | 每 AZ 按小時 + 按 GB | NAT 處理費 |
| RDS Proxy | Proxy 費(按資料庫 vCPU) | — |
| 多區域 | 全部翻倍,加跨區複製流量 | — |
每個「該補」都有對應的帳單行。預算不夠就不要全補。
這篇不放「自架 vs AWS 月費對照」那種表——那些數字沒來源。一句話就夠:AWS 的價值不在便宜,在你不需要半夜三點起來修 server。時間成本算進去,AWS 通常划算;享受自己管機器的人,自架永遠更便宜。
實戰 Checklist
- S3 和 DynamoDB 的 Gateway endpoint 開了;其他服務的 Interface endpoint 算過再開
- 開 Endpoint 前後各看一次 NAT 的
BytesOutToDestination(NAT gateway 往目的地送出的流量,CloudWatch 指標),確認經 NAT 的流量真的降了 - 每個 log group 有保留期;正式環境不開 debug log
- Budget 兩道告警設了,通知到有人看的信箱;另設一個門檻設很低的測試預算,確認通知真的會到
- 每個資源有
project/env/owner標籤,Cost Explorer 按標籤分沒有「未標籤」那塊 - 每月掃一次閒置 EBS、EIP、快照;dev 環境下班自動關
從 K8s 過來的話
自架 K8s 的帳單是一行:機器。AWS 的帳單是幾十行,每個服務各自計費。流量在自己機房內不用錢,在 AWS 要,而且分好幾種。開著不用的東西,自架那邊機器錢早就付了;AWS 這邊照算,NAT、EBS、公有 IPv4 閒著都在收。心智模型也不一樣:自架是買容量,AWS 是按用量計費,每個動作都有價格。
K8s 那邊「機器買了就盡量塞滿」的直覺,在 AWS 會變成「每多開一個服務就多一行」——架構圖上每一個方塊,帳單上至少一行。
Kubecost / OpenCost 那種按 namespace 分攤的做法,在 AWS 對應的是標籤加 Cost Explorer——概念一樣,只是標籤要自己打、而且要在建資源的當下打。
相關文章
省錢最有效的方法不是買 RI,是關掉你忘記在跑的東西。
