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注释中配置,例如 | 60s |
enable-scale-to-zero | 设置字段为 | true |
配置Autoscaler的并发数
字段 | 描述 | 示例值 |
container-concurrency-target-default | 定义在指定时间(软限制)需要多少并发请求,为Knative中Autoscaler的推荐配置。ConfigMap中默认配置的并发target为100。 此外, 此字段值可以通过Revision中的 | 100 |
containerConcurrency | 限制在给定时间内允许并发请求的数量。
| 0 |
container-concurrency-target-percentage | 并发百分比,即并发因子,会直接参与扩缩容并发数计算。实际扩缩容并发数=target(或者containerConcurrency)*container-concurrency-target-percentage。例如,如果并发数target或者containerConcurrency设置值为 | 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应用。
创建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
使用kubectl连接到集群,在命令行执行以下命令部署autoscale-go。
kubectl apply -f autoscale-go.yaml
登录ASM控制台,单击目标实例名称,然后选择 ,在服务地址区域,获取IP。
使用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应用。
创建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
使用kubectl连接到集群,在命令行执行以下命令部署autoscale-go。
kubectl apply -f autoscale-go.yaml
登录ASM控制台,单击目标实例名称,然后选择 ,在服务地址区域,获取IP。
使用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"
预期输出:
预期输出表明,整个过程中Pod最大扩容储量为3,且在无访问请求流量的情况下,Pod最小保留数量为1,即自动扩缩容符合预期。
相关文档
当您需要安全地访问和管理Knative构建的微服务时,可以使用ASM网关来实现HTTPS访问,通过对服务端点进行加密传输配置保护服务间的通信,提高整体架构的安全性和可靠性。具体操作,请参见使用ASM网关实现HTTPS访问Knative服务。
当您在进行应用迭代升级时面临新版本兼容性和稳定性挑战时,可以在Knative on ASM中基于流量灰度发布服务。具体操作,请参见在Knative on ASM中基于流量灰度发布服务。
您可以在Knative Service中设置CPU指标阈值,满足在突发高负载的场景下,自动扩缩容资源的诉求。具体操作,请参见在Knative中使用HPA。