应用现代化中的弹性伸缩简介

描述

应用现代化中的弹性伸缩

这两年应用现代化的步伐飞快,19年我在很多企业部署虚拟化,介绍虚拟网络和虚拟存储。23年,这些企业都已经上了云原生或考虑云原生了。对于高流量的Web应用程序,实时数据分析,大规模数据处理、移动应用程序等业务,容器比虚拟机更适合,因为它轻量级,快速响应,可轻松移植,并具有很强的弹性伸缩能力。

为什么需要弹性伸缩呢?

• 峰值负载应对:促销活动、节假日购物季或突发事件根据需求快速扩展资源,保证应用可用性和性能。

• 提高资源利用率:根据实际资源负载动态调整资源规模,避免基础设施资源浪费,降低TCO。

• 应对故障和容错多实例部署和快速替换,提高业务连续性和可用性。

• 跟随需求变化:匹配前端的业务需求及压力,快速调整规模,提高事件应对能力,满足需求和期望。

Horizontal Pod Autoscaling

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

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

CRD

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

但也有一定局限性:

• 无外部指标支持。如不同的事件源,不同的中间件/应用程序等,业务端的应用程序变化及依赖是多样的,不只是基于CPU和内存扩展。

• 无法1->0。应用程序总有0负载的时候,此时不能不运行工作负载吗?

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

KEDA

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

架构

CRD

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 keda

kubectl apply -f https://github.com/kedacore/keda/releases/download/v2.10.1/keda-2.10.1.yaml
root@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          44s
NAME                             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/keda-metrics-apiserver   ClusterIP   10.233.44.19           443/TCP,80/TCP   45s
NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/keda-metrics-apiserver   1/1     1            1           45s
deployment.apps/keda-operator            0/1     1            0           45s
NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/keda-metrics-apiserver-7d89dbcb54   1         1         1       45s
replicaset.apps/keda-operator-5bb9b49d7c            1         1         0       45s
# kubectl get crd | grep keda
clustertriggerauthentications.keda.sh                     2023-05-11T0906Z
scaledjobs.keda.sh                                        2023-05-11T0907Z
scaledobjects.keda.sh                                     2023-05-11T0907Z
triggerauthentications.keda.sh                            2023-05-11T0907Z

 

KubeSphere部署KEDA

 

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

 

扩展工作负载CRD

ScaledObject对象主要定义要扩展的目标对象,如Deployment、Statefulset、CRD等,Triggers部分声明对应的触发器,在进行这些参数设置后,一个KEDA的自定义伸缩就可以启用了。

 

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: {scaled-object-name}
spec:
  scaleTargetRef:
    apiVersion:    {api-version-of-target-resource}  # Optional. Default: apps/v1
    kind:          {kind-of-target-resource}         # Optional. Default: Deployment
    name:          {name-of-target-resource}         # Mandatory. Must be in the same namespace as the ScaledObject
    envSourceContainerName: {container-name}         # Optional. Default: .spec.template.spec.containers[0]
  pollingInterval:  30                               # Optional. Default: 30 seconds
  cooldownPeriod:   300                              # Optional. Default: 300 seconds
  idleReplicaCount: 0                                # Optional. Default: ignored, must be less than minReplicaCount 
  minReplicaCount:  1                                # Optional. Default: 0
  maxReplicaCount:  100                              # Optional. Default: 100
  fallback:                                          # Optional. Section to specify fallback options
    failureThreshold: 3                              # Mandatory if fallback section is included
    replicas: 6                                      # Mandatory if fallback section is included
  advanced:                                          # Optional. Section to specify advanced options
    restoreToOriginalReplicaCount: true/false        # Optional. Default: false
    horizontalPodAutoscalerConfig:                   # Optional. Section to specify HPA related options
      name: {name-of-hpa-resource}                   # Optional. Default: keda-hpa-{scaled-object-name}
      behavior:                                      # Optional. Use to modify HPA's scaling behavior
        scaleDown:
          stabilizationWindowSeconds: 300
          policies:
          - type: Percent
            value: 100
            periodSeconds: 15
  triggers:
  # {list of triggers to activate scaling of the target resource}

 

Demo

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

Prometheus & KEDA

CRD

部署一个Web应用,使用Prometheus监控Web应用http请求指标。为寻求演示效果,此处部署了一个有点击,互动的Demo APP,

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

CRD

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

CRD

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

CRD

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

CRD

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

CRD

CRD

现在并发访问Web App:

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

CRD

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

CRD

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

CRD

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

CRD

Deployment开始缩容:

CRD

Kafka & KEDA

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

CRD

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

CRD

选择Kafka,进行安装

CRD

CRD

CRD

CRD

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

CRDCRD

创建Kafka Producer服务:

CRD

CRD

向主题发送订单:

CRD

CRD

创建Consumer服务:

CRD

CRD

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

CRD

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

 

apiVersion: keda.k8s.io/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-scaledobject
  namespace: default
  labels:
    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: 5
  minReplicaCount: 0   #Optional Default 0
  maxReplicaCount: 10  #Optional Default 100
  triggers:
  - type: kafka
    metadata:
      # Required
      BootstrapeServers: radondb-kafka-kafka-external-bootstrap.demo:9092 # Kafka bootstrap server host and port
      consumerGroup: order-shipper  # Make sure that this consumer group name is the same one as the one that is consuming topics
      topic: test
      lagThreshold: "10" # Optional. How much the stream is lagging on the current consumer group

 

创建自定义伸缩:

CRD

CRD

CRD

CRD

CRD

CRD

CRD

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

CRD

CRD

CRD

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

CRD

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

CRD






审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分