作者:马伟,青云科技容器顾问,云原生爱好者,目前专注于云原生技术,云原生领域技术栈涉及 Kubernetes、KubeSphere、KubeKey 等。

2019 年,我在给很多企业部署虚拟化,介绍虚拟网络和虚拟存储。

2023 年,这些企业都已经上了云原生了。对于高流量的 Web 应用程序,实时数据分析,大规模数据处理、移动应用程序等业务,容器比虚拟机更适合,因为它轻量级,快速响应,可轻松移植,并具有很强的弹性伸缩能力。

为什么需要弹性伸缩呢?

  • 峰值负载应对:促销活动、节假日购物季或突发事件根据需求快速扩展资源,保证应用可用性和性能。
  • 提高资源利用率:根据实际资源负载动态调整资源规模,避免基础设施资源浪费,降低 TCO。
  • 应对故障和容错:多实例部署和快速替换,提高业务连续性和可用性。
  • 跟随需求变化:匹配前端的业务需求及压力,快速调整规模,提高事件应对能力,满足需求和期望。

Horizontal Pod Autoscaling

Kubernetes 自身提供一种弹性伸缩的机制,包括 Vertical Pod Autoscaler (VPA)和 Horizontal Pod Autoscaler (HPA)。HPA 根据 CPU 、内存利用率增加或减少副本控制器的 pod 数量,它是一个扩缩资源规模的功能特性。

HPA 依赖 Metrics-Server 捕获 CPU、内存数据来提供资源使用测量数据,也可以根据自定义指标(如 Prometheus)进行扩缩。

由上图看出,HPA 持续监控 Metrics-Server 的指标情况,然后计算所需的副本数动态调整资源副本,实现设置目标资源值的水平伸缩。

但也有一定局限性:

  • 无外部指标支持。如不同的事件源,不同的中间件/应用程序等,业务端的应用程序变化及依赖是多样的,不只是基于 CPU 和内存扩展。
  • 无法 1->0。应用程序总有 0 负载的时候,此时不能不运行工作负载吗?

所以就有了Kubernetes-based Event-Driven Autoscaling(KEDA)!

KEDA

KEDA 基于事件驱动进行自动伸缩。什么是事件驱动?我理解是对系统上的各种事件做出反应并采取相应行动(伸缩)。那么 KEDA 就是一个 HPA+多种触发器。只要触发器收到某个事件被触发,KEDA 就可以使用 HPA 进行自动伸缩了,并且,KEDA 可以 1-0,0-1!

架构

KEDA 自身有几个组件:

  • Agent: KEDA 激活和停止 Kubernetes 工作负载(keda-operator 主要功能)
  • Metrics: KEDA 作为一个 Kubernetes 指标服务器,向 Horizontal Pod Autoscaler 提供丰富的事件数据,从源头上消费事件。(keda-operator-metrics-apiserver 主要作用)。
  • Admission Webhooks: 自动验证资源变化,以防止错误配置。
  • Event sources: KEDA 更改 pod 数量的外部事件/触发源。如 Prometheus、Kafka。
  • Scalers: 监视事件源,获取指标并根据事件触发伸缩。
  • Metrics adapter:从 Scalers 获取指标并发送给 HPA。
  • Controller: 根据 Adapter 提供的指标进行操作,调谐到 ScaledObject 中指定的资源状态。Scaler 根据 ScaledObject 中设置的事件源持续监视事件,发生任何触发事件时将指标传递给 Metrics Adapter。Metrics Adapter 调整指标并提供给 Controller 组件,Controller 根据 ScaledObject 中设置的缩放规则扩大或缩小 Deployment。

总的来说,KEDA 设置一个 ScaledObject,定义一个事件触发器,可以是来自消息队列的消息、主题订阅的消息、存储队列的消息、事件网关的事件或自定义的触发器。基于这些事件来自动调整应用程序的副本数量或处理程序的资源配置,以根据实际负载情况实现弹性伸缩。

CRD

  • ScaledObjects:代表事件源(如 Rabbit MQ)和 Kubernetes。 Deployment、StatefulSet 或任何定义 / 规模子资源的自定义资源之间的所需映射。
  • ScaledJobs:事件源和 Kubernetes Jobs 之间的映射。根据事件触发调整 Job 规模。
  • TriggerAuthentications:触发器的认证参数。
  • ClusterTriggerAuthentications:集群维度认证。

