ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AWS成本优化三招:拆账单、清幽灵资源、建制度,省下40%云支出

AWS成本优化三招:拆账单、清幽灵资源、建制度,省下40%云支出 接手公司AWS账号的第一周我没写业务代码也没着急搭新架构而是在Cost Explorer里泡了两天。当时公司在推敏捷研发开发环境一天到晚跑着二十多台8核16G的EC2实例没人想过它们是不是真的需要这么高的配置。直到月底财务把AWS账单截图甩到群里群里安静了十分钟——那一行月度总费用比上个月多了将近两倍。这种“账单惊魂”我见过太多次了。AWS云成本失控不是个例而是绝大多数账号的常态。我后来在几个不同体量的项目中把同一套方法反复打磨最终验证了一个结论在不砍业务、不降性能的前提下一个账号至少能优化掉35%-40%的支出。本文把这套东西分成三招讲清楚第一招借用AWS Well-Architected成本优化支柱给账户做全面体检第二招把ASG缩容后仍然在悄悄计费的“幽灵资源”连根拔起第三招用标签、预算和生命周期策略把成本管理变成制度和日常。全程只依赖AWS原生的账单、监控和治理工具不需要额外买任何FinOps软件。CTO、架构师、运维负责人、云平台管理员都值得从头到尾走一遍。1. 别急着砍配置——先把账单结构拆到Usage Type这一层1.1 为什么只看总账单会越看越焦虑我开始接触成本优化时最先感觉到的是“账单根本看不懂”。Cost Explorer的默认视图按服务堆叠EC2、S3、RDS、数据传输、NAT Gateway条条框框一大堆看起来花了多少钱一目了然可一旦追问“这笔钱是哪个实例花的”“这个S3桶是哪个项目在用”就直接卡壳。所以要做的第一件事不是砍配置而是把账单的粒度打穿打到Usage Type这个字段。AWS账单里有两个维度非常关键一个叫Service它告诉你钱花在了哪个服务上另一个叫Usage Type它会进一步区分出服务里的具体计费动作比如EC2实例小时费、EBS卷存储费、弹性IP闲置费、CloudWatch告警费、跨区域数据传输费。同一个EC2服务Usage Type可能分好几种金额贡献相差巨大如果不拆开看你永远不知道真正的水位在哪里。我习惯的做法是在Cost Explorer里把Group by改成“Usage Type”时间范围选过去三个月先看一个大盘。这时候你会发现账单其实可以分成清楚的三层第一层是核心算力也就是各种EC2和容器实例第二层是配套存储EBS卷、快照、S3、AMI往往占比不小第三层是流量和附加组件比如NAT Gateway的小时费、数据处理费、跨AZ的内网流量费、负载均衡的LCU费。这三层里真正值得动手的往往不是第一层恰恰是第二层和第三层因为算力至少有人知道在跑存储和附加组件却常常成了“账外资源”。1.2 成本失控的四个常见源头结合我服务过的几个项目成本失控几乎逃不出下面四个场景非生产环境开足马力开发、测试、预发环境的实例规格普遍偏大而且7x24小时运行。很多项目的测试环境CPU利用率长期在5%以下却跑着生产同款甚至更高的规格。这部分是“无效算力”的大头。快照与AMI只增不减每次发布或变更前打个快照成了很多团队的本能动作但快照用完就忘了删。时间一长S3、EBS快照、AMI加起来存储费用轻易超过计算费用。伸缩组缩了配套资源没缩开发环境晚上想省钱把Auto Scaling Group的desired置为0以为万事大吉。结果ALB、NAT Gateway、弹性IP、备用EBS卷都还挂着每分钟都在计费。后面我会专门用一章讲这个坑。数据传输费用被忽略跨区域的数据复制、NAT Gateway的数据处理费、S3的GET/PUT请求费每一项单独看都不贵合在一起往往占账单的10%-20%。这四类浪费有个共同点它们都发生在没人负责的角落。只要把这些角落纳入日常巡检清单账单的水分就挤掉了一半。1.3 建立成本基线和单位成本意识很多人只关心“这个月花了多少钱”却忽略了一个更本质的问题钱是否花得有效率。我建议每个业务线选一个核心指标做分母比如订单数、活跃用户数、每日任务数然后定义“单位成本”每万次请求的云成本、每活跃用户的月成本。有了单位成本之后记账本就不只是“涨了还是降了”而是“业务增长是否换来合理的成本增长”。比如一个SaaS客户每月总成本增长了10%听完可能会慌。但拆开看用户量增长了30%单位成本反而下降了15%说明现有架构还有余量。反过来如果用户量持平、成本却涨了那多半是资源闲置或浪费在悄悄增加这才是真正需要担心的。这套“单位成本”思维是所有后续优化动作的基准线。2. 第一招照着Well-Architected的成本支柱给账户做一次全面体检2.1 成本优化支柱到底解决什么问题AWS官方有一门叫做Well-Architected Foundations的基础培训完整框架拆成六大支柱其中“成本优化”Cost Optimization这一支柱在实操中最容易被低估。很多人觉得它是理论其实它更像一张体检清单。它反复逼问三类问题钱花在哪些地方了这些资源是否和业务需求匹配有没有为闲置或低效的资源付费我带着团队做过一轮完整的Cost Optimization Workshop发现仅仅是把这三个问题过一遍就能定位出30%以上的浪费。原因很简单大家在日常开发里习惯的是“能用就行”很少主动问“这个实例还需要吗”“这个快照为什么还留着”。而这套框架的威力就是强迫你用结构化视角去审视整个账号而不是凭记忆挑几个看起来最贵的资源来砍。如果团队里有人是AWS新手我通常建议先把基础服务过一遍市面上像刘鹏老师那本《云计算实战AWS平台应用与开发》就是不错的入门材料学完再带着这套成本框架去重新审视自家账号理解会深很多。但无论是书还是官方培训最终都要落到自己的账单数据上纸上谈兵是省不了钱的。2.2 用工具把闲置资源找出来体检不是靠肉眼要有一组顺手工具。我通常这么组合AWS Compute Optimizer开启后它会收集EC2、Auto Scaling组、Lambda、EBS的利用率数据给出规格调整建议。它比人眼准因为它参考的是过去14天到30天的真实负载曲线。Trusted Advisor高等级支持计划里可以直接看到成本优化检查项比如空闲实例、闲置的EIP、低利用率RDS。如果公司没有买Business支持计划用Compute Optimizer加Cost Explorer也能做一个八九不离十的版本。Cost Explorer 手动账单导出按Usage Type分组找异常波动配合每月的账单CSV做深挖。具体操作步骤上我一般分四步走打开EC2控制台筛选出过去90天CPU平均使用率低于10%的实例对有运行时间规律的实例比如只在工作日跑的任务记录实际负载峰值打开EBS页面筛选出状态为Available的卷这些是空闲卷直接删除风险很低打开弹性IP页面筛选出未关联实例的EIP优先释放。这里给一个真实的案例。某个项目长期挂着一台c5.4xlarge作用是跑每天凌晨的批量数据同步白天CPU利用率不到2%。我们把它降级到t3.large并配置了工作日自动启停一个月下来这部分费用从大约0.68美元/小时降到了0.1美元/小时以内一年省下大约5000美元。更关键的是业务毫无感知因为任务本来就在凌晨跑t3.large到点把活干完用户根本不知道后台规格变小了。2.3 稳态负载用Savings Plans覆盖别让CPU空转还按按需付费体检做完之后成本大头通常只剩两类一类是真正长期运行的生产实例另一类是弹性伸缩的工作负载。对于第一类我强烈建议不要继续按需付费。AWS的Savings Plans和Reserved Instance本质上是用承诺用量换折扣一年的Compute Savings Plans通常能省20%-30%三年期能到40%以上而且Compute类型比EC2类型更宽松覆盖范围包括EC2、Fargate、Lambda可以跨实例族和区域。选Savings Plans的关键是“承诺多少”不能拍脑袋。我的做法是把过去30天所有实例的按需费用拉出来按小时维度画出负载曲线取一个“持续基线”——比如夜里的最低水位——然后用这个最低水位去购买SP而不是按峰值去买。因为SP一旦买了即使资源不用承诺金额也照付。宁可买少再补On-Demand也不要买多导致浪费。在我们那个客户里这一招直接把EC2账单砍掉了约25%而且几乎零风险。2.4 无状态和批处理任务迁到Spot弹性真的可以更便宜第二种工作负载是“突然有弹性需求但随时可被打断”的任务比如CI/CD构建、大数据分析、爬虫、批处理任务、以及一部分无状态API服务Spot实例是最适合的载体。Spot的价格通常是按需价的10%-20%代价是实例可能随时被回收所以必须有优雅的退出和重试机制。我在落地时一般用两个方案一个是在ASG里配置混合实例策略让On-Demand和Spot按比例混跑保证基础容量不受影响另一个是给EKS或ECS搭一个独立的Spot节点组用Pod反亲和把无状态应用调度到Spot节点上有状态应用继续留在On-Demand节点。要注意的是Spot并非所有实例族都有充足的库存必须以实际可用为准建议用多个可用区和多个实例类型组合别把“省钱的宝”全押在一个冷门实例族上。2.5 体检报告怎么写管理层才愿意配合很多架构师把优化做成了一堆命令行最后汇报给管理层时对方只想知道三件事省了多少钱、有没有风险、需要批多少预算。我通常会产出一页纸的体检报告分成四个区块现状概览本月成本与趋势、闲置资源清单已清理和待清理、优化动作降配、SP、Spot、预计节省金额与风险等级。每一类优化都要标注“可回滚方案”比如降配后如果业务压力升高可以随时回到原规格SP则要强调承诺期内的不可变性。这样写管理层才愿意签字推进而不是觉得你在拿生产环境冒险。3. 第二招ASG的desired设为0后仍在扣费问题出在“关联资源”3.1 一个深夜排查的真实场景记得有一次我从周五晚上开始把某个测试环境的ASG desired capacity设为0想着周末没人用让账单“歇口气”。周一一早收到AWS的预算告警点开Cost Explorer一看测试环境所在账号的EC2费用确实下去了但账单总额并没像预期那样少太多。顺着服务维度细看问题出在NAT Gateway、负载均衡器和EBS卷上——它们还在按小时计费。当时我的第一反应是怀疑ASG没缩干净但进控制台一查实例列表确实空了。后来才意识到这里有个非常典型的认知误区ASG缩到0只代表EC2实例没有了不代表这个环境里所有关联资源都免费了。很多人把“ASG”理解成整个环境的开关但它其实只是一个弹性调度组件只管“拉起或杀掉实例”没有义务帮你清理负载均衡、NAT、EBS、弹性IP和快照。3.2 为什么desired0不等于账单归零ASG的职责边界要理解这个坑先说清楚ASG的职责边界。Auto Scaling Group管理的最小单元是EC2实例它负责根据策略扩缩容决定实例数量、实例类型、子网、安全组、启动模板。当desired0ASG会终止全部实例但这些实例被终止后关联资源并不会跟着消失挂在ASG前面的ALB或NLB只要没被单独删除就会继续产生小时费和LCU费用在VPC里创建的NAT Gateway哪怕后面没有流量了小时费和数据通道费照收启动模板里如果设置了额外的EBS卷且DeleteOnTermination没有被显式设成true实例终止后卷可能变成Available状态继续按容量计费如果为环境预留了弹性IP实例释放后EIP没有自动释放未关联EIP每小时仍有费用顺手打过的快照和AMI它们跟EC2实例生命周期解耦只能靠人工或脚本清理。我做过一个小实验一个标准的三层测试环境ALB ASG(desired0) NAT Gateway 2个EBS卷在完全没有任何流量的情况下每个月仍会产生约60-80美元的固定费用。一个月还好一年就是近千美元如果环境多金额就非常可观。3.3 从Cost Explorer到控制台的完整排查路径如果你也遇到“ASG已经缩到0但账单还很高”的情况我建议按下面这条链路排查不要直接去删资源先定位再动手打开Cost Explorer把Group by设为Usage Type时间缩小到最近7天先看除纯实例费之外的其他项目关注这几个Usage Type的异常NatGateway-Hourly、NatGateway-Bytes、LoadBalancerUsage、EBS:VolumeUsage、ElasticIP:IdleAddress、DataTransfer-Regional-Bytes在EC2控制台点开“Volumes”筛选状态为Available的卷在“Elastic IPs”里看有没有未关联地址在VPC控制台看NAT Gateways列表确认哪些状态是Active但没有被关键路由表引用在EC2的“Snapshots”和“AMIs”页面按创建时间排序找出两周之前的遗留物如果启用了资源标签用Resource Groups Tag Editor按Environmenttest一键过滤能快速圈出整条环境的所有资源。排查完成后清理顺序我一般这么定先释放弹性IP再删除NAT Gateway再处理负载均衡器然后删除Available状态的EBS卷最后按保留策略清理快照和AMI。3.4 用IaC把资源生命期绑在一起才能根治排查和清理只能解决眼前的问题真正让这类“幽灵资源”不再出现要靠基础设施即代码IaC。把整套测试环境写成一个CloudFormation模板或Terraform模块让ALB、NAT Gateway、EBS卷、ASG都在同一个Stack里管理想关环境就直接销毁整个Stack资源生命周期自然就绑在一起了。另外还有两个细节值得注意第一在启动模板的块设备映射里显式把DeleteOnTermination设为true避免实例终止后根卷残留第二给环境里所有资源统一打上Environment和Project标签以后清理脚本只需要按标签扫描“desired0但关联资源仍存活”的资源即可。我在实际运维里会每月跑一次扫描脚本找出标签为test环境、但ASG desired0且仍有存活ALB或NAT的资源自动发通知到责任人。这套机制上线后那个客户再也没有出现过“环境关了还在扣费”的问题。4. 第三招把标签、预算和生命周期规则做成“看不见的成本管理员”4.1 标签统一设计是成本分配和追踪的根基如果说前面两招是“外科手术”那标签体系就是“预防医学”。没有标签Cost Explorer只能看服务维度的粗账没法回答“这笔钱是哪个项目花的”也没法给业务线做内部成本核算。我建议从第一天就定下一组最小标签集合别贪多够用就行Environment区分prod、staging、dev、testProject或Service标识业务模块Owner标识资源负责人方便出问题时找人CostCenter用于财务分摊。标签的价值在资源创建的那一刻就决定了所以最好通过SCP或Terraform provider配置强制要求关键资源必须带标签不能指望开发人员每次都记得。有了这套标签Cost Explorer里就能按标签维度做成本分解业务部门看到自己的账单心里有数也会主动起来这比运维单方面催着省钱高效得多。4.2 预算加异常检测让超支信号第一时间到人很多账号开了成本优化但没有“告警机制”等账单出来才傻眼。AWS的Budgets服务就是干这个的建议至少建两类预算一类是月度总成本预算一类是按标签或服务拆分的预算。预算阈值不要只设一个我通常设三档用了80%提醒、90%提醒、100%紧急通知告警通过SNS转发给钉钉或企业微信机器人。另一个容易被忽略的是Cost Anomaly Detection它基于历史账单做机器学习能在当天发现异常突增。曾经某个账号里一个S3桶因为循环任务每天产生几百万次GET请求若不是异常检测当天报警等到月底看到账单估计又多花了几千美元。这个服务不需要太复杂的配置新建一个监控器过几天它自己就学会“正常曲线”了。4.3 S3存储分层与快照策略存储类成本优化常被忽略存储费用不像计算费用那样每天刷新存在感但它非常顽固。对于S3我建议从两个角度优化第一用生命周期策略让数据自动降温第二定期清理过期版本和删除标记。标准做法是把桶里的数据按访问频率分层最近3个月热数据放Standard3个月到1年的冷数据转Standard-IA或Glacier Instant Retrieval超过1年的备份转Glacier Flexible Retrieval几乎不再访问的归档转Deep Archive。费用差异非常大Deep Archive每GB每月的价格大约是Standard的1/20还低而生命周期规则本身不需要人工干预。对于EBS快照我推荐用Data Lifecycle Manager按标签设定保留天数比如保留7天或30天超过后自动删除。这个工具比手动快照可靠得多。4.4 在组织层面用SCP挡住浪费源头如果账号不止一个到了Organization层面还有一道“制度性防线”可用Service Control Policy。SCP本身不收费但能挡住很多浪费源头。我遇到过最典型的例子是某业务线在非合规region开了实例账单乱得无法追溯。用SCP限制只能使用指定region创建EC2、RDS等资源是治理的第一步。SCP也能限制实例规格。比如禁止创建超过16 vCPU的按需实例除非走特定审批流程。这两条策略一上开发环境就不会再冒出“随手拉一台32核机器”的情况。要注意的是SCP不能替代预算和异常检测它更像是把马路护栏修好让车不容易开翻。另外如果你在AWS账号里用了Tag Policy还能对成本标签的合规性做统一校验从源头保证账单分层不失效。5. 从“月底看账单”到“每天看成本”落地路线图与我的执行笔记5.1 两周打底搭建成本治理框架的时间表我帮好几个团队落地成本治理都遵循同一个时间表核心是“先建基线再动刀子最后固化制度”第1天用Cost Explorer导出过去6个月的账单CSV建立成本基线表按服务和Usage Type分别汇总理解当前的费用结构。第3天开启AWS Budgets月度预算、Cost Anomaly Detection、SNS告警先把“发现问题的机制”建起来。第4-7天完成标签体系设计并对存量资源批量打标。这里不能省否则后面所有按标签维度的分析都失效。第2周运行Compute Optimizer梳理闲置实例、空闲卷、游离EIP、过期快照做第一批低风险清理。第3-4周购买Savings Plans、调整实例规格、把无状态工作负载迁到Spot。第5周起进入常态化运营每周看一次成本报表每月做一次月度Review。这套节奏下来一般在第二个月底就能明显看到账单变化不需要等半年。5.2 一组典型数字优化前后对比与40%是怎么算出来的有人可能觉得40%是个标题党我把一个典型测试环境的成本数据摊开来看具体金额随区域和业务不同会有浮动但比例有参考价值项目优化前月费用美元优化后月费用美元节省原因EC2按需实例42002050降配SP覆盖非生产环境按工作时间启停EBS卷与快照1100520删除Available卷和过期快照、DLM自动清理NAT Gateway与ALB700350desired0时销掉整条环境不保留空转负载数据传输与API请求830650收敛跨region访问减少冗余API调用弹性IP与CloudWatch500380释放游离EIP、精简告警合计73303950节省约46%这个例子里优化前EC2占比很高到后来EC2相关费用少了约一半非计算类的存储和附加服务也从2300多美元降到1550美元。整体下来省了3380美元比例约46%。你可以看到真正的大头不在某一个单项而是每个环节都挤掉一点水分积少成多。5.3 持续运营每周看什么、每月Review什么成本优化做完一票就完事的心态是最容易让数字反弹的。我在团队里建立了固定的运营节奏。每周我会看三样东西Cost Explorer的周趋势有没有突增点Budgets的使用率是否快触及阈值Cost Anomaly Detector有没有报警如果有立刻追日志。每月做一次完整的Cost Review拉上各业务线的负责人把本月费用和上月、年初对比一遍重点解释异常增量发生在哪个模块并确认下个月的优化动作。这套频率听起来密集实际上每次只用10到20分钟。时间花得值因为成本问题和稳定性问题一样你在它刚冒头时处理成本最低一旦拖到月底账单生成定位难度和修复成本都会成倍上升。5.4 三个容易反弹的坑提前给你踩过了第一个坑只优化存量不管增量。优化完一个月很爽下个月开发又开了新实例没人记得加标签。我建议把Tag强制策略和SCP审批流程提前做好不然新资源一多前面的账又乱了。第二个坑在非生产环境买了大量Savings Plans。SP的本质是长期承诺如果测试环境本来就要降配或者只在白天运行买SP反而把你未来的灵活性锁死了。我的原则是“先有一年的稳定负载基线再买3年期SP”宁愿少买也别套牢。第三个坑忽略了DataTransfer。很多时候算力费用优化到位了但跨区域流量、NAT数据处理费悄悄涨最终账单看起来还是高。建议把Cost Explorer的Usage Type里所有带DataTransfer的项单列一档每周观察趋势。这三条是我自己在实践中踩过或帮客户排查过的列在这里希望大家一次绕开。最后说点私人体会。做了几年AWS成本治理我最深的感觉是这项工作的难点不在于技术而在于“让成本意识成为团队习惯”。账单看得懂、资源生命周期管得住、有人为每一块钱负责这三个条件一旦同时成立40%根本不算激进目标。这套方法不是让我自己变省而是让团队在花钱时多问一句“值不值”那才是成本不反弹的真正原因。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进