KEDA官网 https://keda.sh/

参考文档https://sysdig.com/blog/kubernetes-hpa-prometheus/ Keda 是一个开源项目,它简化了 Kubernetes HPA 的 Prometheus 指标的使用。

官方提供了helm部署,一键创建比较方便

helm repo add kedacore https://kedacore.github.io/charts
helm repo update
kubectl create namespace keda
helm install keda kedacore/keda --namespace keda

直接执行命令,创建一个新的命名空间给keda,然后使用helm部署

持续观察直到running状态后正常,在国内用helm拉仓库可能因为网络问题镜像和chart拉取不到,只能配代理,这里提供我之前下载好的tgz包keda-2.14.0.tgz

keda的镜像在国内也下载不下来,这里我将三个镜像打包,下载不了的可以本地下载手动将镜像load到docker,然后推到本地仓库就行keda.tar

helm install keda keda-2.14.0.tgz --namespace keda

然后用命令来查看pod部署和运行情况

状态全部running后即可

"当你为一个 ScaledObject 设定 Prometheus 触发器时,你定义了一个 Prometheus 端点和一个 Prometheus 查询。Keda 使用这些信息来查询你的 Prometheus 服务器并在 Kubernetes 外部指标 API 中创建一个指标。一旦你创建了 ScaledObject,Keda 自动为该对象创建 Kubernetes HPA(Horizontal Pod Autoscaler)。"

这是官方的解释,我们在安装好keda插件后会获得keda的crd,每个CRD都扩展了Kubernetes API,允许创建和管理与KEDA功能相关的特定资源。这些资源允许用户定义如何根据事件或指标来自动缩放部署和作业。

cloudeventsources.eventing.keda.sh: 用于定义将云事件源纳入KEDA事件驱动自动扩缩的配置。这些事件源可以是任意系统,只要它们能发送遵循CloudEvents规范的事件。

clustertriggerauthentications.keda.sh: 用于全局定义访问外部系统(如消息队列服务、数据库等)的认证方式。这使得多个ScaledObject或ScaledJob能够在集群范围内重用相同的认证信息,而不必在每个自动扩缩的资源中重复定义。

scaledjobs.keda.sh: 用于定义基于事件的作业自动扩缩。与ScaledObject不同,这些不是持续运行的服务,而是一次性或周期性的任务(比如批处理作业),这些任务可以根据定义的触发器来自动启动。

scaledobjects.keda.sh: 用于定义如何自动扩缩Kubernetes部署或其他可扩缩的工作负载。通过定义触发器(如消息队列的长度、CPU/Memory使用率等),当触发器指定的条件被满足时,ScaledObject会指导KEDA自动增加或减少副本的数量。

triggerauthentications.keda.sh: 类似于ClusterTriggerAuthentication,但它是针对单个ScaledObject或ScaledJob指定认证信息。它允许在单个自动扩缩资源的范围内定义和引用认证机制。

有了这些crd就可以创建ScaledObject来自动扩创建HPA,这里举个例子

apiVersion: apps/v1 #创建一个nginx的pod,并且暴露自己的9113端口给nginx-exporter数据
kind: Deployment
metadata:
  name: nginx-with-exporter
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-with-exporter
  template:
    metadata:
      labels:
        app: nginx-with-exporter
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
      - name: nginx-exporter
        image: nginx/nginx-prometheus-exporter:latest
        args: ["-nginx.scrape-uri", "http://localhost/stub_status"]
        ports:
        - containerPort: 9113
---
apiVersion: v1 #nginx的svc,暴露9113到集群
kind: Service
metadata:
  name: nginx-exporter-service
  labels:
    app: nginx-with-exporter
spec:
  selector:
    app: nginx-with-exporter
  ports:
    - name: nginx-exporter-port
      protocol: TCP
      port: 9113
      targetPort: 9113
---
apiVersion: monitoring.coreos.com/v1 #prometheus配置自动发现
kind: ServiceMonitor
metadata:
  name: nginx-exporter-sm  
  labels:
    team: frontend
spec:
  selector:
    matchLabels:
      app: nginx-with-exporter
  namespaceSelector:
    matchNames:
    - default
  endpoints:
  - port: nginx-exporter-port
    interval: 30s
    path: /metrics 

首先创建一个deploy和对应的svc,同时创建prometheus自动发现规则将数据加入到监控

然后创建keda的ScaledObject

---
apiVersion: keda.sh/v1alpha1 #keda的版本
kind: ScaledObject  #keda的资源对象
metadata:
  name: nginx-exporter-scaledobject  #自定义的名字
  namespace: default #命名空间
spec: 
  scaleTargetRef:
    name: nginx-with-exporter #deploy的名字
  pollingInterval: 30 # 检查指标的频率,以秒为单位
  cooldownPeriod:  300 # 扩缩容操作之间的冷却时间,以秒为单位
  minReplicaCount: 1 # 最小副本数
  maxReplicaCount: 2 # 最大副本数
  triggers:
  - type: prometheus #通过prometheus获取指标
    metadata:
      serverAddress: http://prometheus-k8s.monitoring.svc.cluster.local:9090   #prometheus的地址
      metricName: go_memstats_stack_inuse_bytes 指标的名字
      threshold: "50000" #触发扩容的条件
      query: |
        sum(rate(go_memstats_stack_inuse_bytes{namespace="default", pod=~"nginx-with-exporter-.*"}[2m]))  #promQL查询语句,通过这个语句查询 Golang 程序栈内存使用情况,如果值高于上面设定的50000则触发扩容,这里故意设置了一个会触发扩容的指标来测试,根据自己需求替换promQL即可

创建后get ScaledObject查看keda的规则可以看到已经正常显示

然后get hpa发现keda已经自动创建出对应的hpa

去prometheus页面使用同样的promQL查询可以看到值是一样的我设置的是到50000会触发扩容,但是这个值目前只有1456,为了让他可以扩容我直接edit修改扩容指标为5000,在查询prometheus面板

此时值已经超过5000,按照我设置的标准应该触发扩容,查看hpa可以看到已经扩容

至于为什么hpa显示的值和prometheus中不太一样这个我也没有搞明白,可能是hpa不会自动识别到后面的小数,就通过整数展示出来,实际在prometheus中的值到达预定指标就会触发扩容

把值改回50000稍等一会就可以看到已经被缩容了一个pod

之后就可以通过prometheus的自定义指标来按照需求设置scaledobject,通过keda自动创建hpa来横向扩缩容了