K8s 集群一年云账单 203 万,我扒开一看:至少 123 万是白花的。
之前我做了两件事:
用 eBPF 给集群做了一次性能体检,发现了 5 个传统监控看不到的问题;
做了一次安全审计,发现了 23 个高危漏洞。
有人问我:K8s 安全不是云厂商负责吗?答案是:云厂商管底层安全,但你的 Pod 配置、RBAC 权限、镜像安全,这些全是你的责任。那 23 个漏洞,全是我们自己配置不当造成的。
但还有一个维度我一直没看:资源利用率。
我拉了一份过去一年的云账单:203 万。
然后算了一笔账:如果我们的资源利用率达到合理水平,这笔费用应该是 80 万左右。
123 万,白花了。
更离谱的是,这 123 万里,有 80 万是”沉默的浪费”——没人知道,没人管,就这样持续了一年。
我花了一个月时间,把这 123 万砍了下来。技术层面其实不难,真正让我头疼的是人。
一、分析问题
我先拉了一份各环境的费用分布:
第一眼看到这个表,我就觉得不对:预发布环境花了 42 万?测试环境花了 38 万?
这两个环境加起来 80 万,占了总费用的 40%。而它们的使用率呢?
我查了一下,测试环境最近一个月的 QPS 峰值是 127——还是某次压测产生的。日常 QPS 基本为 0。
预发布环境更离谱,我翻了部署记录,上一次有人往预发布环境部署东西,是两个月前。
80 万,养了两个几乎没人用的环境。
我按节点算了每台机器的 CPU 利用率,发现了一个让我震惊的事实:
50 多个节点里,有 18 个 CPU 常年平均利用率不到 15%。
其中最夸张的一个节点:8 核 32G,上面只跑了 1 个 Pod,一个 QPS 为 0 的测试服务。
这台机器一年的费用是 2.3 万。也就是说,我们花了 2.3 万,养了一台几乎空转的服务器,上面跑着一个没人用的服务。
我查了一下这个服务是谁的。工单系统显示,创建人是半年前离职的一个实习生。
这种”僵尸节点”一共有 5 个,加起来一年浪费 11 万。
接下来我分析了每个 Pod 的资源申请和实际使用。
这里要解释一下:K8s 里 Pod 申请资源(requests)的时候,云平台会按照申请量来预留资源,不管你实际用不用。也就是说,你申请了 4G 内存,实际只用了 200M,云平台照样按 4G 收钱。
我拉了一份 Top 20 “申请/实际”差距最大的 Pod:
order-service 申请了 8G 内存,实际只用了 380M。20 倍的差距。
我找 order-service 的开发聊了一下,问他为什么申请 8G。
他说:”当时上线的时候怕 OOM,就多申请了一点。后来也没人管,就一直没改。”
“多申请了一点”——8G 叫”一点”?
后来我发现,这个 8G 是从另一个服务复制过来的 YAML,那个服务确实需要 8G。但 order-service 的流量只有那个服务的十分之一。
全集群类似这样的”资源通胀”,加起来一年浪费大约 30 万。
到这里,我已经找到了大约 120 万的”浪费”。技术上怎么优化我很清楚:缩节点、降 requests、清理僵尸服务、测试环境定时缩容。
但真正难的是让所有人配合。
二、解决过程
我写了一个方案:测试环境非工作时间(晚上 8 点到第二天早上 9 点,周末全天)自动缩容到 2 个节点。
方案评审会上,测试组长第一个跳出来反对:
“万一周末我要回归测试呢?环境起不来怎么办?” “周一早上环境自动扩容,Pod 启动需要时间,耽误我们测试进度谁负责?”
我说可以配一个 webhook,需要的时候手动触发扩容。
他说:”那多麻烦,我现在随时想测就能测。”
僵了半个月。最后是领导出面拍了板:”先试一个月,有问题再调整。”
试了一个月,测试组一共手动触发过 2 次扩容。其他时间,那 13 个节点确实在空转。
省了 20 万,但花了半个月说服人。
我打算用用 VPA(Vertical Pod Autoscaler,垂直自动扩缩容)自动调整 Pod 的资源 requests。
但这里有个风险:VPA 会重启 Pod 来应用新的资源配置。如果生产环境的 Pod 被频繁重启,可能会影响服务。
我先在测试环境跑了一周,确认没问题后,准备在生产环境灰度。
结果被架构师拦住了:
“VPA 重启 Pod 的风险你评估过吗?如果有状态服务被重启怎么办?” “资源降了之后,遇到流量突增,服务会不会挂?”
我说会配 PDB 保护,而且 VPA 有推荐模式(只推荐不应用),可以先观察。
他说:”那你就先用推荐模式跑一个月,拿数据说话。”
又是一个月。
一个月后数据出来了:VPA 建议把 60% 的 Pod 内存 requests 降低 50% 以上。
但架构师又说:”建议归建议,你敢保证降了不出问题吗?”
最后折中方案:先挑 10 个无状态服务手动降 requests,观察两周,没问题再推广。
注:VPA 目前对无状态服务支持较好,有状态服务建议仍使用 HPA + 手工调整 requests,避免重启导致状态丢失。
两周后,其中 2 个服务各出了一次 OOMKill。
领导找我谈话:”你省了 25 万,但引发了 2 次故障,值不值?”
我说值。因为 OOMKill 之后 Pod 自动重启了,影响时间不到 10 秒,而且这两个服务的 requests 之前确实太高了,降了之后依然有足够的余量。
领导说:”你说的我理解,但下次再出故障,这个优化项目就停。”
省了 25 万,但过程像走钢丝。
我写了个脚本,自动识别连续 30 天 QPS 为 0 的服务。一跑,找出来 32 个。
我给每个服务的负责人发了通知:”你的服务已经 30 天没有流量了,确认是否还需要?如果不需要,我们计划在下周五清理。”
结果收到的回复五花八门:
“这个服务下个季度要重构,先留着。”——产品经理 “我不负责这个服务了,你找 XXX。”——开发 A “XXX 已经离职了。”——开发 B “这个服务虽然没流量,但它的数据库里还有数据,不能删。”——开发 C “删了吧,我忘了还有这个服务。”——开发 D
32 个僵尸服务,真正确认可以删的只有 15 个。剩下的要么有人”说不准以后用”,要么找不到负责人。
最后我采取了”温和手段”:先把这 32 个服务全部缩容到 0 副本(不删除,但不再占用计算资源),保留配置。如果 3 个月内没人恢复,再彻底删除。
省了 10 万,但沟通成本比技术实施成本高 3 倍。
这是最有争议的一个优化。
我们全部用的按量付费实例,没有用 Spot(抢占式实例)。Spot 的价格通常是按量的 20-30%,如果 30% 的无状态服务改用 Spot,一年能省 15 万。
但 Spot 有一个致命问题:云平台可以在任何时候回收它。
我之前在上一家公司用过 Spot,有一次被回收导致服务不可用,被领导骂了一顿。所以我对此有心理阴影。
这次我做了更充分的准备:
只在无状态服务上用 Spot
配了 PDB(PodDisruptionBudget,用于限制同时中断的 Pod 数量),确保至少有足够多的 Pod 可用
分布在多个可用区,避免单 AZ 回收影响太大
用 Cluster Autoscaler 自动补充被回收的节点
方案评审的时候,SRE 团队的同事问了一个问题:
“Spot 被回收的时候,Pod 重建需要多长时间?如果重建时间超过 30 秒,对用户的影响怎么评估?”
我说我测试过,大部分情况下 10-15 秒就能恢复。
他说:”大部分?那小部分呢?”
我说小部分可能需要 30-60 秒。
他说:”30-60 秒的服务中断,你能接受吗?”
说实话,我不太能接受。但我们现在的服务可用性目标是 99.9%,理论上每月允许 43 分钟的故障时间。Spot 回收导致的故障,一个月可能也就几次,每次不到 1 分钟,在 SLA 范围内。
最后还是领导拍板:”先在非核心服务上试,核心服务不动。”
上线一个月,Spot 被回收了 3 次,最长的一次 Pod 重建花了 45 秒。没有触发用户投诉。
省了 15 万,但上线前我失眠了两个晚上。
最终结果
从 203 万砍到了 80 万。
三、我学到了什么
技术上怎么省钱,我一天就能列出清单。但让清单落地,花了两个月。
每个优化项背后,都有人在”守护”自己的资源:
开发怕 OOM,不愿意降 requests
测试怕耽误进度,不愿意缩容
产品怕以后要用,不愿意下线服务
SRE 怕故障,不愿意用 Spot
你要做的不是证明”这样能省钱”,而是证明”这样省钱且安全”。
如果我上来就搞 Spot 实例和降 requests,大概率会被叫停。
我的策略是:先做没争议的(清理僵尸节点、开发环境降配、日志存储优化),用这些”白捡”的节省建立信任,再推动有争议的优化。
先赢几场小的,才有资格打大的仗。
我说”测试环境利用率低,应该缩容”,测试组长不信。
我拉了一张图:过去 30 天,测试环境 15 个节点的 CPU 利用率,每天晚上 8 点到第二天早上 9 点,全部低于 5%。
图贴出来,他没话说了。
不要说”我觉得浪费”,要说”这是数据,你自己看”。
资源 requests 优化,我没有直接用 VPA 自动应用,而是先推荐模式观察一个月,再手动挑 10 个服务试点,最后才推广。
Spot 实例,我没有一上来就搞 30%,而是先在 5% 的非核心服务上试,确认没问题再扩大范围。
每一步都留退路,每一步都有回滚方案。
很多人以为成本优化是一个”项目”——做完了就完了。
不是。今天是合理的配置,三个月后可能就不合理了。新的服务上线、流量增长、业务下线——这些都会影响成本结构。
我现在每个月会跑一次成本分析,看看有没有新的浪费。这比一次性砍 100 万更有价值。
四、写在最后
这次经历让我对”运维的价值”有了新的理解。
以前我觉得运维的价值是保证系统稳定。现在我觉得,在保证稳定的前提下,帮公司省钱,同样是运维的价值,甚至可能是更大的价值。
203 万砍到 80 万,省了 123 万。这些钱可以多招两个开发、多买几台服务器、或者直接变成利润。
但我也清楚,省钱是有边界的。你不能为了省 100 万,冒 200 万的风险。每一刀砍下去之前,都要想清楚:省了多少钱,承担了什么风险,风险能不能兜住。
最难的不是技术,是判断和平衡。
更多精彩评论
在这篇文章下方的评论区,网友们对此展开激烈讨论。
有网友调侃:
网友1:如果有 120W 空间,那这次省 60W 就可以了。
网友2:这次省了60W,下次领导就会让你再省30W,领导业绩出来了,生产稳定降低了,也严重影响其他同事的工作效率和习惯了。
也有不同的现实视角:
网友3:你给公司一年省了 100 万 公司一年能多给你 10 万吗? 你节省的费用,是否会影响某些领导的利益呢?所以这种情况如果公司没有明确的激励制度,还是睁一只眼闭一只眼吧。
网友4:公司在扩张时,花钱越少,运维越没价值。 只有公司要倒闭时,才是各种省钱。运维,稳定才是第一,成本第二。
还有网友分享了实际调参经验:
网友5:我都是 request 设的相对来说低一点,limit 设置的高,比如,request 256M,limit 2G。收费一般都是按照 request 来收的,当然平台也会按照用量调高 request,但是相对来说能剩很多费用。
那么,你们的 K8s 集群一年云费用是多少?有没有发现过离谱的浪费?欢迎在评论区聊聊。