部署 KEDA

helm repo add kedacore https://kedacore.github.io/charts
helm repo update
kubectl create namespace keda
helm install keda kedacore/keda --namespace kedakubectl apply -f https://github.com/kedacore/keda/releases/download/v2.10.1/keda-2.10.1.yamlroot@node-1:/# kubectl get all -n keda
NAME                                          READY   STATUS    RESTARTS   AGE
pod/keda-metrics-apiserver-7d89dbcb54-v22nl   1/1     Running   0          44s
pod/keda-operator-5bb9b49d7c-kh6wt            0/1     Running   0          44sNAME                             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/keda-metrics-apiserver   ClusterIP   10.233.44.19   <none>        443/TCP,80/TCP   45sNAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/keda-metrics-apiserver   1/1     1            1           45s
deployment.apps/keda-operator            0/1     1            0           45sNAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/keda-metrics-apiserver-7d89dbcb54   1         1         1       45s
replicaset.apps/keda-operator-5bb9b49d7c            1         1         0       45s
root@node-1:/# kubectl get all -n keda
NAME                                          READY   STATUS    RESTARTS   AGE
pod/keda-metrics-apiserver-7d89dbcb54-v22nl   1/1     Running   0          4m8s
pod/keda-operator-5bb9b49d7c-kh6wt            1/1     Running   0          4m8sNAME                             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/keda-metrics-apiserver   ClusterIP   10.233.44.19   <none>        443/TCP,80/TCP   4m9sNAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/keda-metrics-apiserver   1/1     1            1           4m9s
deployment.apps/keda-operator            1/1     1            1           4m9sNAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/keda-metrics-apiserver-7d89dbcb54   1         1         1       4m9s
replicaset.apps/keda-operator-5bb9b49d7c
# kubectl get crd | grep keda
clustertriggerauthentications.keda.sh                     2023-05-11T09:26:06Z
scaledjobs.keda.sh                                        2023-05-11T09:26:07Z
scaledobjects.keda.sh                                     2023-05-11T09:26:07Z
triggerauthentications.keda.sh                            2023-05-11T09:26:07Z

KubeSphere 部署 KEDA

kubectl edit cc -n kubesphere-system (kubesphere 3.4+)
spec:
···autoscaling:enabled: true
···

扩展工作负载 CRD

ScaledObject 资源定义,详情参数请看 :https://keda.sh/docs/2.10/concepts/scaling-deployments/。

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:name: {scaled-object-name}
spec:scaleTargetRef:apiVersion:    {api-version-of-target-resource}  # Optional. Default: apps/v1kind:          {kind-of-target-resource}         # Optional. Default: Deploymentname:          {name-of-target-resource}         # Mandatory. Must be in the same namespace as the ScaledObjectenvSourceContainerName: {container-name}         # Optional. Default: .spec.template.spec.containers[0]pollingInterval:  30                               # Optional. Default: 30 secondscooldownPeriod:   300                              # Optional. Default: 300 secondsidleReplicaCount: 0                                # Optional. Default: ignored, must be less than minReplicaCountminReplicaCount:  1                                # Optional. Default: 0maxReplicaCount:  100                              # Optional. Default: 100fallback:                                          # Optional. Section to specify fallback optionsfailureThreshold: 3                              # Mandatory if fallback section is includedreplicas: 6                                      # Mandatory if fallback section is includedadvanced:                                          # Optional. Section to specify advanced optionsrestoreToOriginalReplicaCount: true/false        # Optional. Default: falsehorizontalPodAutoscalerConfig:                   # Optional. Section to specify HPA related optionsname: {name-of-hpa-resource}                   # Optional. Default: keda-hpa-{scaled-object-name}behavior:                                      # Optional. Use to modify HPA's scaling behaviorscaleDown:stabilizationWindowSeconds: 300policies:- type: Percentvalue: 100periodSeconds: 15triggers:# {list of triggers to activate scaling of the target resource}

查看 KEDA Mterics Server 暴露的指标

kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1"

Demo

KEDA 目前支持 53 种 Scalers,如 Kafka,Elasticsearch,MySQL,RabbitMQ,Prometheus 等等。 此处演示一个 Prometheus 和 Kafka 的例子。

Prometheus & KEDA

部署一个 Web 应用,使用 Prometheus 监控 Web 应用 http 请求指标。

