写点什么

使用 kubernetes,你真的降本了吗

作者:谦寻
  • 2021 年 12 月 15 日
  • 本文字数:8372 字

    阅读完需:约 27 分钟

我所接触的圈子,现在还没有使用 kubernetes 的企业已经不多了,或多或少大家都在使用容器相关的一些技术。基本都会觉得 kubernetes 一定是能够提效降本的,实际上呢?


曾经我听过一位运维人员的演讲,大概就是讲了 kubernetes 如何如何高效、如何给公司带来很大的降本。最后我认真的听完,问了一句:没有容器化之前,你的应用每个节点分配的资源是 2C/4G,容器化之后我看你每个 pod 的配置还是 2C/4G,你觉得降本在哪里?你的资源使用率提升了多少?然后他有点不知所措,云里雾里的说了很多,但都不在点子上。从那之后,我看很多时候,很多同学都是在自嗨,为了使用新技术,而去玩 kubernetes、玩云原生。并没有真正的用容器化技术给企业、给业务带来真正的价值。


如果没有合理的使用,可能上了 k8s 之后成本反而会增加,为什么这么说呢。首先 k8s 本身就是有成本的,且不论学习成本、人力成本,之前的架构可能都要推翻重来。其次,k8s 各个组件本身就要占用不少的资源,比如 master 节点、还要做高可用,各个控制组件等。所以如果我们没有充足的准备,合理的规划,成本只会增加。

回顾 kubernetes 价值

从运维的角度来看

  • 屏蔽底层基础设施、屏蔽底层异构环境:对于上层的应用是无感知的,无论调度到哪台服务器,都能够稳定、正常的运行。这样的标准,让服务、甚至平台之间迁移更简单。

  • 管理方便、高效:如果你问一位运维人员是管理 10000 台服务器简单,还是管理 10000 个 docker 简单,我相信用过 k8s 的同学都会选择后者。之前我们的 ecs 服务器数量虽然没有上万,但是也直逼 2000 台,如果不是随着容器化的落地,早已远远超过这个数字了。针对这么庞大的公有云资源,现在仅仅一位运维花费少量的时间就行。

从业务角度来看

  • 弹性:很多企业上 k8s 更多应该就是冲着容器技术弹性来的,以前的分钟级、十分钟级的扩缩容,现在变成了秒级。这样我们就基于这种弹性做一些动态扩缩容,并且稳定性也更高。

  • 降本:这个也是我们今天的主题,后面会详细讲解。

  • 研发效能:迭代效率更快、更稳,基于云原生的 DevSecOps 方案越来越标准、越成熟,整个生态提供了比较完善的解决方案

从技术趋势角度来看

  • 这个更多的是指云原生技术带来的价值,以 kubernetes 为基础设施坚实的底座带来的一系列技术价值,包括最近比较火的 service mesh、serverless、边缘计算领域、flink on k8s,更多的部署应用在 kubernetes 上的,让这些技术的落地更简单

  • 有时候我们做技术、做架构需要往前看,不然随着时间的推移、业务的增长,可能会带来很多技术债,那个时候想要重构、改变就能很难,成本会很高。以 kubernetes 为首的容器技术是基础设施标准,围绕着 kubernetes 的生态也慢慢健全起来,各大云厂商也在基于 kubernetes 的赛道在云计算领域做赛跑。各技术厂商提供的 api 也会围着这个生态,按照统一的标准,你不跟上,可能会步步跟不上,迭代的效率也会落下一大步。

  • 技术文化沉淀,我相信每一位做技术的人员都希望能够接触到前沿技术领域,尤其是热门技术。一个有技术氛围的团队,更容易吸引人才,因为大家都渴望能够和企业共同成长,这也是为什么一些大厂会去做一些前沿技术的交流峰会、沙龙等。

降本,我们从哪里开始

上面谈了一些 kubernetes 的价值,当然它的价值不仅仅是这些,每位同学的理解也都不一样。但是降本这个事情是大家提的最多的,也是最认可的。无论最终的结果如何,它真的给大部分企业带来了效率提升和成本下降,这点我是比较坚信的,不然以 kubernetes 为代表的云原生技术也不会在短短几年火热到这种程度,几乎无所不在。它在一定程度上着实解决了困扰运维和开发的一些问题,之前效率和成本在某种程度上是一个矛盾体,运维为了业务上线快,可能会多准备一些计算资源,那势必就会带来成本上的浪费,或者说,为了避免业务受损,按照最大的量去准备资源。无论怎么样,业务想要服务上线快、稳定运行,运维想要控制成本,最小化使用资源,这就是一直不能化解的矛盾。

我们的成果

可以先给大家说说我们降本的成果,让大家有看下去的动力,从我开始负责降本这个项目开始,到目前为止全年降本在千万元以上,具体数据就不说了,重要的是希望通过这些分享能让大家能够感受到原生技术带来的价值,以及在未来提效降本的路上,哪怕是有一点点帮助也是值得的。


从我们开始全面容器化开始,我就给团队提了一个要求,我们最终呈现给业务的终态必须是达到了提效降本的结果,并且这个结果是一个长期的价值。如果做不到,那就没有必要去耗费这么大的人力物力去改造基础设施。

从云计算说起

你可能会好奇,不是聊降本吗,怎么突然说起云计算了。我觉得这个是绕不开的话题,随着云计算的发展,大多数的基础设施都是运行在云上。你降的是谁的本,说白了就是云资源的本、基础设施的本。如果你说,你们是自己的 idc,服务器都是买好的,节省下来的资源短期内其它业务也用不上,空着也是浪费,那这种情况怎么办,这也是传统 idc 的通病,针对企业来说,不具备弹性的能力,买了就是买了。如果短期业务不会有增长,省出来的资源也没地方用,那确实也没有什么降的必要性。如果业务会持续增长,那也可以压缩资源给增长的业务用。你看往前退 5 年,降本这个词其实大家提的没有像现在这么多,起码没有成体系的讨论,倒不是说大家不在意成本,起码不像现在这么大范围的讨论,甚至作为一个课题去研究,什么在离线混部啊、高低峰弹性啊,都是为了优化成本。


“上云”这个词大家这些年听的比较多,包括云原生也是为了让应用天然运行在云上,发挥云最大的优势。这个云可以是公有云、混合云、私有云,今天我们更多的去聊公有云,毕竟大部分的企业都是在公有云上,只有少数头部企业才会有实力去做自己的云。另外最近很多企业也慢慢开始把部分业务迁移到公有云,其中一个重要的原因也是为了成本,比如针对电商企业,双 11 这天可能要准备比之前数十倍的服务器,如果还像之前那样租 idc,然后买服务器,那双 11 之后呢,服务器就会出现大量的空跑。这个时候公有云的价值就体现了,可以用的时候随时买,用完也能随时退掉,按照使用的时间去支付费用,这个成本就会降低很多。


未来的云计算会像使用水电一样方便,电的优点是什么,第一,便宜,价格足够的低,大家都用得起,已经不像以前那样,买个灯泡还要考虑多少瓦能纠结半天。第二,方便,随地可取、随时接入。

第三,按量付费,使用多少付多少钱。我坚信云计算会有这么一天,原因有很多,这里我说其中我认为比较重要的一点:规模效应,之前你购买的资源你不用就没人用,会造成空置,而公有云不会,这个企业不用就会有另外一家企业用,成本由大家分摊。并且随着用户数量的增多,这个成本就会越来越低,接着成本越来越低,然后用户愿意使用的数量越来越多,形成了如下面的增强回路。


现在公有云的函数计算、serverless 技术就比较接近按量付费,比如根据函数调用次数收费。当然,现在我们使用公有云基本还是包年包月的形式,比如 ecs,我们还是购买固定的资源,以包月使用,资源使用率比较低,成本上也有很大的压缩空间,这个是我们迫切要解决的事情,也是我们今天要讨论的主题。

