简介
当我们构建弹性和可扩展的应用程序时,自动化的扩缩容是非常重要的。在这篇博客中,我将介绍如何使用 KEDA(Kubernetes Event-driven Autoscaling)实现基于 QPS(每秒请求量)的 Pod 自动扩缩容。
KEDA 是一个用于在 Kubernetes 集群中根据事件触发自动扩缩容的工具。通过结合 KEDA 与 Prometheus 等监控系统,我们可以利用 Kubernetes 的弹性特性,在请求量高峰期自动扩容 Pod,在请求量下降时自动缩小 Pod 数量,以优化资源利用并确保应用程序的稳定性。
在本文中,我将向你展示如何配置 KEDA 来监控应用程序的 QPS指标,并根据预设的阈值自动调整 Pod 数量。我将介绍如何设置 KEDA 的扩缩容触发器,如何定义 QPS 阈值和缩放规则。
部署 KEDA
KEDA 官网有比较详细的部署文档:
这里推荐使用文档中的 Helm 部署方式:
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda --namespace keda --create-namespace
在生产环境中,我们的 Kubernetes 集群大部分都是在公有云上,以 ACK 为例,阿里云提供了更为简单的部署方式:
在 ACK 的应用市场可以直接在 Web UI 上快捷的部署为 ACK 定制的 KEDA:
参考上述文档即可快速完成 KEDA 在 Kubernetes 中的部署。
数据采集
既然要基于 QPS 来进行扩缩容,那我们首先得能取到 QPS 相关的数据,这个数据怎么取?
我这里就以覆盖面最广的 Java Spring Boot 应用为例,Spring boot 本身有一个监控模块,在 Spring 官网也有介绍:
集成好 Actuator 之后,你的 Spring Boot 应用将会暴露一个 /actuator/prometheus
接口,该接口提供 Prometheus metrics 格式的详细监控指标数据,包括不限于 JVM、QPS 等常用指标。
有了数据源之后,我们就要将数据采集到 Prometheus 中。
由于我这里使用的是 ACK,所以我是直接使用 ACK 运维管理中 Prometheus 监控:
对于自建的 Kubernetes 集群,推荐使用 Prometheus Operator 的方式部署 Prometheus。
通过上述两种方式部署的 Prometheus 都支持通过自动发现采集目标,要将 Actuator 暴露的数据采集到 Prometheus,只需要在你的应用 Pod manifest 中添加上类似如下注解:
metadata:
annotations:
prometheus.io/path: /actuator/prometheus # 采集指标路径
prometheus.io/port: "19999" # ACTUATOR 暴露的端口
prometheus.io/scrape: "true" # 是否采集
如果配置正确,你将能使用 Grafana 通过如下 Promql 查询到指定应用的 QPS 数据:
sum(rate(http_server_requests_seconds_count{app='loverent-liquidation-api-boot'}[2m]))
创建扩缩容 CRD
KEDA 有一个 Scalers 的概念,它可以理解为触发扩缩容的数据源,我们这里的数据源就是 Prometheus 了,官网也有详细的使用文档:
KEDA 的扩缩容规则是通过 CRD 定义的,要对 Deployment 进行扩缩容,需要使用名为 ScaledObject
的 CRD 类型,我这里先给出我们生产环境扩缩容 Deployment 的 ScaledObject
定义示例:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
labels:
deploymentName: <Deployment 名字,可选>
name: <名称>
spec:
minReplicaCount: 4 # 最小副本数
maxReplicaCount: 10 # 最大副本数
scaleTargetRef:
name: <目标 Deployment 名字>
triggers:
- authenticationRef: # 如果没有开启认证,可省略此字段
name: keda-prom-creds # Prometheus 认证信息
metadata:
authModes: bearer # 认证类型
metricName: http_server_requests_seconds_count # 指标名
query: sum(rate(http_server_requests_seconds_count{app='<应用名>'}[2m])) # promql
serverAddress: http://cn-shanghai-intranet.arms.aliyuncs.com:9090/api/v1/prometheus/xx/xx/xxx/cn-shanghai # Promtheus 服务地址
threshold: "60"
type: prometheus # 类型
以上定义所表达的含义即:
- 对目标 Deployment 创建了一个 ScaledObject 对象;
- 目标 Deployment 最小副本数为 4,自动扩容最大副本数不能超过 10;
- 基于 Promtheus Promql 查询出来的数据进行扩缩容;
- 如果 QPS 大于 60,则执行扩容操作,小于 60,则执行缩容操作;
要注意的是 threshold
这个字段,它表示触发扩缩容的阈值,默认它为 AverageValue 类型(平均值类型,和 HPA 中的 Value 类型相同)。
比如此时 query 的结果是 320,那么 KEDA 将会使目标 Deployment 副本数趋于 round(320/60)
,也就是 6。
HPA 相关文档:
上述文档基本描述了使用 KEDA 实现基于 QPS 的 Pod 扩缩容的全部流程,如果你的 Prometheus 是内网部署,并且没有开启认证,那么参考上述文档也应该能自己实现了。
如果你的 Prometheus 开启了认证,以 Bearer token 认证为例,你还需要配置如下两个资源:
- keda-prom-secret
apiVersion: v1
data:
bearerToken: MTIzNDU2 # 123456,注意 Secret value 需要使用 base64 进行编码
kind: Secret
metadata:
name: keda-prom-secret
type: Opaque
- keda-prom-creds
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: keda-prom-creds
spec:
secretTargetRef:
- key: bearerToken
name: keda-prom-secret
parameter: bearerToken
然后如上 ScaleObject
中在 trigger 中添加上认证信息的关联字段即可:
- authenticationRef:
name: keda-prom-creds
评论区