为寻求演示效果,此处部署了一个有点击,互动的 Demo APP,地址如下:https://github.com/livewyer-ops/keda-demo/blob/v1.0.0/examples/keda/。

部署成功后通过 NodePort 访问:

进入 KubeSphere 项目,新建一个自定义伸缩:

设置最小副本数为 1,最大副本数为 10,轮询间隔 5 秒,等待时间为 1 分钟:

KubeSphere 支持 Cron、Prometheus,和自定义触发器:

触发器设置 Prometheus,设置请求为 30s 内的增长率总和,当阈值大于 3 时事件驱动触发缩放:

设置一些其他设置,如资源删除后是否恢复指本来的副本数,以及扩缩策略设置:

现在并发访问 Web App:

可以在自定义监控看到监控指标的变化:

Web App 的副本数开始横向扩展:

最终扩展到 ScaledObject 中定义的 10 个副本:

在访问停止后,可以看到监控指标的数值在慢慢变小:

Deployment 开始缩容:

Kafka & KEDA

KEDA 使用 Kafka 事件源演示的整体拓扑如下:

Kafka 使用 Demo 代码:https://github.com/ChamilaLiyanage/kafka-keda-example.git。

部署 Kafka

打开 KubeSphere 应用商店,查看 DMP 数据库中心:

选择 Kafka,进行安装:

安装好 Kafka 后,创建一个测试的 Kafka Topic,Topic 分区设置为 5,副本设置为 1:

创建 Kafka Producer 服务:

向主题发送订单:

创建 Consumer 服务:

发送新订单看 Consumer 服务是否消费:

现在可以来做自动伸缩了,创建一个 ScaledObject,设置最小副本数为 0,最大为 10,轮询间隔为 5s,Kafka LagThreshold 为 10:

apiVersion: keda.k8s.io/v1alpha1
kind: ScaledObject
metadata:name: kafka-scaledobjectnamespace: defaultlabels:deploymentName: kafka-consumer-deployment # Required Name of the deployment we want to scale.
spec:scaleTargetRef:deploymentName: kafka-consumer-deployment # Required Name of the deployment we want to scale.pollingInterval: 5minReplicaCount: 0   #Optional Default 0maxReplicaCount: 10  #Optional Default 100triggers:- type: kafkametadata:# RequiredBootstrapeServers: radondb-kafka-kafka-external-bootstrap.demo:9092 # Kafka bootstrap server host and portconsumerGroup: order-shipper  # Make sure that this consumer group name is the same one as the one that is consuming topicstopic: testlagThreshold: "10" # Optional. How much the stream is lagging on the current consumer group

创建自定义伸缩:

现在,让我们向队列提交大约 100,000 条订单消息,看看自动缩放的实际效果。你会看到随着队列中多余消息的增长,将会产生更多的 kafka-consumer pod。

NAMESPACE   NAME                      REFERENCE                   TARGETS      MINPODS   MAXPODS   REPLICAS   AGE
demo        keda-hpa-kafka-consumer   Deployment/kafka-consumer   5/10 (avg)   1         10        1          2m35s

此处我们看到最大到 5 个副本,没有到 10 个副本,因为默认最大副本数不会超过 Kafka 主题分区数量,上面设置了分区为 5,可以激活 allowIdleConsumers: true 来禁用这个默认行为。 重新编辑自定义伸缩后,最大副本变化成 10:

在无消息消费时,副本变化为 0:

结尾

到这里本篇就结束了,对此有需求或感兴趣的小伙伴可以操练起来了。

本文由博客一文多发平台 OpenWrite 发布!

