12

kubernetes pod的弹性伸缩(三)(基于事件驱动伸缩)

 3 years ago
source link: https://www.bladewan.com/2021/06/18/kubernetes_keda/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

kubernetes pod的弹性伸缩(三)(基于事件驱动伸缩)

软件 版本 keda 2.3.0 Kubernetes 1.20.7

目前在Kubernetes中做POD弹性伸缩HPA有基于CPU、memory这种资源指标实现和通过custom-metrics-apiserver和Prometheus-adapter实现的自定义业务监控指标的弹性伸缩,但这些都不是很灵活有效,基于cpu、memory实际对业务带来价值并不大,并不能很准确代表业务实际是否需要扩缩容。基于自定义业务监控指标配置起来相当繁琐。所以社区这些问题背景下开发了KEDA,基于事件的伸缩

KEDA是什么?

KEDA是红帽和微软联合开发的一个开源项目,后面贡献给了CNCF基金会,目前处于sandbox阶段,实现KEDA的目的主要为了更好和更加灵活使用HPA。

项目地址
https://github.com/kedacore/keda

文档地址
https://keda.sh/

什么是事件驱动?

举个简单例子,常见的消息队列系统,有生产者和消费者,生产者往消息队列中吐数据,消费者从消息队列中消费数据,当出现消息堆积时,此时是消费者处理不过来了,应该及时扩容消费者。这就是keda可以实现的,通过对应的接口去查看消息队列系统的情况,进行判断,调用HPA进行扩缩容。

keda能做什么?

图片来源:https://developer.ibm.com/technologies/messaging/articles/introduction-to-keda/

图片来源:https://keda.sh/docs/1.4/concepts/

KEDA 监控定义的事件源,并定期检查是否有任何事件。达到设置的阈值后,KEDA 会根据部署的复制件计数设置为 1 或 0,根据配置最小副本计数,激活或停用POD,具体取决于是否有任何事件。
通过上面两幅架构图可以看见keda和HPA是相辅相成的,keda实现的是事件收集和pod副本数0->1,1->0的调整,HPA实现1->n,n->1的POD副本调整.

keda组成

keda由两个组件组成:
keda-operator:创建维护hpa资源对象,同时激活hpa伸缩(0->1,1->0)。

keda-metrics-apiserver: 实现了hpa中external metrics,根据事件源配置返回计算结果,推动hpa进行。

keda定义的CRD对象主要有三个

  • ScaledObjects:定义事件源和资源映射以及控制的范围。
  • ScaledJobs:定义事件源和job资源映射以及控制的范围。
  • TriggerAuthentication:监控事件源的认证配置

keda部署非常简单,有三种方式

  • Helm charts
  • Operator Hub
  • YAML declarations

这里,我们直接用yaml进行,一个yaml即可搞定

kubectl apply -f https://github.com/kedacore/keda/releases/download/v2.3.0/keda-2.3.0.yaml

部署完后检查

kubectl get pod -n keda
NAME READY STATUS RESTARTS AGE
keda-metrics-apiserver-84d8fc689d-62kc2 1/1 Running 0 5h23m
keda-operator-54f95d8598-l5vjg 1/1 Running 0 5h23m

看状态是否正常,也建议看看这两个组件的log是否有报错。

接下来进行测试使用,直接使用官方github里面的例子。

RabbitMQ弹性

实现效果

