基于流量请求数实现服务自动扩缩容

Knative on ASM中提供开箱即用、基于流量请求的自动扩缩容KPA(Knative Pod Autoscaler)功能。当您遇到因业务流量波动导致的服务性能不稳定或资源浪费问题时,可以基于流量请求数实现服务自动扩缩容。通过监控和分析实时流量数据动态调整服务实例数,既能保障高峰期的服务质量和用户体验,又能有效节约闲置资源,在降低成本的同时提高系统整体效能。

前提条件

已使用Knative on ASM创建Knative服务。具体操作,请参见使用Knative on ASM部署Serverless应用

说明

本示例以默认域名example.com为例为您演示功能。如需使用自定义域名, 请参见在Knative on ASM中使用自定义域名

自动扩缩容介绍

Knative Serving为每个Pod注入QUEUE代理容器(queue-proxy)。该容器负责向Autoscaler报告业务容器的并发指标。接收到这些指标之后,Autoscaler会根据并发请求数及缩放算法,调整Deployment的Pod数量,从而实现自动扩缩容。

扩缩容

并发数和QPS

并发数指同一时刻Pod的接收的请求数;QPS指Pod每秒响应的请求数,即最大吞吐能力。

并发数的增加并不一定会导致QPS增加。应用在访问压力较大的情况下,如果并发数增加,可能导致系统超负荷工作,CPU、内存等其他消耗导致系统性能下降,从而导致响应延迟,QPS反而会下降。

算法

Knative Pod Autoscaler(KPA)基于每个Pod的平均请求数(或并发数)进行自动扩缩容,Knative默认使用基于并发数的自动弹性,每个Pod的最大并发数为100。此外,Knative还提供了目标使用率(target-utilization-percentage)的概念,用于指定自动扩缩容的目标使用率。

基于并发数弹性为例,Pod数计算方式如为:Pod数=并发请求总数/(Pod最大并发数*目标使用率)

例如,如果服务中Pod最大并发数设置为10,目标使用率设置为0.7,此时如果接收到了100个并发请求,则Autoscaler就会创建15个Pod(即100/(0.7*10)≈15)。

KPA基于每个Pod的平均请求数(或并发数)来进行自动扩缩容,并结合了Stable稳定模式和Panic恐慌模式两个概念,以实现精细化的弹性。

  • Stable稳定模式

    在稳定模式中,KPA会在默认的稳定窗口期(默认为60秒)内计算Pod的平均并发数。根据这个平均并发数,KPA会调整Pod的数量,以保持稳定的负载水平。

  • Panic恐慌模式

    在恐慌模式中,KPA会在恐慌窗口期(默认为6秒)内计算Pod的平均并发数。恐慌窗口期=稳定窗口期*panic-window-percentage(panic-window-percentage取值是0~1,默认是0.1)。当请求突然增加导致当前Pod的使用率超过恐慌窗口百分比时,KPA会快速增加Pod的数量以满足负载需求。

在KPA中,弹性生效的判断是基于恐慌模式下计算得出的Pod数量是否超过恐慌阈值(PanicThreshold)。恐慌阈值=panic-threshold-percentage/100,panic-threshold-percentage默认为200,即恐慌阈值默认为2。

综上所述,如果在恐慌模式下计算得出的Pod数量大于或等于当前Ready Pod数量的两倍,那么KPA将使用恐慌模式下计算得出的Pod数量进行弹性生效;否则,将使用稳定模式下计算得出的Pod数量。

KPA配置介绍

KPA的全局默认配置位于kantive-serving命名空间下ConfigMap的config-autoscaler中。您可以执行以下命令,查看config-autoscaler的默认配置。下文介绍重点参数。

kubectl -n knative-serving get cm config-autoscaler -o yaml

预期输出(已忽略代码中的注释部分):

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-autoscaler
  namespace: knative-serving
data:
  _example:
    container-concurrency-target-default: "100"
    container-concurrency-target-percentage: "0.7"
    enable-scale-to-zero: "true"
    max-scale-up-rate: "1000"
    max-scale-down-rate: "2"
    panic-window-percentage: "10"
    panic-threshold-percentage: "200"
    scale-to-zero-grace-period: "30s"
    scale-to-zero-pod-retention-period: "0s"
    stable-window: "60s"
    target-burst-capacity: "200"
    requests-per-second-target-default: "200"

_example字段下展示的参数配置为默认值。如需修改,请将_example字段下相应的字段复制到data字段下进行修改。

说明

对config-autoscaler所做的修改对全局的Knative service生效。如需单独对某个Knative service进行修改,您可以通过Annotation注解的方式。具体操作,请参考下文场景一:设置并发请求数实现自动扩缩容场景二:设置扩缩容边界实现自动扩缩容

为KPA配置缩容至0

字段

描述

示例值

scale-to-zero-grace-period

在缩容至0之前,inactive revision保留的运行时间(最小时间为30s)。

30s

stable-window

Stable模式运行时,Autoscaler在稳定窗口期下平均并发数下的操作。此外, stable-window也可以在Revision注释中配置,例如autoscaling.knative.dev/window: 60s

60s

enable-scale-to-zero

设置字段为true

true

配置Autoscaler的并发数

字段

描述

示例值

container-concurrency-target-default

定义在指定时间(软限制)需要多少并发请求,为Knative中Autoscaler的推荐配置。ConfigMap中默认配置的并发target为100。

此外, 此字段值可以通过Revision中的autoscaling.knative.dev/target注释进行修改,例如autoscaling.knative.dev/target: 50