降本如何做

说了这么多,接下来我想以公司的实践来聊聊我们是如何做的。会从以下几个方面着手:

  1. 提升资源使用率,这个很容易理解,无论是 CPU、内存还是磁盘只要使用率提升,一定会带来成本的降低

  2. 按量付费,使用 kubernetes 和公有云的弹性能力,做到部分资源使用多少就付费多少,可以大幅度降低成本

  3. 评估合理性,有些资源我们并不能靠使用率来评估其是否存在浪费,比如我们之前的日志服务,其成本已经占到了公有云成本的 10%以上,公有云是按照索引和数据量来收费的,并不是看其 CPU、内存使用率来衡量的。针对这种服务,我们就要有一个标尺,超过这个标尺,就可以初步判定是存在浪费的,使用上有它的不合理性。

  4. 平台化落地,我们不能把降本看成一次性的工作,过一段时间去审视一次,然后做一次。应该把成本治理作为日常运维的一部分,实时关注、实时治理。这个时候我们就需要平台化落地,帮助运维去驱动这个事情,甚至通过自动化的手段帮忙去完成这个事情。

接下来,我就带着大家一一拆解

提升资源使用率

早期我们业务 ecs 的平均 CPU 使用率大概在 5%左右,后面经过大幅度调整,提升到了 20%以上,这个说的是业务的 k8s 集群,非大数据领域的,是不是达到这个值就算好了,当然不是,一些头部企业使用混部可能会达到更高。如果是大数据集群,要达到 70%以上才算合理。大家可以看下自己所在的业务,CPU 平均使用率有没有稳定的超过这个值,如果没有那就有很大的改善空间。

弹性

既然要提升资源使用率、压缩服务的资源,那我们就首先要做的就是让业务具备弹性能力来应对突发流量。我们这边也经常会有流量高峰,可能瞬间就会把 CPU 用到很高的值,如果平时 CPU 使用率就很高,到时候会完全扛不住流量高峰,然后造成服务抖动影响到业务。 


我们基于原生 HPA+开源 KEDA 工具开发了弹性扩缩容的平台,能够让业务的应用根据自己的情况进行策略配置、调整,目前已经实现的弹性扩缩容功能有:

  • 内存:根据内存使用率

  • CPU:根据 CPU 使用率

  • 流控:服务发生熔断、限流触发

  • 定时:指定服务某个时间点触发

  • 自定义指标:对接第三方平台,比如 prometheus

  • 业务指标:可以根据业务暴露的指标触发


如果只是做到应用的弹性那是远远不够的,容器化了之后,我们关注的资源使用率不仅仅是容器的,还要关注宿主机的。不是说容器的资源使用率高了,就代表 ecs 资源使用率也高了。我们还需要做 ecs 的弹性,这点公有云提供的 eci 技术已经帮我们完成了,我们需要对接相应的接口就行。


这一块,应该有不少公司为了能够让业务弹性会多预留一些资源,比如多增加 10%的 worker 节点,让业务流量突增的时候,或者需要扩容的时候能够及时触发。这样其实就无形的增加了成本。我们利用公有云的 eci 技术优势,做到服务器资源不够的时候能够在几十秒的时间里扩容大量资源,并且当我们需要缩容的时候,优先回收 eci 的资源,这些资源都是按照使用时间收费,可以大大缩短使用成本。

调度

了解 k8s scheduler 的都知道,它的调度是基于资源的 request 值来决定的(其它因素不在我们今天讨论范围),也就是说看看哪个 worker 节点的总资源减去已经 request 的资源最多,就往空余最多资源的节点上调度,理论上这个是合情合理的。但是这个空余并不能真正的代表空余,它并不能感知到实际服务器资源使用情况,可能这里大家看着有点绕,我举个我们实际场景的例子。


之前我们应用每个节点给的 CPU 配置都是 4C,也就是 pod 的 request 值和 limit 值都是 4,而大部分应用 CPU 平均使用率都很低,第一阶段降本我们就直接把所有的 pod 配置 CPU 直接减少 50%。我们把 request 值降为 2,limit 值保持不变仍然是 4。举个例子,一台 16C32G 的服务器,之前只能部署 4 个 4C8G 的 pod,那么现在我们只需要一台 8C32G 服务器,就可以部署 4 个 pod,这样 CPU 的成本就降低了一倍。


你肯定会想这样之前某些应用可能需要的不止 2C 怎么办,这个也是我们把 limit 保持不变的原因。针对这种情况,我们也是做了一系列的保障,不然这种调整会带来一系列的风险。并且 k8s 针对 request 和 limit 的值是否相等,调度优先级也不一样,搞不好的话,在资源紧张的情况下有可能导致服务被驱逐,这里我就不专门讲解了,感兴趣的同学可以自行去查资料,我就简单说几个需要重点做的事情。

  1. 调度、调度、调度,既然这节是说调度,那肯定要重点去做,我们允许有些服务 CPU 使用超过 2C,那肯定就有些服务会使用会少于 2C,为了稳定,并且少于 2C 的服务应用占比要多。一、k8s 原生的能力,比如服务的反亲和配置上,尽量同一个应用的多个 pod 不要调度到同一台 ecs 上,二、应用分级、我们把应用按照核心、重要、一般分为三类,优先保证核心应用的资源,这个通过 CMDB 管理,应用的 owner 可以自行调整,最后结合自定义调度使用,三、自定义调度,开发属于我们业务场景的调度器,一开始我就提到 k8s 原生的 scheduler 问题,它无法感知到 ecs 实际资源使用的情况,也无法知道我们哪些应用是核心,哪些是非核心,那就更不用想它能够根据实际业务情况给出合理的调度了。曾经我发现原生的调度导致我们有些 ecs CPU 使用率很高,有些 ecs CPU 使用率很低,可能会有百分十几到二十多的差距,可能有些高流量的应用被调度到同一台 ecs 了。这个时候,我们就可以使用 Scheduling Framework 来开发我们特有的调度器了。

  2. 保障资源充足,这个可不是说你要预留很多 worker 节点的资源,前面提到,我们可以使用 ECI 技术进行接入,在资源不足的情况下自行扩容。当然这里面要加入资源监控,严格控制,也不能一味的扩容,如果是某个应用本身程序死循环导致 CPU 暴增,这种情况扩容也解决不了问题。

  3. 如果你的策略是整体都是 request 值和 limit 值不相等,建议就尽量所有应用都一样,这样起码不会产生有些应用优先级比较高,在资源紧张的情况下驱逐了其它服务。这个视各自业务情况而定。

通知

既然我们想长期治理,那通知机制就很有必要。举个场景,某个服务可能最近使用率比较高,但是未来可能有很长一段时间使用率都比较低,这个时候我们就需要能够及时发现、及时治理,我们可以设置当某个服务如果在连续两周 CPU 使用率都低于 10%以下,就发个通知信息到应用的 owner 和运维人员,考虑是否可以降配。


为了减轻运维人员负担,我们还使用 k8s 的 crd 相关技术开发了 ops-controller,当我们调整了 pod 的 limit 值,会自动调整环境变量里面的 jvm 参数,无需运维手动修改。然后我们还可以结合 k8s 的 vpa 技术,当应用自动纵向扩容的时候,可以全自动化。



按量付费

未来的计算资源会像水电一样按量付费,我们现在离这个目标还有一段的距离,虽然不能所有的产品都做到这样,但是在有些场景下还是可以实现的。比如大数据、算法,可能只是每天固定的时间段需要大量的计算资源,还有就是活动类场景,可能只是某几天或者某几个小时使用。这些使用按量的付费方式就能节约很多成本,目前基本各大公有云也都支持这种模式。


上面已经讲了一些按量付费的方式方法,这里单独去讲是因为我觉得这个是我们未来很长一段时间技术演进的方向,也是我们接下来想实现的一个目标。节约成本这个事情在我看来不难,难的是如何在节约资源、降低成本的同时,还能保障服务的高可用、业务的连续性。


每个企业业务场景不一样,使用的方式也不一样,这里我只列一些常见场景的解决方法大家可以参考,不作为最终的解决方案。

  • 定时扩缩容,对于业务高峰、低峰时间比较固定的业务,高峰的时间每天不会超过一半时间,可以试着采用这种方式,使用按量付费的方式购买 ecs、高峰的时候提前扩容

  • 大数据、算法业务,这种基本上压缩空间很大,如果 CPU 或者 GPU 平均使用率不在 70%以上,可以想想是不是哪里没有合理的利用。现在公有云 VGPU、CGPU 技术也做的不错,可以更大化的去利用 GPU 资源,毕竟 GPU 还是很贵的。

  • serverless,比如函数计算这块就是典型的按量付费,我们的前端渲染使用的就是函数计算、不但能够节约研发人员的时间,还能降低计算成本

  • 公有云 ECI,尽量减少、压缩长期固定的资源,针对业务短暂高峰、紧急扩容可以使用 ECI 资源,按照使用量计费


这里只是简单举几个例子,当然还有很多,篇幅原因具体实施方案可以后续做专门的技术探讨。

评估合理性

看到这里,前面我讲到主要针对服务器资源的压缩,具体用的合理性怎么样,看下资源使用率就行。还有些资源靠这些指标是无法判断的,比如日志服务,如果你是自己搭建 elk 系统,服务器的资源你可以用 CPU 或者磁盘使用率去判断,但是日志量呢,业务可能什么日志都打,最终的是结果是日志量一直涨,运维拼命的扩容服务器、优化 es 性能,曾经我们就是这种状态。另外还有存储天数的问题,有些应用日志存储的时间短、有些应用日志存储的时间长,以前的方式基本都是一刀切,因为很多应用的日志可能放到一个索引的里面,只能针对这个索引去设置保留时长,这些都是问题,你如何解决?后面因为我们日志规模比较大,我们使用了公有云的 sls,按照索引的量和日志的量收费,也需要解决上面的问题。因为这些是有业务决定的,由你自己的使用方式决定,无关你使用什么平台。


那如何评估其合理性呢,这个我觉得没有一个统一的答案,比如日志服务、如果业内整个日志服务占了基础设施成本都在 5%以下,那我们是不是可以设置第一个阶段降本达到 5%这个水位线,当时我们的日志成本占了 10%以上,于是我们设置了这个目标,最终日志服务成本降低了 50%,完成了目标。


是不是什么产品都要去评估呢,我个人觉得没有必要,现在稍微有点规模的企业,产品形态都很多,比如使用公有云,可能你使用的产品都有大几十、甚至上百种。我的做法是二八原则,优先治理花费了那 80%的费用,分了四大类:服务器、大数据、日志、数据库,针对每一种资源都想清楚我们的标尺,什么情况下资源存在浪费。


这里还拿日志服务举例,我们设定了两个目标:

  1. 日志服务占比公有云基础设施成本降到 5%以下

  2. 日志服务整体成本降低到 50%以下

目标清晰了之后,接下来就由我们团队全面改造、推广:

第一、由业务来决定每个应用的日志存多少天,会有个上限,信息存在 CMDB 中,第一次需要我们手动收集然后倒入,后面新应用上线可以在系统上由 owner 填写,自动设置公有云 sls 保留时间。

第二、每个应用一个索引,这个得益于公有云云 sls 的优势,es 在索引比较多的情况下,性能会下降很多。公有云目前我们使用不用顾虑这个问题,这样我们就可以针对每个应用去做不同的策略。

第三、统一日志格式,减少不必要字段的索引。

第四、平台化,这个我们下面会专门去讲。

整个项目我们用了不到一个月的时间,就完成了目标,并且改造过程完全不影响业务人员使用,没有造成任何服务中断,总体是比较成功的。

