ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

从AWS自建K8s到Sealos:一年省下87万的云成本优化实践

从AWS自建K8s到Sealos:一年省下87万的云成本优化实践 离那份季度成本报表交上去已经过去两个月了CFO现在偶尔路过我们办公区还会用一种“真没想到你能办成”的眼神看我。也难怪他那样想毕竟我在汇报里写的是把公司跑在 AWS 上的自建 K8s 集群体系整体迁到基于 Sealos 的 Kubernetes 平台后一年在基础设施上少花了 87 万人民币。这不是预算里砍出来的数字也不是把某笔费用挪到了下一年而是过去 12 个月实际账单和现在这套新平台的真实成本对比。写下这篇文章就是想把当时怎么算的账、怎么决策的、怎么迁的以及中间踩过的坑完整地说清楚。如果你也在为 AWS 账单头疼或者正在运维多套自建 K8s 集群希望这篇能给你一条可以照着走的路线。我先把结论放在前面如果你们的业务只是几个小服务、跑在 AWS 上一个集群里那你大概率不需要做这个迁移因为省不出多少。但如果你们的云账单里同时出现了 EC2、负载均衡、NAT、EBS 快照、跨可用区流量费用而且你们还雇了专职运维在维护多套 Kubernetes——那就值得认真坐下来按我下面这套方法算一遍。87 万的开销不是被谁莫名其妙收走的而是被一整套高成本的架构选择逼出来的。1. 先用最笨的方法把账单拆开看看钱漏在了哪里刚开始说要迁出 AWS团队里反对的声音不少。有个同事说得挺直接“我们又不是没用过 K8s之前自己装集群天天半夜修 etcd现在用云省心多了为什么要动”我理解这种感受但作为这次项目的负责人我不能凭感觉做决定。我做的第一件事是拉出过去 12 个月的 AWS 账单按服务项目重新归类用 Excel 一张张拆把每一笔花费都标清楚归属哪一个集群、哪一条业务线。这一拆问题立刻浮出来了。表面上看最大的支出当然是 EC2 计算资源但真正恐怖的是那些“周边费用”。我在下边放一张当时整理的简化版月度成本表数字做了脱敏但各项的比例和我们当时的真实分布基本一致。成本项覆盖内容月度成本人民币计算节点EC2 节点池、三台 master、堡垒机、监控 Agent约 72000网络相关NLB/CLB、NAT 网关、跨可用区流量、镜像拉取带宽约 19000存储EBS 数据盘、快照、S3 低频访问约 16000托管或自建控制面开销K8s 控制面资源预留、etcd 高可用、安全补丁升级约 11000运维人力折算版本升级、排障、处理证书过期、业务方频繁提需求约 20000月度合计大约 13.8 万一年就是 165 万往上。这个数字还是在我们已经尽量用完预留实例的情况下。你会发现很多人算 K8s 成本时只盯着“节点单价 × 数量”但实际账单里网络、存储、控制面冗余三块加起来占比一点都不比计算少。尤其是跨可用区流量A 可用区到 B 可用区之间每传 1GB 都是钱而你的应用为了“高可用”恨不得把所有服务都搞成双活流量翻倍费用也翻倍。1.1 自建 K8s 的隐藏成本比你想的更伤我们在 AWS 上的 K8s严格说是自建用 kubeadm 在 EC2 上初始化集群master 节点自己管etcd 自己管网络插件自己管。这种方案有一个好处是省钱因为不需要付 EKS 的控制平面服务费但代价是运维成本全部扔给了团队。最典型的场景就是环境初始化。新加一套生产集群 kubeadm init 之后偶尔会收获一个“the api server is not healthy after 4m0.00747357s”的报错。这个报错一出现etcd 容器、kubelet 参数、容器运行时、安全组规则都要从头查一遍。有时候只是因为某个节点的时区没对齐有时候又是镜像仓库拉取超时一个半夜就这么没了。这种成本不会出现在 AWS 账单里但它实实在在地消耗了团队人力。我把这部分按时薪折算成钱大家才意识到问题不在于 AWS 收费高而在于我们维持这套架构的动作本身太贵了。1.2 资源预留和浪费是账单膨胀的加速器三台 master 做高可用要预留足够的 CPU 和内存给 etcd 和 kube-apiserver每个 worker 节点上系统组件、日志采集器、监控 Agent 又要吃掉一部分资源。等到在线业务真正跑起来节点规格明明看着够实际可调度资源却少了 15% 上下。为了保证大促稳定性我们只好继续加节点加完又发现负载不均衡部分节点资源的实际使用率只有 40%。所以当我看到账单一年比一年高第一反应不是去跟 AWS 商务聊折扣而是先问一个问题这些多出来的节点到底是为业务买的还是为 K8s 自身的运维复杂度买的。答案很扎心相当一部分是为后者买的。2. 87 万是这样算出来的云账单加人力全口径对比很多公司做技术方案对比时只喜欢比“云厂商账单”却从来不比“运维人力”。我这次换了一个统计口径TCO也就是总拥有成本。包括所有云资源费用、备份容灾费用、专线和带宽费用以及团队投入到集群维护上的时间折算。只有口径统一才能说服 CFO也才能说服我自己。2.1 新旧平台的价格模型对比我们最后选定的替代方案是把业务迁到基于 Sealos 的 Kubernetes 平台。Sealos 本质上是一个建立在 K8s 之上的云操作系统它把集群管理、应用编排、存储、网关这些能力做成了标准化模块。对使用者来说不再需要关心“这台节点上的 K8s 组件健不健康”而是直接面对一个统一的资源池和应用管理面。这一层抽象带来的直接收益体现在三方面。第一控制面的运维成本大幅下降因为集群生命周期、证书、etcd 备份这些事都不再需要人工盯。第二资源利用率明显提升平台可以把零散的集群整合成更大的资源池容器调度粒度更细系统组件占用也被压缩。第三存储和网络方案不再绑定云厂商的专有服务而是基于开源技术栈实现成本结构透明很多。为了不凭印象说话我把两种模式下一个中等规模业务的年度成本做成了一张对比表。这个业务模型是30 条后端服务、10 套测试环境、20 多套 K8s namespace、每天峰值订单约 5 万笔。成本域AWS 自建 K8s年成本Sealos 平台年成本差异基础计算约 86 万约 52 万-34 万网络与负载均衡约 23 万约 9 万-14 万块存储与快照约 18 万约 9 万-9 万集群控制面维护约 15 万约 3 万-12 万运维人力约 42 万2 人全职约 24 万1 人负责平台侧-18 万合计约 184 万约 97 万-87 万这 87 万的来源就清清楚楚了。计算节省占大头但不只是计算。网络、存储、控制面维护、人力每一项都省出可观数字。CFO 觉得我在吹牛是因为他习惯只看到 AWS 那几张账单但在我的视角里真正的成本还包括我们一年里为了集群稳定消耗掉的一百多个“深夜”以及团队因为疲于救火而写不出的自动化工具。2.2 为什么 Sealos 模型下资源利用率能变高我简单解释一下这个数字背后的机制。自建 K8s 集群分散管理时每个团队各自建集群各自留峰值冗余资源。A 团队的平台业务在晚间跑满B 团队的数据任务在凌晨跑满但两者是彼此隔离的谁也没法借对方的空闲资源。汇总到统一的 Sealos 资源池之后调度器可以把不同峰谷的服务混合部署到同一批节点上白天让平台类容器多用 CPU晚上把资源让给离线任务。资源利用率从 40% 提升到 70%需要的物理节点自然就少了。另一个关键点是存储。以前我们用 EBS每块盘都要支付固定容量费用快照还要额外按量计费。迁移后我们把一部分适合本地盘的中间件改为本地存储另一部分需要持久化的数据放到分布式的自建存储上成本从“按云盘规格付费”变成“按实际使用容量付费”。光这一项每年就能省出接近十万。3. 替换而不是裸迁从 AWS 到 Sealos 的分阶段实施记录账算明白了剩下的事情就是怎么迁。我要强调一个观念这不是“把服务器搬个家”而是“换一套运行方式”。我们的目标不是零停机地把所有容器搬过去而是让新旧两套环境并存一段时间让流量逐步切换保证每一分钟业务都是可用的。整个迁移从启动到全部业务跑在新平台上一共花了 11 周。前 6 周都在做盘点和环境搭建真正割接核心生产流量只有 4 个周末窗口。3.1 第一步把所有服务盘点清楚建立迁移清单第一步的工作非常枯燥但也最容易决定成败。我们给每一个服务建了一张“迁移卡”卡片上记录这些信息服务在 K8s 里的 Namespace、Deployment、Service、Ingress 定义是否使用了 StatefulSet挂载了哪些存储存储是否允许停机配置项来自 ConfigMap 还是 Secret配置读取方式是文件还是环境变量服务间调用关系哪些服务之间有内部 DNS 依赖对外暴露的入口是需要保留统一公网域名还是走内部网关当时业务侧觉得我们太慢花了两周都在“填表”。但事实证明迁移事故有 80% 都出在“我忘了这个服务还用了一个旧配置文件”或者“这个 CronJob 平时不跑月底才触发一次”上。迁移卡把这些隐藏依赖全部暴露出来之后后续操作反而快了很多。3.2 第二步先在 Sealos 平台搭建一套“影子环境”影子环境的意思是新环境不直接承接线上流量而是把生产流量复制一份过来让新平台上的服务真实处理这些请求但返回结果不落库、不返回给用户只和旧环境的处理结果做对比。我们通过一个边缘代理把线上请求按 1:1 复制到影子环境重点观察三件事新环境下服务的 P99 延迟是否和旧环境一致日志和链路追踪里是否出现新错误磁盘、网络、CPU 消耗是否符合预期影子环境运行了两周期间我们发现了 3 个问题一个是旧环境里有一条服务通过公网 IP 互相调用到了新环境因为网络策略不通请求超时另一个是一个老系统还依赖 AWS 的内网 DNS 解析新环境解析不到还有一个是某个 Java 服务的 JVM 参数在新平台上内存分配不合理频繁触发 GC。这些问题如果不跑影子环境直接切流量绝对是一次生产事故。影子环境的原理很简单就是“以极小代价换取迁移验证”。你不需要改造业务代码只需要在网关层做流量复制就能提前获得线上流量在新架构上的表现。我给很多团队推荐过这套做法但很少有团队愿意多花这两周时间总觉得“直接切就行了”结果最后都是切完再回滚折腾半宿。3.3 第三步有状态服务的迁移才是真正考验耐心的地方业务服务大多是无状态的重建容器没有任何心理负担。真正麻烦的是数据库和中间件。我们环境里有 MySQL、Redis、RabbitMQ 三类有状态服务。它们的迁移方式完全不同。MySQL 采用了“主从同步 切换”的方式。先在旧集群上给 MySQL 增加一个从节点从节点开在新平台的存储上让新节点实时复制旧主节点的 binlog。等到数据追平到秒级延迟后把旧主节点短暂设置为只读等最后一波 binlog 同步完成再把应用连接切换到新节点上原地提升为主。整个过程只有大概 3 分钟的写不可用时间挑在业务低谷执行影响可以接受。Redis 的迁移要简单一些因为我们的 Redis 主要做缓存和临时会话存储。策略是启动一个新集群把流量切换前先把热点数据预热进去切换后靠回源动态补冷数据。关键是要设置一个较短的过期时间兜底避免旧集群里的缓存数据在新集群查询不到时引发雪崩。RabbitMQ 的队列数据没法直接停机恢复。我们采用的方法是增加消费者把积压消息尽快消费完再切换生产端保证不丢消息。这里踩过一个坑旧集群里有一批消息一直停留在 DLQ 死信队列里我们一度以为这些消息不消费也没关系结果切换后对新环境发起了重试风暴。后来我们学到一个教训迁移前一定要统计每个队列的积压量、死信量和业务方确认哪些消息可以直接丢弃不要想当然全部搬过去。3.4 第四步分阶段切流量而不是某一天晚上“一刀切”一切准备好之后流量切换是分四天完成的。周一先切了 5% 的内部测试流量周二把内部管理系统和后台任务切过去周三切一个独立的边缘业务周四才切核心链路。每一步切换后我们都会对比网关层的成功率、错误率、响应时间曲线如果数值比 AWS 旧环境差超过 2%就立即回滚到旧环境排查清楚后再切。这里分享一个非常实用的细节迁移切换当天建议安排两组人一组人专门盯着“切换动作”另一组人专门盯着“业务指标”。搞 DevOps 的同学很容易犯一个错误——自己一边改流量权重一边看监控大屏结果流量切到一半自己人也懵了分不清是切换动作导致了抖动还是业务本身就出现了问题。职责分离之后整个过程会清晰很多。4. 迁移后的日常运维从“救火”变成了“写工具”公有云和自建 K8s 并不是坏方案但对当时的我们来说它已经变成了一个每天要花大量精力去维护的“成本中心”。我们团队当时有两个人几乎每个星期都要折腾集群相关的事证书过期、节点 NotReady、镜像仓库满了、某台 EC2 偶发网络抖动。这些事不致命但非常消耗注意力。迁移到新平台之后最直观的感受就是——这些“每日杂事”消失了。4.1 多集群管理从“跳板机大战”变成统一控制台以前我们手上一共有 10 多套 K8s 集群测试环境、预发环境、生产环境各自独立每个环境都有一台跳板机。新人入职光是要记住“哪套集群用哪个 kubeconfig、哪个 namespace 是大促核心”就得花一周。现在通过 Sealos 统一管理所有集群在一个控制面上展示资源使用率、运行状态、异常事件都一目了然。权限也收得更紧了普通开发只需要申请对应 namespace 的权限不再需要整个集群的 kubeconfig。4.2 自动扩容和弹性伸缩终于敢放开用了以前在 AWS 自建集群上我们不敢轻易开 Cluster Autoscaler因为多套集群各自维护配置不一致扩容出来的节点经常因为初始化脚本没跑完无法加入集群。迁移之后节点池的扩容变成平台能力我们可以在业务高峰期自动加机器低谷期自动释放不需要人工干预。第一次完整跑过大促后我算了一下大促期间临时扩的 20 台机器忙完两天就回收了而往年这 20 台机器是按月预留的。这也是“计算成本”那一栏能省出 34 万的隐形原因。4.3 应用发布从“半夜求运维”变成自助操作平台化带来的另一个红利是开发体验变好了。过去开发要发一次版本先提工单运维给改 Ingress再等容器滚动更新。现在开发组自己维护应用的部署配置通过平台的发布接口一键滚动更新遇到异常可以一键回滚。开发觉得可控了运维也轻松了。我觉得这才是省钱故事背后最值得讲的部分你省下的不只是账单而是整个团队的焦虑感。5. 这套方案不是万能模板先判断你的场景适不适合说到这里一定要给读者泼一盆冷水。并不是所有公司都适合把 AWS 上的自建 K8s 迁到自维护的 Sealos 平台上。如果你看完前面的内容觉得“我们要不也迁了吧”先对照一下你们的状态。5.1 适合照着做的三种情况第一你们已经有超过两套生产 K8s 集群且每套的规模都不大但为了高可用各留了一堆冗余节点。这种情况是最适合整合的因为统一资源池可以抵消峰值。第二你们有专人在维护 K8s但这些人 60% 的精力都在处理控制面问题而非业务问题。这种情况下换到管理面更成熟的平台人力会立刻释放出来。第三你们的业务流量有明显的峰谷差异比如白天高并发、夜间有空闲统一调度能把这些错峰利用起来资源利用率提升立竿见影。5.2 不适合照搬的两种典型场景一种是小团队没有一个熟悉 Linux、容器、网络的运维最好还是老老实实购买成熟的托管云服务别自己折腾。另一种是业务有很强的出海或者全球多区域覆盖诉求对“就近接入”“区域容灾”要求极高这种情况用大厂成熟的全球网络反而划算强行自建平台只会在网络基建上花更多钱。我经常举一个例子如果你开一家便利店货架和收银台不需要你自己造买现成的效率最高。但如果你已经开了五十家连锁店每家店都单独配了一个仓库和一个库管那么统一规划一个中央仓库才是更合理的事。迁移到统一平台就是这个道理。5.3 留好退路切换后第六周我们做了一次完整灾备演练迁移完成不意味着结束。我们选择在新平台稳定运行六周后做了一次全员参与的灾备演练模拟整个基础设施不可用的情况测试从备份恢复到业务上线需要多长时间。演练暴露出来的问题包括两个基础数据库从备份恢复到可写入状态花了 6 小时未达到业务预期监控告警在某些故障场景下没有自动通知到值班人部分存储的备份策略配置错误三天前就已经停止拖数据了。这些问题只需要再花一到两周就能解决但如果不去演练等到真正的灾难发生时才意识到那就是无法挽回的损失。这个建议送给所有正在规划类似迁移的团队不要只做“搬迁”一定要做“恢复测试”。一个系统不可怕可怕的是你不知道它能不能从灾难里站起来。我也在这里分享一些我们在迁移过程中沉淀下来的检查项都是经历过真实故障之后才写进去的所有有状态组件必须有自动备份并且备份数据每周至少做一次随机恢复验证每个服务都必须能拉出治理画像谁拥有它、它是给谁用的、能不能断、能断多久每个切流窗口都必须有回滚按钮回滚不是口头承诺而是要在迁移演练里真的按一遍监控不只看节点和容器还要看业务指标订单量曲线、登录成功率、支付回调延迟权限最小化不是所有人都需要拿到整集群的 kubeconfig平台化管理之后这件事才有条件做扎实这些检查项看起来像常识但我见过太多团队因为少了一个备份验证在迁移后第一次大故障时翻车。最后再说一个我们自己的感受。过去半年团队不再把精力花在应付 control plane 不健康、证书到期、镜像仓库爆满这些琐事上而是开始有精力做容量预测、做业务稳定性治理、做研发效能提升。省下的 87 万当然是一笔扎实的投入产出比证明但我更看重的是团队终于从“运维工具人”变成了能真正对业务结果负责的人。如果你也有类似的处境希望这篇文章能帮你少走一点弯路。
RELATED READING

延伸阅读

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