100

containerConcurrency

限制在给定时间内允许并发请求的数量。

  • 1:确保一次只有1个请求由Revision给定的容器实例处理。

  • 2-N:请求的并发值限制为2或更多。

  • 0:不作限制,由系统自身决定。

0

container-concurrency-target-percentage

并发百分比,即并发因子,会直接参与扩缩容并发数计算。实际扩缩容并发数=target(或者containerConcurrency)*container-concurrency-target-percentage。例如,如果并发数target或者containerConcurrency设置值为100,并发因子container-concurrency-target-percentage为0.7,那么实际担当并发数达到70(100*0.7)时就会触发扩容操作。

0.7

配置扩缩容边界

通过minScale和maxScale,可以配置应用程序提供服务的最小和最大Pod数量,以控制服务冷启动或者控制计算成本。

说明
  • 如果未设置minScale注释,Pod将缩放至0。

  • 如果未设置maxScale注释,创建的Pod数量将没有上限。

  • 如果设置config-autoscaler的enable-scale-to-zero为false,Pod将缩放至1。

minScale和maxScale可以在Revision模板中按照以下方式进行配置。

spec:
  template:
    metadata:
      autoscaling.knative.dev/minScale: "2"
      autoscaling.knative.dev/maxScale: "10"

场景一:设置并发请求数实现自动扩缩容

本场景将在集群中部署autoscale-go应用,通过设置并发请求数,基于KPA实现自动扩缩容。

说明

关于如何使用Knative on ASM创建Knative服务,请参见使用Knative on ASM部署Serverless应用

  1. 创建autoscale-go.yaml,设置并发目标数为10,即autoscaling.knative.dev/target取值为10。

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: autoscale-go
      namespace: default
    spec:
      template:
        metadata:
          labels:
            app: autoscale-go
          annotations:
            autoscaling.knative.dev/target: "10"
        spec:
          containers:
            - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/autoscale-go:0.1
  2. 使用kubectl连接到集群,在命令行执行以下命令部署autoscale-go。

    kubectl apply -f autoscale-go.yaml
  3. 登录ASM控制台,单击目标实例名称,然后选择ASM网关 > 入口网关,在服务地址区域,获取IP。

  4. 使用Hey压测工具,执行30s内保持50个并发请求。

    关于Hey压测工具的安装步骤和详细信息,请参见Hey

    说明

    请将xxx.xxx.xxx.xxx替换为您实际的访问网关地址。关于如何获取访问网关地址的具体操作,请参见获取访问网关地址

    hey -z 30s -c 50   -host "autoscale-go.default.example.com"   "http://xxx.xxx.xxx.xxx?sleep=100&prime=10000&bloat=5"

    预期输出:预期输出

    预期输出表明,整个过程中共扩容7个Pod。这是由于当容器并发量大于目标并发量的一定百分比后(默认为70%),Knative会提前创建更多的Pod备用,避免并发量进一步增加的情况下目标值被突破。

场景二:设置扩缩容边界实现自动扩缩容

扩缩容边界指应用程序提供服务的最小和最大Pod数量。本场景将在集群中部署autoscale-go应用,通过设置应用程序提供服务的最小和最大Pod数量实现自动扩缩容。

说明

关于如何使用Knative on ASM创建Knative服务,请参见使用Knative on ASM部署Serverless应用

  1. 创建autoscale-go.yaml,设置最大并发请求数为10,minScale最小保留实例数为1,maxScale最大扩容实例数为3。

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: autoscale-go
      namespace: default
    spec:
      template:
        metadata:
          labels:
            app: autoscale-go
          annotations:
            autoscaling.knative.dev/target: "10"
            autoscaling.knative.dev/minScale: "1"
            autoscaling.knative.dev/maxScale: "3"
        spec:
          containers:
            - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/autoscale-go:0.1
  2. 使用kubectl连接到集群,在命令行执行以下命令部署autoscale-go。

    kubectl apply -f autoscale-go.yaml
  3. 登录ASM控制台,单击目标实例名称,然后选择ASM网关 > 入口网关,在服务地址区域,获取IP。

  4. 使用Hey压测工具,执行30s内保持50个并发请求。

    关于Hey压测工具的安装步骤和详细信息,请参见Hey

    说明

    请将xxx.xxx.xxx.xxx替换为您实际的访问网关地址。关于如何获取访问网关地址的具体操作,请参见获取访问网关地址

    hey -z 30s -c 50   -host "autoscale-go.default.example.com"   "http://xxx.xxx.xxx.xxx?sleep=100&prime=10000&bloat=5"

    预期输出:预期输出2

    预期输出表明,整个过程中Pod最大扩容储量为3,且在无访问请求流量的情况下,Pod最小保留数量为1,即自动扩缩容符合预期。

相关文档

  • 当您需要安全地访问和管理Knative构建的微服务时,可以使用ASM网关来实现HTTPS访问,通过对服务端点进行加密传输配置保护服务间的通信,提高整体架构的安全性和可靠性。具体操作,请参见使用ASM网关实现HTTPS访问Knative服务

  • 当您在进行应用迭代升级时面临新版本兼容性和稳定性挑战时,可以在Knative on ASM中基于流量灰度发布服务。具体操作,请参见在Knative on ASM中基于流量灰度发布服务

  • 您可以在Knative Service中设置CPU指标阈值,满足在突发高负载的场景下,自动扩缩容资源的诉求。具体操作,请参见在Knative中使用HPA