弹性伸缩又称自动伸缩,是云计算场景下一种常见的方法,弹性伸缩可以根据服务器上的负载、按一定的规则、进行弹性的扩缩容服务器。
弹性伸缩在不同场景下的含义:
引用自:https://zh.wikipedia.org/wiki/%E5%BC%B9%E6%80%A7%E4%BC%B8%E7%BC%A9
弹性伸缩,顾名思义某种机制能够让某些对象进行弹性的扩容和缩容。在云计算和容器相关领域也有较多的关于弹性伸缩的能力,有基于系统负载进行弹性扩缩容的,有基于业务日志进行弹性扩缩容的,也有基于资源预申请进行弹性扩缩容的。最常用的主要有以下记录:
使用场景:当您的应用程序承担更多负载时,往往需要更多的 CPU 和内存资源,这时您可以设置一个 CPU 和内存利用率的指标,系统会自动设置副本数以动态承担不同的负载情况,防止资源利用率过低的资源浪费或负载过高时应用程序无法承担。
限制:有时应用的负载变高但 CPU 和内存的利用率并没有很高,这时基于系统负载指标扩缩容是无效的。并且具体使用哪一种系统负载指标,以及利用率的阈值设定都是比较需要经验的。
使用场景:业务的日志有专门记录和存储,并且可以通过日志分析得到当前应用的实际负载情况,这时可以根据业务的日志自动扩缩容。
限制:需要拥有日志存储和分析工具;日志信息量普遍很大,基于日志的弹性扩缩容易误判、漏判。
使用场景:当有些应用不适合水平扩缩容时,此时可以通过调整对资源的请求量来实现扩缩容。相较方式1是扩容副本数实现水平扩缩容,此时扩容的是容器对资源的请求量,属于垂直扩缩容。
限制:当前这种方式需要重建容器,可能会引发服务的中断;并且垂直扩容依赖当前容器运行的节点容量大小,如果节点本身没有剩余资源,也无法实现垂直扩容。
使用场景:例如当您的业务需要处理 Kafka 消息队列中的任务时,Kafka 中每多一条 topic,需要生成一个新的副本来处理这个 topic;或者数据库每多一条任务数据,会自动生成一个新的副本来承载这个任务。
限制:完全依赖事件的触发,但事件本身处理时长有长有段,负载程度有高有低,完全相同的副本无法灵活应对。
当然还可以用其他的特征和属性进行扩缩容对象,这里也未全部枚举,具体业务使用弹性伸缩,按需选择不同的特征和属性,特征和属性则是弹性伸缩的基础。
基于上述的特征和属性获得了数据之后,那么就需要一定的策略和判断规则。 总结来说就是:
举个 kubernetes Cluster AutoScaler 的例子:
在腾讯云容器服务里节点的缩容策略:
CA(Cluster Autoscaler)监测到利用率(取 CPU 利用率和 MEM 利用率的最大值)低于设定的节点。计算利用率时,可以设置 Daemonset 类型不计入 Pod 占用资源。
CA 判断集群的状态是否可以触发缩容,需要满足如下要求:
节点空闲时长要求(默认10分钟)。
集群扩容缓冲时间要求(默认10分钟)。
CA 判断该节点是否符合缩容条件。您可以按需设置以下不缩容条件(满足条件的节点不会被 CA 缩容):
含有本地存储的节点。
含有 Kube-system namespace 下非 DaemonSet 管理的 Pod 的节点。说明:
CA 驱逐节点上的 Pod 后释放/关机节点(不会处理包年包月节点)。
上述就是 Kubernetes 对节点缩容的处理逻辑,也就是弹性伸缩三大关键要素的扩缩容策略部分。总结来说,策略是决定弹性伸缩相关的能力是否足够匹配业务场景的最关键的部分。
弹性伸缩在云服务商上的服务对象往往就是服务器的数量,还有更多弹性伸缩的对象如:云服务器的资源配置(CPU/内存)、还可以是承载用户业务的 Kubernetes 里的 Pod、还可以是其他企业所需要使用的云产品,业务只要有按需使用云资源的诉求,随用随取的资源皆可成为弹性伸缩的对象。 云上弹性伸缩的本质和目的:就是对弹性伸缩对象的按需付费。
腾讯云云原生团队后续计划推出云原生白皮书, 其中将会介绍来着 1000+ 企业在成本方面的经验总结, 整体分成了三个部分:理解成本->控制成本->优化成本。利用云的弹性伸缩是企业优化成本的三大方法之一。
通过《降本增效|容器化计算资源利用率现象剖析》中的调研分析,充分利用弹性伸缩能力,是提高资源利用率,降低资源成本的关键点之一,对比未使用弹性伸缩的情况下整体资源利用率能够提高20%、30%以上。
腾讯云原生团队提出了容器化资源利用率成熟度模型中的 level2 就是业务利用容器和云的弹性伸缩能力,结合 Kubernetes 的 HPA、VPA、CA 等能力,高峰扩容、空闲缩容,极大提高资源利用率。
未使用弹性伸缩的情况下,运维人员可能会碰到以下场景:
● 业务突增或 CC 攻击导致机器数量不足,以致您的服务无响应
● 按高峰访问量预估资源,而平时访问量很少达到高峰,造成投入资源浪费
● 人工守护及频繁处理容量告警,需要多次手动变更
采用弹性伸缩,配置自动化后,既可以释放人员对资源的手动变更的投入成本, 还可以让业务的稳定性进一步提高。
引用自:https://cloud.tencent.com/document/product/377/3154
灵敏度可以用从触发扩缩容到实际将对象扩缩容完成的时间来衡量,时间越短、灵敏度越高。
灵敏度的提升对业务来说不仅仅是影响时间差的 IT 资源成本,还可能对业务某些场景起到关键性的作用。
灵敏度可以从 HPA 扩容速度、CluterAutoscler 扩容速度、业务扩容方式多维度进行提升。
灵敏度是腾讯云容器系列产品弹性伸缩功能的关键考核指标,从基础层重点考量弹性伸缩的速度,以节点扩展效率为例,TKE 通过节点池扩节点的时间实际测试数据如下:
测试方案:
创建一个 TKE 集群,分别扩展50、100、200节点
记录批量扩展从启动到完成初始化的时间
释放新创建的节点
重复测试5次,记录每一次批量扩展时间
批量添加50节点:
- | 第1次 | 第2次 | 第3次 | 第4次 | 第5次 |
---|---|---|---|---|---|
耗时 | 3分 16秒 | 3分 33秒 | 3分 59秒 | 4分 5秒3 | 3分 13秒 |
批量添加100节点批量添加200节点:
- | 第1次 | 第2次 | 第3次 | 第4次 | 第5次 |
---|---|---|---|---|---|
耗时 | 4分 55秒 | 5分 07秒 | 5分 02秒 | 5分 11秒 | 5分 10秒 |
当然从业务实际需要触发扩缩容到业务负载 Ready,在 Kubernetes 服务层面不仅仅是节点的扩容一个部分,还涉及 Pod 的 HPA、监控或日志指标的采集分析效率等,腾讯云容器服务系列产品也将持续围绕提高弹性伸缩灵敏度建设弹性伸缩产品能力。
精确度在弹性伸缩领域主要意味着:在准确的时间进行扩缩容、扩缩数量准确、扩缩的对象属性精确(如云服务器的机型),精确度越高同样意味着越贴合业务,扩容不会扩得过大而导致成本的浪费,也不会扩的过小导致没有解决业务问题,同样缩容不缩的过多导致业务故障、不会缩的过下而造成资源浪费。
精确度跟扩缩容的策略和算法息息相关。
在 Kubenretes 服务上的精确度同灵敏度一样,也分散在各个弹性扩缩容的组件上,以 HPA 来举例,精确度主要的还是其默认的扩缩容算法作代表,详情可参阅 Kubernetes 官网:
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
默认的 HPA 扩容策略,能够满足绝大数场景,但业务的场景更多,因此也出现了匹配业务熟悉具备更高精确度的对 Pod 进行扩缩容的组件如:
● 业务属性跟时间相关,通过 CronHPA (腾讯容器服务为 HPC 功能) 来控制更精确的扩缩容时间。
● 基于事件的自动扩缩容 KEDA ,通过替换指标的数据源来匹配业务的诉求如离线计算的场景。
● ......
相信社区后续在 Pod 级别的扩缩容上也还会出现越来越丰富的组件,以适配业务的多样的场景来提高弹性伸缩的精确度。
自动化的程度如果要通过一个可衡量的数值来参考,可以考虑选择运维或开发在IT资源管理上投入的时间,时间越少,自动化程度越高, 投入的时间越少,也意外着投入的人力成本越低。这里的时间还可以继续拆分到投入扩缩容 IT 资源的时间和对 IT 资源资源维护的时间如故障替换等。
想要提高弹性伸缩的自动化程度,理解弹性的基本工作原理是最基础的要求。下文也会详细展开 Kubenetes 服务下的几个基本的弹性伸缩组件的工作原理。
在理解弹性伸缩工作原理的基础上,企业往往会结合自身的运维平台,将弹性伸缩集成进去,成为运维系统的一部分,以结合业务的诉求。因此自动化也要求云服务商对弹性伸缩的可配置性、API 的易用性也有较高的要求,如若各位读者有使用腾讯云容器服务相关的弹性伸缩 API,欢迎各位给产品提供优质的建议。
之所以将弹性伸缩的可观测性单独作为一个影响运维成本的关键点,是因为当前 Kubernetes 的弹性伸缩的自动化还不能达到完全脱离运维人员的状态,良好的可观测性能让负责 IT 管理的人员减少心智负担,让业务的运行更加透明。同时也让自动化无法处理的工作能够有更快人员介入处理。
可观测性包含对弹性伸缩对象的盘点和管理、弹性伸缩对象基本的系统指标、运行状态的监控、以及故障告警等等。
云厂商的产品包括腾讯云容器系列的产品都会提供一些基本的可观测性的产品能力,也可以采用社区的 Grafana 等仪表盘工具构建企业自己的可观测性平台。
业务的扩容相对来讲是一件低风险的事情,最大的影响是支出可能会增多,但对业务本身来说是一件安全的事情。但是弹性伸缩不仅有扩容,也有缩容。业务被缩容之后,针对下次的突发流量是否能快速扩容?特别是如果剩余资源被别的业务抢占,或云上的资源售罄的情况下,临时再扩容是一件风险比较大的事情。
业务的应用之间存在依赖关系时,一个应用扩缩容后,另一个应用是否也该扩缩容?是否会有连锁反应?这些都是可能导致系统故障的风险点。
上面提到的弹性伸缩基于的特征和属性、策略、对象都有很多种,任何一种方式都可以弹性伸缩,到底哪一个才是最好最适合的扩容方式?往往需要非常强的技术积累和经验,很难自动化。
使用弹性不当,导致账单爆涨的案例比比皆是。要理解弹性伸缩工作的原理、才能更准确的使用弹性伸缩,降低业务成本,提高业务稳定性。建议使用 Kubernetes 弹性伸缩能力之前先详细阅读 Kubernetes 弹性伸缩相关官方文档或 Git 文档。
· ClusterAutoScaler: https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler
· HPA: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
· VPA:https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler
弹性伸缩需要监控到“变化”(这个变化指的是上面提到的弹性伸缩的特征和属性),才能根据提前制定的“策略”,对要操作的“对象”进行弹性伸缩。但是从实际业务流量的变高,到负载量“变化”,再到监控组件监控到负载量变化,到最后引发弹性扩缩容发生往往需要较长的时间。
此外,为了保证 Pod 高的 QoS,防止重要 Pod 被 Kubernetes 的调度器驱逐,用户会将容器设置相同的 Request 和 Limit,此时用户实际的资源使用率最多只有 100%。假设用户使用 HPA,且阈值设置为 90%,则每次扩容,副本数最多只能扩容到现在的 1/0.9=1.11 倍。倘若此时流量突然增大到必须使用现在两倍的资源量,即两倍的副本数,则需要扩容 8 次才能承载两倍的流量:(1(1.18)= 2.14),很明显这个扩容步骤过多,周期过长。
时间窗口的设置,当前 HPA 控制器中针对扩容和缩容分别有一个时间窗口,即在该窗口内会尽量保证 HPA 扩缩容的目标副本数处于稳定的状态,其中扩容是3分钟,而缩容是5分钟。若时间窗口设置得较小,则副本数可能频繁变化导致集群状态不稳定;若时间窗口设置得较大,则扩缩容反应时间太慢,无法有效应对突发流量。
扩容是有可能失败的,这对流量突发场景可能是致命的,例如:云上的资源是有可能售罄的,此时无法扩容。
当前 Cluster Autoscaler 的节点扩缩容主要依赖 Pod 的 Pending 情况,数据过于单一,精度有待提高。并且 Pod 的 Pending 只查看已分配的资源请求和限制,而不是实际的资源使用情况,对业务方来说,过度配置 Pod 是常见的做法,这些都影响着弹性伸缩的精度。
一个集群中存在多个规格的 CVM,扩容和缩容应优先处理哪种规格的 CVM,例如:缩容大规格节点容易引发容器重新调度后的争抢饥饿,缩容小规格节点有可能导致集群最后仅剩下大规格节点。
当前的弹性伸缩的各种方法还不够自动化,虽然最后能实现自动的弹性扩缩容,但是它还是建立在前期大量的手工配置上面,这些配置需要很强的业务经验和积累,以及对 Kubernetes 各种弹性伸缩的深刻理解。
以 HPA 为例,目前 TKE 已经支持了五大类共 30 个不同的指标,了解更多详细内容请参见 TKE 自动伸缩指标说明,此外,TKE 还提供了使用自定义指标进行弹性伸缩的方法。这么多的指标该如何选择?那种指标才是最合适自己业务的指标?指标的数值设置成多少合适?副本数的变化范围该如何设置?这里都是影响弹性伸缩的关键因素。
什么时间因为什么事情造成了什么样的弹性扩缩容结果,这对现有的监控系统来说,还需要做较多努力。因为现有的监控系统通常都是监控某一项指标,它可以监控副本数的变化,可以监控弹性伸缩对象的变化,也可以监控资源使用率的情况,甚至可以监控事件/日志等信息,但是把它们有机的结合在一起,互联互通却是一件相对来讲较为困难的事情,当前弹性伸缩的可观测性方面还需要人工聚合和分析多方面的监控数据,需要高度定制化,对运维人员来说依旧是一件比较繁琐的事情。
当前 HPA 监控的是 Pod 的指标,但是有些 Pod 里存在多个容器,主业务容器高负载的情况下,如果此时 sidecar 容器低负载,并且此 Pod 下所有容器的平均资源利用率低于引发扩容的阈值时,也无法引发扩容,配置的弹性伸缩无效。维度方面还有一个高维度的问题:同样以 HPA 为例,作用对象是 Pod 级别,但产品通常是以应用为中心,HPA 的弹性伸缩缺少“联动效应”,例如一个 Pod 的扩缩容是否可以自动引发同一个应用下其它 Pod 的扩缩容?
一个 Pod 资源利用率很低,若它的资源被弹性收缩后,资源被别的负载侵占,此时如果这个 Pod 负载突然变高,但节点又没有剩余可用资源,是该驱逐该 Pod 还是驱逐别的 Pod?
我们致力于依托腾讯云原生团队提供的各种弹性伸缩服务,帮助客户实现自动化的资源管理,减少人力维护成本以及资源浪费,提升弹性伸缩灵敏度、精确度、自动化、可观测性。具体可参照的 Kubernetes 降本增效标准指南系列的上一篇文章《资源利用率提升工具大全》。
欢迎广大读者试用并且提出您宝贵的建议。