如何根据不同业务场景调节 HPA 扩缩容灵敏度
背景
在 K8s 1.18 之前,HPA 扩容是无法调整灵敏度的:
- 对于缩容,由
kube-controller-manager
的--horizontal-pod-autoscaler-downscale-stabilization-window
参数控制缩容时间窗口,默认 5 分钟,即负载减小后至少需要等 5 分钟才会缩容。 - 对于扩容,由 hpa controller 固定的算法、硬编码的常量因子来控制扩容速度,无法自定义。
这样的设计逻辑导致用户无法自定义 HPA 的扩缩容灵敏度,而不同的业务场景对于扩容容灵敏度要求可能是不一样的,比如:
- 对于有流量突发的关键业务,在需要的时候应该快速扩容 (即便可能不需要,以防万一),但缩容要慢 (防止另一个流量高峰)。
- 对于一些需要处理大量数据的离线业务,在需要的时候应该尽快扩容以减少处理时间,不需要那么多资源的时候应该尽快缩容以节约成本。
- 处理常规数据/网络流量的业务,它们可能会以一般的方式扩大和缩小规模,以减少抖动。
HPA 在 K8s 1.18 迎来了一次更新,在之前 v2beta2 版本上新增了扩缩容灵敏度的控制,不过版本号依然保持 v2beta2 不变。
如何使用
这次更新实际就是在 HPA Spec 下新增了一个 behavior
字段,下面有 scaleUp
和 scaleDown
两个字段分别控制扩容和缩容的行为,具体可参考官方 API 文档: https://v1-18.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#horizontalpodautoscalerbehavior-v2beta2-autoscaling
下面给出一些使用场景的示例。
快速扩容
当你的应用需要快速扩容时,可以使用类似如下的 HPA 配置:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: web
spec:
minReplicas: 1
maxReplicas: 1000
metrics:
- pods:
metric:
name: k8s_pod_rate_cpu_core_used_limit
target:
averageValue: "80"
type: AverageValue
type: Pods
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
behavior: # 这里是重点
scaleUp:
policies:
- type: percent
value: 900%
上面的配置表示扩容时立即新增当前 9 倍数量的副本数,即立即扩容到当前 10 倍的 Pod 数量,当然也不能超过 maxReplicas
的限制。
假如一开始只有 1 个 Pod,如果遭遇流量突发,它将以飞快的速度进行扩容,扩容时 Pod 数量变化趋势如下:
1 -> 10 -> 100 -> 1000
没有配置缩容策略,将等待全局默认的缩容时间窗口 (--horizontal-pod-autoscaler-downscale-stabilization-window
,默认5分钟) 后开始缩容。
快速扩容,缓慢缩容
如果流量高峰过了,并发量骤降,如果用默认的缩容策略,等几分钟后 Pod 数量也会随之骤降,如果 Pod 缩容后突然又来一个流量高峰,虽然可以快速扩容,但扩容的过程毕竟还是需要一定时间的,如果流量高峰足够高,在这段时间内还是可能造成后端处理能力跟不上,导致部分请求失败。这时候我们可以为 HPA 加上缩容策略,HPA behavior
配置示例如下:
behavior:
scaleUp:
policies:
- type: percent
value: 900%
scaleDown:
policies:
- type: pods
value: 1
periodSeconds: 600 # 每 10 分钟只缩掉 1 个 Pod
上面示例中增加了 scaleDown
的配置,指定缩容时每 10 分钟才缩掉 1 个 Pod,大大降低了缩容速度,缩容时的 Pod 数量变化趋势如下:
1000 -> … (10 min later) -> 999
这个可以让关键业务在可能有流量突发的情况下保持处理能力,避免流量高峰导致部分请求失败。
缓慢扩容
如果想要你的应用不太关键,希望扩容时不要太敏感,可以让它扩容平稳缓慢一点,为 HPA 加入下面的 behavior
:
behavior:
scaleUp:
policies:
- type: pods
value: 1 # 每次扩容只新增 1 个 Pod
假如一开始只有 1 个 Pod,扩容时它的 Pod 数量变化趋势如下:
1 -> 2 -> 3 -> 4
禁止自动缩容
如果应用非常关键,希望扩容后不自动缩容,需要人工干预或其它自己开发的 controller 来判断缩容条件,可以使用类型如下的 behavior
配置来禁止自动缩容:
behavior:
scaleDown:
policies:
- type: pods
value: 0
延长缩容时间窗口
缩容默认时间窗口是 5 min (--horizontal-pod-autoscaler-downscale-stabilization-window
),如果我们需要延长时间窗口以避免一些流量毛刺造成的异常,可以指定下缩容的时间窗口,behavior
配置示例如下:
behavior:
scaleDown:
stabilizationWindowSeconds: 600 # 等待 10 分钟再开始缩容
policies:
- type: pods
value: 5 # 每次只缩掉 5 个 Pod
上面的示例表示当负载降下来时,会等待 600s (10 分钟) 再缩容,每次只缩容 5 个 Pod。
延长扩容时间窗口
有些应用经常会有数据毛刺导致频繁扩容,而扩容出来的 Pod 其实没太大必要,反而浪费资源。比如数据处理管道的场景,扩容指标是队列中的事件数量, 当队列中堆积了大量事件时,我们希望可以快速扩容,但又不希望太灵敏,因为可能只是短时间内的事件堆积,即使不扩容也可以很快处理掉。
默认的扩容算法会在较短的时间内扩容,针对这种场景我们可以给扩容增加一个时间窗口以避免毛刺导致扩容带来的资源浪费,behavior
配置示例如下:
behavior:
scaleUp:
stabilizationWindowSeconds: 300 # 扩容前等待 5 分钟的时间窗口
policies:
- type: pods
value: 20 # 每次扩容新增 20 个 Pod
上面的示例表示扩容时,需要先等待 5 分钟的时间窗口,如果在这段时间内负载降下来了就不再扩容,如果负载持续超过扩容阀值才扩容,每次扩容新增 20 个 Pod。
小结
本文介绍了如何利用 K8s 1.18 的 HPA 新特性来控制扩缩容的灵敏度,以更好的满足各种不同场景对扩容速度的需求。
参考资料
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
如何根据不同业务场景调节 HPA 扩缩容灵敏度的更多相关文章
- 三十三、HPA实现自动扩缩容
通过HPA实现业务应用的动态扩缩容 HPA控制器介绍 当系统资源过高的时候,我们可以使用如下命令来实现 Pod 的扩缩容功能 $ kubectl -n luffy scale deployment m ...
- Airbnb的动态kubernetes集群扩缩容
Airbnb的动态kubernetes集群扩缩容 本文介绍了Airbnb的集群扩缩容的演化历史,以及当前是如何通过Cluster Autoscaler 实现自定义扩展器的.最重要的经验就是Airbnb ...
- Knative 基本功能深入剖析:Knative Serving 自动扩缩容 Autoscaler
Knative Serving 默认情况下,提供了开箱即用的快速.基于请求的自动扩缩容功能 - Knative Pod Autoscaler(KPA).下面带你体验如何在 Knative 中玩转 Au ...
- 【kubevirt】VirtualMachineInstanceReplicaSet(vmis)-扩缩容-弹性伸缩
@ 目录 概述/理解 使用场景 创建vmis 扩缩容 弹性伸缩 方法1 方法2 概述/理解 VirtualMachineInstanceReplicaSet(vmis)确保指定数量的 VirtualM ...
- 从零入门 Serverless | Serverless Kubernetes 应用部署及扩缩容
作者 | 邓青琳(轻零) 阿里云技术专家 导读:本文分为三个部分,首先给大家演示 Serverless Kubernetes 集群的创建和业务应用的部署,其次介绍 Serverless Kuberne ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容
上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...
- Netty 如何高效接收网络数据?一文聊透 ByteBuffer 动态自适应扩缩容机制
本系列Netty源码解析文章基于 4.1.56.Final版本,公众号:bin的技术小屋 前文回顾 在前边的系列文章中,我们从内核如何收发网络数据开始以一个C10K的问题作为主线详细从内核角度阐述了网 ...
- Kubernetes 监控:Prometheus Adpater =》自定义指标扩缩容
使用 Kubernetes 进行容器编排的主要优点之一是,它可以非常轻松地对我们的应用程序进行水平扩展.Pod 水平自动缩放(HPA)可以根据 CPU 和内存使用量来扩展应用,前面讲解的 HPA 章节 ...
- 构建Docker平台【第四篇】创建服务及扩缩容等操作
第一步:创建服务 1. 配置 nginx 的 yaml 文件 apiVersion: extensions/v1beta1 kind: Deployment metadata: name: my-ng ...
随机推荐
- PyQt(Python+Qt)学习随笔:QTableWidget的获取指定位置项的item和itemAt方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 1.获取指定行和列的项 根据行和列可以获取对应位置的项,调用语法如下: QTableWidgetIt ...
- NOI2008 志愿者招聘
文化课 + 竞赛双废物又来水题解了. 首先,对于题干中的人,很像网络流中的流量,但是他有一个每天人数的下限,我从网上借鉴(chaoxi)到了两种思路: 把下界限制转化为一条边的流量下界,这样就是最小费 ...
- KVM初体验之virt-manager unable to connect to libvirt的处理办法
解决方法 需要用root身份运行virt-manager
- Vue--子组件互相传值,子组件来回传值,传值反复横跳
Vue--子组件传值,子组件来回传值,子组件传值反复横跳 我不不仅要子组件之间直接传值,我还要传过去再传回来,传回来再传过去,子组件直接反复横跳 解决问题 给组件传值,并不知道改值的校验结果 同一个组 ...
- STL—— 容器(vector)的数据写入、修改和删除
1. 通过 push_back() 尾部增加一个元素 : vector 可以通过 "push_back " 写入数据,通过 push_back 可以将数据直接写入至 vector ...
- 最简单的 K8S 部署文件编写姿势,没有之一!
1. 头疼编写K8S部署文件? K8S yaml 参数很多,需要边写边查? 保留回滚版本数怎么设? 如何探测启动成功,如何探活? 如何分配和限制资源? 如何设置时区?否则打印日志是GMT标准时间 如何 ...
- Validated 注解完成 Spring Boot 参数校验
1. @Valid 和 @Validated @Valid 注解,是 Bean Validation 所定义,可以添加在普通方法.构造方法.方法参数.方法返回.成员变量上,表示它们需要进行约束校验. ...
- 微服务开发的最大痛点-分布式事务SEATA入门简介
前言 在微服务开发中,存在诸多的开发痛点,例如分布式事务.全链路跟踪.限流降级和服务平滑上下线等.而在这其中,分布式事务是最让开发者头痛的.那分布式事务是什么呢? 分布式事务就是指事务的参与者.支持事 ...
- react第十四单元(react路由-react路由的跳转以及路由信息)
第十四单元(react路由-react路由的跳转以及路由信息) #课程目标 理解前端单页面应用与多页面应用的优缺点 理解react路由是前端单页面应用的核心 会使用react路由配置前端单页面应用框架 ...
- 一位弱校选手的oi经历
锦瑟无端五十弦,一弦一柱思华年. 这只是一位不知道什么时候就要退役的oier在一节晚自习的时候写的无聊东西 曾经也想好好写一写自己的oi历程,也许会有人看,不过因为自己懒加上文笔差也一直没写,直到昨天 ...