平台化落地

会不会很好奇,降本也要做平台化?我一直给团队说,希望大家把降本做成一种可持续的能力输出,不是说今天大规模治理一把,过一段时间再来一次。我们要把降本这个事情融入到整个基础设施管理的生命周期,早发现早治理早省钱。


在云原生的技术体系里,以“应用”为中心也是我们设计平台架构的指导思想,我们这边开发了一套 PaaS 平台,包括了发布、变更、CMDB、中间件管理、容器中心、成本治理等各种功能。今天我主要讲讲我们是如何做成本治理的。



我们对每个应用都定义了各种属性信息,包括应用的 owner、所属的团队、日志保留时长、应用的等级(是否核心),还有一些其它属性,这里不列举了。从应用出发我们能知道跟这个应用所关联的服务器、k8s、日志、数据库等信息,能知道使用了多少 CPU、内存,自然就能计算出所产生的各种产品费用。这样我们就能了解到每个应用产生的各种费用,又能根据应用所属的团队计算出整个团队的费用。这里举个例子如何判断某个应用使用了多少服务器资源,我们的监控系统有实时的 k8s 和服务器所有节点的数据,平台去调监控系统的接口获取数据,然后求和就能算出每个应用的所有节点的 CPU、内存数量,最终去分摊费用。


我们平台还对接了各个公有云平台的接口,能够详细分析各个云商成本,这样就能知道每天、每周、每月费用使用情况,是否有使用异常情况。


针对每个类型,都按照团队做了精细化的图表分析,比如日志有索引、存储按照团队划分,每日、每月的同比、环比分析等等。这样业务管理人员就能够清晰的知道他的团队各个产品产生的实时费用情况,如果用多了就会考虑是否需要治理。


最后那就是可观测性平台的建设了,这个是非常重要的,作为最后的兜底。成本治理归根揭底最终是压缩了资源,如果出现资源紧张导致的故障我们需要第一时间知道。在我们一开始的时候,由于资源的压缩,也出现了一些故障,比如 CPU 瞬时打满、网络抖动等等。而这些问题在之前的监控体系下是很难发现的,指标的采集基本都是分钟级的,对于一些秒级的抖动不一定能告警出来。我们的监控目前做了几个比较重要的事情,1,有些指标尽量做到秒级,比如网络的检测,做不到的也尽量做到 15s,2,整合,尽量做到端到端,之前监控系统都好几套,前端、后端、基础设施等,现在我们把 metrics、log、trace 都建设在一个平台上,把数据打通更好的去发现问题。3,建设 SRE 体系,从告警到事件到自动生成故障报告,复盘之后的 to do list 也会有跟进,没有做完就会发通知提醒。当然这里面有很多技术挑战,就不在这里面讨论了,后面可以做专题讲解。

结束

成本治理这个事情不是说做到上面就够了,道阻且长,我们一直在路上,还有很多做的不足的地方。2020 年 8 月,Linux 基金会宣布成立 FinOps 基金,致力于通过最佳实践、培训、制定标准来提升企业中云财务管理从业人员的能力。FinOps 是“云财务管理”的简写,它的核心是确保企业在云中花费的每一分钱都获得最大价值。


前几天,也就是 11 月 24 日,腾讯云正式宣布加入 FinOps 基金会,作为国内首家 FinOps 基金会顶级会员,腾讯云将联合 FinOps 基金会,全面推进对 FinOps 标准和最佳实践的贡献,为企业提供云财务管理的最佳解决方案。这也说明了现在大家开始注重云环境的成本治理,慢慢成为企业关注的焦点话题。


最后感谢大家的阅读,如果大家对这个感兴趣或者有好的想法,也欢迎找我探讨。


用户头像

谦寻

关注

could native 2017.12.17 加入

云原生、DevSecOps、SRE方面的爱好者、从业者

评论

发布
暂无评论
使用kubernetes,你真的降本了吗