图片来源:(https://jstobigdata.com/rabbitmq/direct-exchange-in-amqp-rabbitmq/)
当rabbimq队列达到设定的长度后扩容consumer副本数,当队列长度降下去后将副本数缩小为对应的配置值。

部署Rabbimq-server

helm repo add bitnami https://charts.bitnami.com/bitnami

部署rabbitmq

helm install rabbitmq --set auth.username=user --set auth.password=PASSWORD bitnami/rabbitmq

查看是否部署成功

kubectl get pod
NAME READY STATUS RESTARTS AGE
rabbitmq-0 1/1 Running 0 7h37m

部署 RabbitMQ consumer

repo里面是配置rabbimq-consumer和keda规则

git clone https://github.com/kedacore/sample-go-rabbitmq.git


cd sample-go-rabbitmq
kubectl apply -f deploy/deploy-consumer.yaml
secret/rabbitmq-consumer-secret created
deployment.apps/rabbitmq-consumer created
scaledobject.keda.sh/rabbitmq-consumer created
triggerauthentication.keda.sh/rabbitmq-consumer-trigger created

主要看看ScaledObject

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: rabbitmq-consumer
namespace: default
spec:
scaleTargetRef:
name: rabbitmq-consumer
pollingInterval: 5 # Optional. Default: 30 seconds
cooldownPeriod: 30 # Optional. Default: 300 seconds
maxReplicaCount: 30 # Optional. Default: 100
triggers:
- type: rabbitmq
metadata:
queueName: hello
queueLength: "5"
authenticationRef:
name: rabbitmq-consumer-trigger
参数 含义 pollingInterval 定时获取scaler的时间间隔,默认30s cooldownPeriod 上次active至缩容为0需要等待的时间,默认300s maxReplicaCount 最大POD副本数 minReplicaCount 最小POD副本数,默认为0 triggers.type 事件类型是keda支持的哪种,如是redis就写redis,是kafka是写kafka trigger.metadata.queueName 这个根实际事件类型有关的触发器指标了,这里定义的是rabbitmq的队列名 trigger.metadata.queueLength 触发器定义的队列长度 trigger.authenticationRef 认证关联,关联TriggerAuthentication

部署后会发现rabbitmq-consumer副本数会自动变为0,因为此时队列是空的

kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
rabbitmq-consumer 0/0 0 0 1h53m

此时get hpa也创建出来了

kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-rabbitmq-consumer Deployment/rabbitmq-consumer <unknown>/5 (avg) 1 30 0 1h

部署produce往Rabbitmq里面推数据制造拥堵

这个job将推送 300信息到 “hello” 这个队列 keda将在2分种扩容 deployment到30个

kubectl apply -f deploy/deploy-publisher-job.yaml

对应的我们也可以观察hpa和pod的扩缩容

已经在迅速扩容了

ubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-68df844cc-dclwb 1/1 Running 0 8h
rabbitmq-0 1/1 Running 0 8h
rabbitmq-consumer-5c486c869c-4pwxj 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-5wd9k 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-6zgs9 1/1 Running 0 56s
rabbitmq-consumer-5c486c869c-78lx9 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-7g4wf 1/1 Running 0 71s
rabbitmq-consumer-5c486c869c-7qhqn 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-8rj6l 1/1 Running 0 56s
rabbitmq-consumer-5c486c869c-bmjqx 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-db2ts 1/1 Running 0 71s
rabbitmq-consumer-5c486c869c-ddzhp 1/1 Running 0 56s
rabbitmq-consumer-5c486c869c-dgwn4 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-f4k8l 1/1 Running 0 87s
rabbitmq-consumer-5c486c869c-jqbhl 1/1 Running 0 87s
rabbitmq-consumer-5c486c869c-k2mdw 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-kpgc2 0/1 ContainerCreating 0 56s
rabbitmq-consumer-5c486c869c-kzlwl 0/1 ContainerCreating 0 56s
rabbitmq-consumer-5c486c869c-ls4dm 1/1 Running 0 56s
rabbitmq-consumer-5c486c869c-lvtx8 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-ngmnj 1/1 Running 0 71s
rabbitmq-consumer-5c486c869c-nxp4n 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-p27lk 1/1 Running 0 71s
rabbitmq-consumer-5c486c869c-p4d59 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-q9wdl 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-qqgdw 1/1 Running 0 56s
rabbitmq-consumer-5c486c869c-rpghb 1/1 Running 0 89s
rabbitmq-consumer-5c486c869c-sr7hd 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-sxl8t 1/1 Running 0 87s
rabbitmq-consumer-5c486c869c-vk9wp 0/1 ContainerCreating 0 56s
rabbitmq-consumer-5c486c869c-xgnbf 0/1 ContainerCreating 0 40s
rabbitmq-consumer-5c486c869c-xn76k 0/1 ContainerCreating 0 40s
rabbitmq-publish-rxjpl 0/1 Completed 0 109s

等待队列数据消费完了,等待冷却期,pod会自行销毁。

基于Prometheus自定义监控指标弹性

使用自定义HPA监控的例子测试

clone代码

git clone https://github.com/stefanprodan/k8s-prom-hpa

切换到k8s-prom-hpa目录

kubectl create namespace monitoring
kubectl create -f ./prometheus

查看prometheus

kubectl get pod -n monitoring
NAME READY STATUS RESTARTS AGE
prometheus-64bc56989f-qcs4p 1/1 Running 1 22h
kubectl get svc -n monitoring
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus NodePort 10.104.215.207 <none> 9090:31190/TCP 22h

访问prometheus
http://node_ip:31190

prometheus内prometheus-cfg.yaml 配置了自动发生规则,会自动将组件注册。

部署Podinfo应用测试custom-metric autoscale

kubectl create -f ./podinfo/podinfo-svc.yaml,./podinfo/podinfo-dep.yaml

prometheus配置了自动发现规则,在podinfo-dep.yaml里面配置了对应的规则

annotations:
prometheus.io/scrape: 'true'

所以应用一启动就能直接在prometheus-target中发现。

配置keda

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: prometheus-scaledobject
namespace: default
spec:
scaleTargetRef:
name: podinfo
pollingInterval: 5# Optional. Default: 30 seconds
cooldownPeriod: 30 # Optional. Default: 300 seconds
maxReplicaCount: 30 # Optional. Default: 100
triggers:
- type: prometheus
metadata:
serverAddress: http://192.168.0.32:31190/
metricName: http_requests_total
threshold: '10'
query: sum(rate(http_requests_total[1m]))

这里10指的是每秒10个请求,按照定义的规则metricsQuery中的时间范围1分钟,这就意味着过去1分钟内每秒如果达到10个请求则会进行扩容。

配置完后使用ab进行压力测试

使用ab进行压力测试,模拟1000个并发量

apt install apache2-utils -y

ab命令最基本的参数是-n-c

-n 执行的请求数量
-c 并发请求个数
其他参数:
-t 测试所进行的最大秒数
-p 包含了需要POST的数据的文件
-T POST数据所使用的Content-type头信息
-k 启用HTTP KeepAlive功能,即在一个HTTP会话中执行多个请求,默认时,不启用KeepAlive功能


ab -n 10000 -c 1000 http://192.168.0.32:31198/

查看是否进行弹性伸缩。

kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-68df844cc-dclwb 1/1 Running 3 3d8h
podinfo-56874dc7f8-4n9m4 0/1 Running 4 74m
podinfo-56874dc7f8-g89vr 0/1 Running 0 43s
podinfo-56874dc7f8-v2pn8 1/1 Running 4 74m
podinfo-56874dc7f8-xgrz6 0/1 ContainerCreating 0 12s
rabbitmq-0 1/1 Running 0 3d8h
rabbitmq-publish-rxjpl 0/1 Completed 0 2d23h

keda会根据实际的值计算需要弹性的副本数,保证业务可用性。

root@cka01:~# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-prometheus-scaledobject Deployment/podinfo 13/10 (avg) 1 30 3 3m3s

总的感受下来,还是非常好用的,像之前配一些业务自定义指标的HPA监控还需要配置Prometheus-adapter
配置规则,但通过keda直接可以对接Prometheus,配置对应表达式尽快。其他一些集成的事件触发器也直接使用就可以了。

keda支持的业务事件触发器

参考链接:

https://keda.sh


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK