Kubernetes弹性伸缩全场景解读(八) - 定时伸缩组件支持HPA兼容

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 在之前的文章中,我们介绍了kubernetes-cronhpa-controller是如何通过设置定时的方式触发容器的水平副本伸缩,但是在实际的场景下,虽然定时伸缩对于负载有规律的应用比较友好,但是应用为了防止突发的流量冲击,还是会配置HPA来做最后的保障的。

前言

在之前的文章中,我们介绍了kubernetes-cronhpa-controller是如何通过设置定时的方式触发容器的水平副本伸缩,但是在实际的场景下,虽然定时伸缩对于负载有规律的应用比较友好,但是应用为了防止突发的流量冲击,还是会配置HPA来做最后的保障的。那么CronHPA与HPA之间该怎么选择呢?

定时伸缩组件兼容HPA

在抉择什么时候需要CronHPA,什么时候使用HPA的时候,我们在思考是否可以将CronHPA与HPA一起使用,如果一起使用会有什么需要解决的问题呢?首先我们先看CronHPA的模板定义

apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:
  labels:
    controller-tools.k8s.io: "1.0"
  name: cronhpa-sample
spec:
   scaleTargetRef:
      apiVersion: apps/v1
      kind: Deployment
      name: nginx-deployment-basic
   jobs:
   - name: "scale-down"
     schedule: "30 */1 * * * *"
     targetSize: 1
   - name: "scale-up"
     schedule: "0 */1 * * * *"
     targetSize: 3

在CronHPA中是通过scaleTargetRef字段来获取伸缩对象的,并通过jobs的crontab规则定时伸缩实例的副本。

那么我们再来看下HPA的模板定义

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-deployment-basic
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

HPA也是通过scaleTargetRef来定义伸缩的对象,并通过资源利用率来判断伸缩的情况。如果同时设置CronHPA与HPA,那么就会出现HPA与CronHPA同时操作一个scaleTargetRef的场景,而两者之间又相互独立无法感知,这样就会出现两个controller各自工作,后执行的会覆盖先执行的结果。

c01acfe2a616965e45a57714436e20aef08a3269.png
这个问题的本质是两个controller无法相互感知,从而造成了异常,当回过头来看这个问题的时候,其实我们可以发现HPA早期也有同样的问题,开发者如果希望通过用两个监控指标同时作用到HPA的时候,如果设置两个HPA对象,会出现类似的问题,在解决这个问题的时候,是通过在HPA对象中定义metrics字段,将多个metrics合并到一个HPA对象中来实现的,例如:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-deployment-basic
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 50

当两个metrics触发弹性的个数不同的时候,会根据稳定性第一的原则,优先弹出更多的副本或者在缩容时保留更多的副本。那么是否CronHPA和HPA也可以通过这个方案进行整合,答案是Yes and No。因为的确可以通过alibaba-cloud-metrics-adapter将定时的数据通过External Metrics的方式进行转换,然后通过HPA中使用External Metrics的方式进行整合和匹配。但是这样会带来的结果就是,我们需要通过HPA的结构去表达CronHPA的规则,然后再通过Metrics Adapter的模型去转换时间信息与副本计算。从模型上来看,这个方式看似兼容了HPA,但是实际上对定时伸缩的可读性、学习成本、出错诊断、审计与离线都带来了新的挑战。

那么是否还有其他的方法可以实现CronHPA与HPA的兼容呢?我们将视角放回scaleTargetRef,还记得HPA是怎么伸缩Deployment的Pod吗,是HPA将Deployment配置在了scaleTargetRef的字段下,然后Deployment通过自身定义查找到了ReplicaSet,在通过ReplicaSet调整了真实的副本数目。
b4259cc83f9b203cf4c35cf96e48fddfdbc61b12.png
那么从这个角度出发,我们有了一个大胆的想法,是否可以将scaleTargetRef设置为HPA对象,然后通过HPA对象来寻找真实的scaleTargetRef
6dfb0eba5791cb43ef0d1cd4397f4eaab8553c22.png

apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:
  labels:
    controller-tools.k8s.io: "1.0"
  name: cronhpa-sample
spec:
   scaleTargetRef:
      apiVersion: autoscaling/v1
      kind: HorizontalPodAutoscaler
      name:  nginx-deployment-basic-hpa
   jobs:
   - name: "scale-down"
     schedule: "30 */1 * * * *"
     targetSize: 1
     runOnce: true
   - name: "scale-up"
     schedule: "0 */1 * * * *"
     targetSize: 3
     runOnce: true