应用现代化中的弹性伸缩相关推荐

  1. 弹性伸缩服务在商业应用中的优劣势分析

    在数字化飞速发展的今天,许多企业都面临着业务量快速变化的问题.为了应对这种变化,企业需要采用一种动态的资源调度机制,即弹性伸缩服务.本文将详细介绍弹性伸缩服务的优势.应用场景以及在实战中的具体应用. ...

  2. 基于希克斯需求价格弹性计算_Serverless弹性伸缩的现状调研(超详细)

    作者:闲鱼技术--影湛 引言 闲鱼的服务端技术架构正向着云原生/Serverless化发展,Serverless具有着运维自动化.按需加载.弹性伸缩.强隔离性.敏捷开发部署等技术特点,带来了降低人力成 ...

  3. 计算云服务——弹性伸缩服务

    AS简介 弹性伸缩(Auto Scaling)是根据用户的业务需求,通过策略自动调整其业务资源的服务.您可以根据业务需求自行定义伸缩配置和伸缩策略,降低人为反复调整资源以应对业务变化和高峰压力的工作量 ...

  4. 一分钟了解阿里云产品:弹性伸缩概述

    阿里云发布了很多产品,今天让我们来一起了解下弹性伸缩(Auto Scaling)吧. 什么是弹性伸缩呢?让我来给大家解释下. 弹性伸缩是根据用户的业务需求和策略,自动调整其弹性计算资源的管理服务.其能 ...

  5. 如何利用弹性伸缩服务降低80%的机器成本

    一.引言 弹性伸缩服务是一种应用在云计算平台上的技术,能够自动根据工作负载和业务需求来调整资源,从而达到优化成本和提高资源利用率的目的.本文将分享一些在实际操作中使用弹性伸缩服务的技巧,并探讨其在企业 ...

  6. 美团弹性伸缩系统的技术演进与落地实践

    弹性伸缩具有应突发.省成本.自动化的业务价值.平台侧将各业务零散.闲置资源进行整合,形成一个大规模资源池,通过弹性调度.库存管控技术在公司运营成本和业务体感中寻求较好的平衡. 本文将介绍美团弹性伸缩系 ...

  7. 弹性伸缩:实现自动扩展和缩减容器的秘诀

    在当今的云计算环境中,弹性伸缩是确保应用程序在高流量或高峰期能够正常工作的关键.Rancher是一个领先的开源容器平台,提供了一系列强大的功能,其中包括通过webhook微服务实现Service/Ho ...

  8. 弹性伸缩:实现自动资源管理的利器

    随着互联网技术的不断发展,云计算已经成为了当今社会的重要组成部分.在云计算中,弹性伸缩是一个重要的概念,它可以让应用在需求量变化时自动增加或减少资源,从而达到最优的资源利用率.而实现弹性伸缩的关键就在 ...

  9. 阿里云弹性伸缩在生产环境中的实战应用

    之所以要写这篇文章,是因为11月19日正好是个周五,一下班匆匆忙忙拿起书包往家赶,谁知刚出公司大门就连续接到好几个报警电话,服务器崩掉了.赶紧回公司定位问题,发现公司发了一条公众号,链接到商城小程序的 ...

最新文章

  1. linux安全加固(2)
  2. erlang精要(5)-列表推导式
  3. csv注入java怎么解决_CSV Injection(CSV注入)
  4. 2020年8月编程语言排行榜新鲜出炉 - 编程语言世界的假期
  5. 决策树之C4.5算法
  6. gh0st源码分析与远控的编写(二)
  7. 记录ishield遇到的问题的解决过程
  8. Unknown column 'XXX' in 'where clause'一例排查
  9. 线性规划与多目标规划
  10. LeetCode(705)——设计哈希集合(JavaScript)
  11. explict关键字
  12. 2021“数维杯”国际大学生数学建模竞赛A题思路
  13. 如何查看本机ip地址,首先介绍下,查看电脑在局域网里的ip地址
  14. HTML页面返回503状态码设置,503错误网页状态码出现原因及监控方法介绍
  15. 计算机网络中速率(date rate)和带宽的区别
  16. 活动(已结束)--我们是冠军,啊呸,我们是CSDN VIP
  17. 单招计算机面试技巧和注意事项,单招面试技巧和注意事项
  18. java 微信 图灵机器人,SAE服务下用java实现微信公众账号图灵机器人
  19. 使用golang发送电子邮件
  20. linux 服务器配置

热门文章

  1. 【锐捷无线】隐藏SSID配置
  2. ElementUI中InfiniteScroll无法控制自动加载问题的解决
  3. 计算机科学美在哪些方面,揭秘美本-计算机科学专业是什么? 爱问知识人
  4. 微信小程序开发之——录音播放及文件上传下载-理论(1)
  5. PostgreSql 日期类型处理
  6. UE4控制三自由度动感平台
  7. C++ int类型最大最小数字(16进制)
  8. Cray 推出开源大数据一体机 Urika-GX
  9. 国产之路:复旦微调试笔记3:环境配置
  10. 三星530换固态硬盘_三星迷你固态硬盘Portable SSD T7 Touch试用 支持指纹识别设备...