侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

绿泡泡:___zze,添加备注来意

  • 累计撰写 748 篇文章
  • 累计创建 65 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

使用KEDA实现基于qps的pod扩缩容

zze
zze
2023-09-12 / 0 评论 / 0 点赞 / 339 阅读 / 5536 字

简介

当我们构建弹性和可扩展的应用程序时,自动化的扩缩容是非常重要的。在这篇博客中,我将介绍如何使用 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:
image-1694501133828

参考上述文档即可快速完成 KEDA 在 Kubernetes 中的部署。

数据采集

既然要基于 QPS 来进行扩缩容,那我们首先得能取到 QPS 相关的数据,这个数据怎么取?

我这里就以覆盖面最广的 Java Spring Boot 应用为例,Spring boot 本身有一个监控模块,在 Spring 官网也有介绍:

集成好 Actuator 之后,你的 Spring Boot 应用将会暴露一个 /actuator/prometheus 接口,该接口提供 Prometheus metrics 格式的详细监控指标数据,包括不限于 JVM、QPS 等常用指标。

有了数据源之后,我们就要将数据采集到 Prometheus 中。

由于我这里使用的是 ACK,所以我是直接使用 ACK 运维管理中 Prometheus 监控:
image-1694501146885

对于自建的 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]))

image-1694501159894

创建扩缩容 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
0

评论区