这样设计的好处是,首先CronHPA可以感知HPA当前的状态,明确的知晓HPA的min、max、desired的数值,同时也知道HPA scaleTargetRef所对应的当前replicas。那么本着稳定性原则,我们要如何操控HPA呢?

hpa(min/max) cronhpa deployment result 场景
1/10 5 5 hpa(1/10) deployment 5 定时和当前一致,无需变更
1/10 4 5 hpa(1/10) deployment 5 当前高于定时,保留当前副本
1/10 6 5 hpa(6/10) deployment 6 定时高于当前,保留定时副本
定时高于HPA下限,修改HPA下限
5/10 4 5 hpa(4/10) deployment 5 定时低于当前,保留当前副本
定时低于HPA下限,修改HPA下限
5/10 11 5 hpa(11/11) deployment 11 定时高于当前,保留定时副本
定时高于HPA上限,修改HPA上限

如上图所以,CronHPA会通过调整HPA的方式进行感知,CronHPA要达到的副本和当前副本取大值,来判断是否要扩容以及修改HPA的上限。CronHPA要达到的副本和HPA的配置取小值,判断是否要修改HPA的下限。简单而言,CronHPA不会直接调整Deployment的副本数目,而是通过HPA来操作Deployment,这样就可以避免HPA和CronHPA的冲突问题了。

最后

定时伸缩CronHPA和HPA都是在线业务场景下非常重要的功能,不论使用何种的兼容与适配的方式,稳定性第一的原则是不能改变的,开发者如果对CronHPA感兴趣,欢迎提交PR

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
6月前
|
Kubernetes 监控 Cloud Native
Kubernetes自动伸缩方案的终极指南
【4月更文挑战第18天】
315 0
Kubernetes自动伸缩方案的终极指南
|
28天前
|
存储 Kubernetes 持续交付
介绍一下Kubernetes的应用场景
【10月更文挑战第18天】介绍一下Kubernetes的应用场景。
126 3
|
1月前
|
Prometheus Kubernetes 监控
k8s学习--kubernetes服务自动伸缩之水平伸缩(pod副本伸缩)HPA详细解释与案例应用
k8s学习--kubernetes服务自动伸缩之水平伸缩(pod副本伸缩)HPA详细解释与案例应用
107 1
k8s学习--kubernetes服务自动伸缩之水平伸缩(pod副本伸缩)HPA详细解释与案例应用
|
1月前
|
Kubernetes 应用服务中间件 nginx
k8s学习--kubernetes服务自动伸缩之水平收缩(pod副本收缩)VPA策略应用案例
k8s学习--kubernetes服务自动伸缩之水平收缩(pod副本收缩)VPA策略应用案例
|
1月前
|
Kubernetes 监控 调度
k8s学习--kubernetes服务自动伸缩之垂直伸缩(资源伸缩)VPA详细解释与安装
k8s学习--kubernetes服务自动伸缩之垂直伸缩(资源伸缩)VPA详细解释与安装
|
3月前
|
存储 Kubernetes API
在K8S中,etcd 适应的场景?
在K8S中,etcd 适应的场景?
|
3月前
|
运维 Kubernetes 大数据
Kubernetes 的架构问题之在Serverless Container场景下尚不支持资源超售如何解决
Kubernetes 的架构问题之在Serverless Container场景下尚不支持资源超售如何解决
63 0
|
3月前
|
Kubernetes Cloud Native 应用服务中间件
Kubernetes 自动伸缩策略:优化资源利用率
【8月更文第29天】在现代云原生环境中,应用的流量往往具有不可预测性。为了应对这种变化,Kubernetes 提供了多种自动伸缩机制来动态调整应用实例的数量和每个实例分配的资源。本文将深入探讨两种主要的自动伸缩工具:水平 Pod 自动伸缩器 (HPA) 和垂直 Pod 伸缩器 (VPA),并提供实际的应用示例。
101 0
|
3月前
|
存储 缓存 Kubernetes
在K8S中,有状态服务与无状态服务都是怎么使用pv和pvc?(可以通过应用场景说明一下)
在K8S中,有状态服务与无状态服务都是怎么使用pv和pvc?(可以通过应用场景说明一下)
|
3月前
|
Prometheus Kubernetes 监控
在K8S中,当Pod业务量比较大时候,如何实现水平伸缩和扩容?
在K8S中,当Pod业务量比较大时候,如何实现水平伸缩和扩容?

相关产品

  • 容器服务Kubernetes版
  • 下一篇
    无影云桌面