【Knative系列】理解 Knative Serving扩缩容系统的设计

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

  • Knative Serving 扩缩容系统的组件;
  • 涉及的API;
  • 扩缩容和冷启动时的 控制流和数据流的一些细节;

组件

Knative Serving 是 Knative 系统的核心,而理解 Knative Serving 系统内的组件能更容易了理解 Knative Serving 系统的实现:
了解其中的控制流和数据流的走向,了解其在扩缩容过程中的作用。因篇幅有限,这里只对组件进行简要描述,后续会针对每个组件进行详细的单独讲解。

1. queue-proxy

queue-proxy 是 一个伴随着用户容器运行的 Sidecar 容器,跟用户容器运行在同一个 Pod 中。每个请求到达业务容器之前都会经过 queue-proxy 容器,
这也是它问什么叫 proxy 的原因。

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

2. Autoscaler

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

  • PodAutoscaler reconciler
  • Collector
  • Decider

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

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

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

want = concurrencyInSystem/targetConcurrencyPerInstance

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

3. Activator

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

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

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

API

PodAutoscaler (PA,KPA)

API: podautoscalers.autoscaling.internal.knative.dev

PodAutoscaler 是对扩缩容的一个抽象,简写是 KPA 或 PA ,每个 revision
会对应生成一个 PodAutoscaler
可通过下面的指令查看

kubectl get kpa -n xxx

ServerlessServices (SKS)

API: serverlessservices.networking.internal.knative.dev

ServerlessServicesKPA 产生的,一个 KPA 生成一个 SKSSKS 是对 k8s service 之上的一个抽象,
主要是用来控制数据流是直接流向服务 revision(实例数不为零) 还是经过 Activator(实例数为0)。

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

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

public service 是不受 k8s 管控的,它没有 label selector,不会像 private service 一样 自动生成 endpoints。public service 对应的 endpoints
由 Knative SKS reconciler 来控制。

SKS 有两种模式:proxyserve

  • serve 模式下 public service 后端 endpoints 跟 private service一样, 所有流量都会直接指向 revision 对应的 pod。
  • proxy 模式下 public service 后端 endpoints 指向的是 系统中 Activator 对应的 pod,所有流量都会流经 Activator

数据流

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

1. 稳定状态下的扩缩容

scale-up-down.png

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

  1. 请求通过 ingress 路由到 public service ,此时 public service 对应的 endpoints 是 revision 对应的 pod
  2. Autoscaler 会定期通过 queue-proxy 获取 revision 活跃实例的指标,并不断调整 revision 实例。
    请求打到系统时, Autoscaler 会根据当前最新的请求指标确定扩缩容比例。
  3. SKS 模式是 serve, 它会监控 private service 的状态,保持 public service 的 endpoints 与 private service 一致 。

2. 缩容到零

scale-to-0.png

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

  1. AutoScaler 通过 queue-proxy 获取 revision 实例的请求指标
  2. 一旦系统中某个 revision 不再接收到请求(此时 Activatorqueue-proxy 收到的请求数都为 0)
  3. AutoScaler 会通过 Decider 确定出当前所需的实例数为 0,通过 PodAutoscaler 修改 revision 对应 Deployment 的 实例数
  4. 在系统删掉 revision 最后一个 Pod 之前,会先将 Activator 加到 数据流路径中(请求先到 Activator)。Autoscaler 触发 SKS 变为 proxy 模式,此时 SKSpublic service 后端的endpoints 变为 Activator 的IP,所有的流量都直接导到 Activator
  5. 此时,如果在冷却窗口时间内依然没有流量进来,那么最后一个 Pod 才会真正缩容到零。

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

scale-from-0.png

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

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

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

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

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

本文作者: zhaojizhuang
本文链接https://chumper.cn/2020/09/30/knative-autoscalling/
版权声明: 本博客所有文章除特别声明外,均采用 [CC BY-NC-SA 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/) 许可协议。转载请注明出处!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350