Bootstrap

【Knative系列】一文读懂 Knative Serving扩缩容的原理

本文主要讲解 Knative Serving扩缩容系统的设计原理及实现细节,主要从以下三个方面进行讲解:

  • Knative Serving 扩缩容系统的组件;

  • 涉及的API;

  • 扩缩容和冷启动时的 控制流和数据流的一些细节;

组件

Knative Serving 是 Knative 系统的核心,而理解 Knative Serving 系统内的组件能更容易了理解 Knative Serving 系统的实现:

了解其中的控制流和数据流的走向,了解其在扩缩容过程中的作用。因篇幅有限,这里只对组件进行简要描述,后续会针对每个组件进行详细的单独讲解。

1. queue-proxy

 是 一个伴随着用户容器运行的 Sidecar 容器,跟用户容器运行在同一个 Pod 中。每个请求到达业务容器之前都会经过  容器,

这也是它问什么叫  的原因。

 的主要作用是统计和限制到达业务容器的请求并发量,当对一个 Revision 设置了并发量之后(比如设置了5), 会确保不会同时有超过5个请求打到业务容器。当有超过5个请求到来时,会先把请求暂存在自己的队列  里,(这也是为什么名字里有个 queue的缘故)。 同时会统计进来的请求量,同时会通过指定端口提供平均并发量和 rps(每秒请求量)的查询。

2. Autoscaler

 是 Knative Serving 系统中一个重要的 pod,它由三部分组成:

  • PodAutoscaler reconciler

  • Collector

  • Decider

 会监测 (KPA)的变更,然后交由  和  处理

 主要负责从应用的  那里收集指标,  会收集每个实例的指标,然后汇总得到整个系统的指标。为了实现扩缩容,会搜集所有应用实例的样本,并将收集到的样本反映到整个集群。

 得到指标之后,来决定多少个Pod 被扩容出来。简单的计算公式如下:

want = concurrencyInSystem/targetConcurrencyPerInstance

另外,扩缩容的量也会受到  中最大最小实例数的限制。同时  还会计算当前系统中剩余多少突发请求容量(可扩缩容多少实例)进来决定 请求是否走  转发。

3. Activator

 是整个系统中所用应用共享的一个组件,是可以扩缩容的,主要目的是缓存请求并给 主动上报请求指标

 主要作用在从零启动和缩容到零的过程,能根据请求量来对请求进行负载均衡。当  缩容到零之后,请求先经过  而不是直接到 。 当请求到达时, 会缓存这这些请求,同时携带请求指标(请求并发数)去触发 扩容实例,当实例 ready后, 才会将请求从缓存中取出来转发出去。同时为了避免后端的实例过载, 还会充当一个负载均衡器的作用,根据请求量决定转发到哪个实例(通过将请求分发到后端所有的Pod上,而不是他们超过设置的负载并发量)。 Knative Serving 会根据不同的情况来决定是否让请求经过 ,当一个应用系统中有足够多的pod实例时, 将不再担任代理转发角色,请求会直接打到  来降低网络性能开销。

跟  不同, 是通过 websocket 主动上报指标给 ,这种设计当然是为了应用实例尽可能快的冷启动。 是被动的拉取:去 指定端口拉取指标。

API

PodAutoscaler (PA,KPA)

API: 

 是对扩缩容的一个抽象,简写是 KPA 或 PA ,每个 

会对应生成一个 。

可通过下面的指令查看

kubectl get kpa -n xxx

ServerlessServices (SKS)

API: 

 是  产生的,一个  生成一个 , 是对 k8s service 之上的一个抽象,

主要是用来控制数据流是直接流向服务 (实例数不为零) 还是经过 (实例数为0)。

对于每个 ,会对应生成两个k8s service ,一个,一个 .

 是标准的 k8s service,通过label selector 来筛选对应的deploy 产生的pod,即 svc 对应的 endpoints 由 k8s 自动管控。

 是不受 k8s 管控的,它没有 label selector,不会像  一样 自动生成 endpoints。 对应的 endpoints

由 Knative  来控制。

 有两种模式: 和 

  •  模式下  后端 endpoints 跟 一样, 所有流量都会直接指向  对应的 pod。

  •  模式下  后端 endpoints 指向的是 系统中  对应的 pod,所有流量都会流经 。

数据流

下面看几种情况下的数据流向,加深对Knative 扩缩容系统机制的理解。

1. 稳定状态下的扩缩容

scale-up-down.png

稳定状态下的工作流程如下:

请求通过  路由到  ,此时  对应的 endpoints 是 revision 对应的 pod

 会定期通过  获取  活跃实例的指标,并不断调整 revision 实例。

请求打到系统时,  会根据当前最新的请求指标确定扩缩容比例。

 模式是 , 它会监控  的状态,保持  的 endpoints 与  一致 。

2. 缩容到零

scale-to-0.png

缩容到零过程的工作流程如下:

3. 冷启动(从零开始扩容)

scale-from-0.png

冷启动过程的工作流程如下:

当  缩容到零之后,此时如果有请求进来,则系统需要扩容。因为  在  模式,流量会直接请求到  。 会统计请求量并将 指标主动上报到 , 同时  会缓存请求,并 watch  的 , 直到  对应的endpoints产生。

 收到  发送的指标后,会立即启动扩容的逻辑。这个过程的得出的结论是至少一个Pod要被创造出来, 会修改  对应  的副本数为为N(N>0), 同时会将  的状态置为  模式,流量会直接到导到  对应的 pod上。

 最终会监测到  对应的endpoints的产生,并对 endpoints 进行健康检查。健康检查通过后, 会将之前缓存的请求转发到

健康的实例上。

最终  完成了冷启动(从零扩容)。

本文作者: zhaojizhuang

本文链接: 

版权声明: 本博客所有文章除特别声明外,均采用 [CC BY-NC-SA 3.0]() 许可协议。转载请注明出处!