【Knative系列】看完这篇还不懂 Knative Serving,你来打我~(史上最详细)

本文主要讲解 Knative serving 系统及组件:

发展历程

Knative 是谷歌开源的 serverless 架构方案,旨在提供一套简单易用的 serverless 方案,把 serverless 标准化。目前参与的公司主要是 Google、Pivotal、IBM、Red Hat,2018年7月24日才刚刚对外发布,当前还处于快速发展的阶段(3.4k star, 3.3k issue)。

Knative 包含 build(已被tekton取代),serving,event三个部分,本文主要介绍serving。

先看下Knative的发展里历程

项目 时间 发起公司
k8s 2014年6月 Google (同年加入 微软、RedHat、IBM、Docker)
istio 2017 年6 月8 日 Google,IBM 和 Lyft
knative 2018年7月24日 Google (目前主要为 Google、Pivotal、IBM、Red Hat)

前言 有了 ”k8s,为什么还要 knative”

通常情况下 Serverless = Faas + Baas,Faas 无状态(业务逻辑),Baas 有状态(通用服务:数据库,认证,消息队列)。

既然有了 k8s (paas), 为什么还需要 Knative (Serverless),下面从四个方面来进行解释:资源利用率,弹性伸缩,按比例灰度发布,用户运维复杂性

1. 资源利用率

讲资源利用率之前先看下下面两个应用,左边应用 A 这个是典型的中长尾应用,中长尾应用就是那些每天大部分时间都没有流量或者有很少流量的应用。

想一下,如果用 paas(k8s) 来实现的话,对于应用 A,需按照资源占用的资源最高点来申请规格,也就是 4U10G, 而且 paas 最低实例数>=1, 长此以往, 当中长尾应用足够多时,资源利用率可想而知。有可能会出现 大部分边缘集群资源被预占,但是利用率却很低。

而 Knative,恰恰可以解决应用A的资源占用问题,因为 Knative 可以将实例缩容为0,并根据请求自动扩缩容,缩容到零可以大大增加集群的资源利用率,因为中长尾应用都是按需所取,不会过度空占用资源。

比较合理的是对应应用A 用 Knative(Serverless),对于应用 B 用 k8s(Paas)

2. 弹性伸缩

大家可能会想到,k8s 也有 hpa 进行扩缩容,但是 Knative 的 kpa 和 k8s 的 hpa 有很大的不同:

Knative 支持缩容到 0 和从 0 启动,反应更迅速适合流量突发场景;

K8s HPA 不支持缩容到 0 ,反应比较保守

具体比较如下

Knative KPA k8s HPA
指标类型 可以根据 请求量扩速容 只能根据 cpu memory 等指标扩缩容(或自定义指标)
01启动 可以缩容到0和冷启动 只能缩容到1(如果缩容到0,就没有实例了,流量进不来,metrics数据永远为0,此时HPA也无能为力)
指标获取方式 Knative 指标获取有两种方式,Activator 和queue-proxy, activator的metrics 是通过websocket 主动push 给Autoscaler的,反应更迅速 k8s 只能是通过prometheus 轮询获取。
反应速度 Knative 默认会 计算 60 秒窗口内的平均并发数, 也会计算 6 秒的恐慌窗口,6s内达到目标并发的 2 倍,则会进入恐慌模式。在恐慌模式下,Autoscaler 在更短、更敏感的紧急窗口上工作 而且 HPA 本身设计比较保守,有一个稳定期(默认5min)默认在5min内没有重新扩缩容的情况下,才会触发扩缩容。当大流量突发过来时,如果正处在5min内的HPA稳定期,这个时候根据HPA的策略,会导致无法扩容。

3. 按比例灰度发布

设想一下,假如通过 k8s来进行灰度发布怎么做,只能是通过两个Deployment和两个service,如果灰度升级的话只能通过修改两个 Deployment 的rs,一个逐渐增加,一个逐渐减少,如果想要按照百分比灰度,只能在外部负载均衡做文章,所以要想 Kubernetes 原生实现,至少需要一个按流量分发的网关,两个 service,两个 deployment ,两个 ingress , hpa,prometheus 等,实现起来相当复杂。

使用 Knative 就可以很简单的实现,只需一个 ksvc 即可

4. 用户运维复杂性

使用 Knative 免运维,低成本:用户只关心业务逻辑,由工具和云去管理资源,复杂性由平台去做:容器镜像构建,Pod 的管控,服务的发布,相关的运维等。

k8s 本质上还是基础设施的抽象,对应pod的管控,服务的发布,镜像的构建等等需要上层的包装。

1. 相关概念介绍

资源介绍: knative 资源

推荐一个工具 kubectl tree 可以查看k8s资源之间的引用关系

1. Service(ksvc)

ksvc 是 Knative 中 最顶层的 CR 资源,用于定义 Knative 应用 ,包含镜像以及 traffic 百分比等等(本例配了 两个版本,流量百分比是 10%,90%), 可以接管 route 和 configuration 的配置

k_1.png

2. Configuration

configuration 是 Knative 应用的最新配置,也就是应用目前期望的状态。configuration 更改会产生快照 revision

k_2.png

3. Revision

revision 是 Knative 应用的快照,Knative 的设计理念中 revision 是不可更改的,可以看做是 git 的 历史 commit 记录

k_3.png

4. Route

route 是 Knative 蓝绿发布,金丝雀发布的关键,用于声明不同版本之间流量的百分比。

k_4.png

5. Ingress(kingress)

Knative 的流量入口网关 是通过 kingress 抽象的。详情可以看第二节 Knative 网关

k_5.png

6. PodAutoScaler(kpa)

k_6.png

7. ServerlessService(sks)

k_7.png

8. k8s Service (public)

注意,此处的 k8s service 没有 label selector,说明这个 service 的后端 endpoint 不是由 k8s 自动控制的,实际上这个 svc 的后端 endpoint 是 由 knative 自己来控制的,(是取 activator 的pod ip 还是 服务真实实例的pod ip)

k_8.png

9. k8s Service (private)

private 类型 的 svc 不同于 public 类型的 svc,这个 svc 是通过label selector 来筛选后端 endpoint 的,这里后端指向的永远是 服务真实实例的 pod ip

k_9.png

2. Knative 网关

Knative 从设计之初就考虑到了其扩展性,通过抽象出来 Knative Ingress (kingress)资源来对接不同的网络扩展:AmbassadorContourGlooIstioKongKourier

这些网络插件都是基于 Envoy 这个新生的云原生服务代理,关键特性是可以基于流量百分比进行分流

感兴趣的可以研究下 https://www.servicemesher.com/envoy/intro/what_is_envoy.html

knativegate.png

3. Knative 组件

1. Queue-proxy

queue-proxy.png

Queue-proxy 是每个业务 pod 中都存在的 sidecar,每个发到业务pod的请求都会先经过 queue-proxy

queue-proxy 的主要作用是 收集和限制 业务应用的并发量,比如当一个 revision 设定了并发量为 5 ,那么 queue-proxy 会保证每次到达业务容器的请求数不会大于 5. 如果多于 5 个请求到达,queue-proxy 会将请求暂存在本地队列中。

几个端口表示如下:

• 8012, queue-proxy 代理的http端口,流量的入口都会到 8012
• 8013, http2 端口,用于grpc流量的转发
• 8022, queue-proxy 管理端口,如健康检查
• 9090, queue-proxy的监控端口,暴露指标供 autoscaler 采集,用于kpa扩缩容
• 9091, prometheus 应用监控指标(请求数,响应时长等)
• USER_PORT, 是用户配置的容器端口,即业务实际暴露的服务端口,ksvc container port 配置的

2. Autoscaller

k_2.png

AutoScaller 主要是 Knative 的扩缩容实现,通过request指标来决定是否扩缩容实例,指标来源有两个:

• 通过获取每个 pod queue-proxy 中的指标
• Activator 通过 websocket 主动上报

扩缩容算法如下:

autoscaler 是基于每个 Pod(并发)的运行中请求的平均数量。系统的默认目标并发性为 100,但是我们为服务使用了 10。我们为服务加载了 50 个并发请求,因此自动缩放器创建了 5 个容器( 50 个并发请求/目标 10 = 5 个容器)。

算法中有两种模式,分别是 panic 和 stable 模式,一个是短时间,一个是长时间,为了解决短时间内请求突增的场景,需要快速扩容。

Stable Mode(稳定模式)

在稳定模式下,Autoscaler 根据每个pod期望的并发来调整Deployment的副本个数。根据每个pod在60秒窗口内的平均并发来计算,而不是根据现有副本个数计算,因为pod的数量增加和pod变为可服务和提供指标数据有一定时间间隔。

Panic Mode (恐慌模式)

KPA会在 60 秒的窗口内计算平均并发性,因此系统需要一分钟时间才能稳定在所需的并发性级别。但是,自动缩放器还会计算一个 6秒 的紧急窗口,如果该窗口达到目标并发性的 2 倍,它将进入紧急模式。在紧急模式下,自动缩放器在较短,更敏感的紧急窗口上运行。一旦在 60 s秒内不再满足紧急情况,autoscaler 将返回到最初的 60 秒稳定窗口。

window.png

3. Activator

activator.png

Activator 的作用:流量的负载和缓存,是Knative能缩容到 0 的关键

实例为0 时(冷启动),流量会先转发到 Activator,由 Activator 通过 websocket 主动触发 Autoscaler 扩缩容。

Activator 本身的扩缩容通过 hpa 实现

root@admin03.gyct:~# kubectl get hpa -n knative-serving
NAME        REFERENCE              TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
activator   Deployment/activator   8%/100%   1         20        1          73d

可以看到 Activator 默认最大可以扩缩容到 20

Activator 只在 冷启动阶段是 proxy 模式,当当实例足够时,autoscaler 会更新 public service 的endpoints 指向 revision对应的pod,将请求导向真正的后端,这时候处理请求过程中 activator 不在起作用

详细步骤如下:

activator2.png

冷启动时 activator 的角色

  1. Kingress 收到请求(确切的是 网关收到请求后根据kingress生成的配置做转发,如istio是virtualservice)后,将请求导至 activator
  2. activator 将请求保存在缓存中
  3. Activator 触发 autoscaller, 触发过程中其中做了两件事:
    a. Activator 携带了第2步缓存的请求信息到 autoscaler;
    b. 触发信号促使 autoscaller 立即做出扩容决定,而不是等下个扩容周期;
  4. 考虑到有请求需要处理,但是目前实例是0,autoscaller 决定扩容出一个实例,于是设置一个新的 scale 目标
  5. activator 在等待 autoscaler 和 Serving 准备工作的时候,activator 会去轮询 Serving 查看实例时候准备完毕
  6. Serving 调用k8s 生成k8s 实例(deploy,pod)
  7. 当实例可用时,Activator 将请求从缓存中 proxy 到实例
  8. Activator 中的 proxy 模块 将请求代理到实例
  9. Activator 中的 proxy 模块 同样将 response 返回到 kingress

4. 扩缩容原理

1. 正常扩缩容场景(非 0 实例)

scale1.png

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

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

2. 缩容到 0 的场景

scale-to-0.png

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

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

3. 从 0 启动的场景

scale-from-0.png

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

当 revision 缩容到零之后,此时如果有请求进来,则系统需要扩容。因为 SKS 在 proxy 模式,流量会直接请求到 Activator 。Activator 会统计请求量并将 指标主动上报到 Autoscaler, 同时 Activator 会缓存请求,并 watch SKS 的 private 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 完成了冷启动(从零扩容)。

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

推荐阅读更多精彩内容

  • 本文主要讲解 Knative Serving扩缩容系统的设计原理及实现细节,主要从以下三个方面进行讲解:Knati...
    chumper阅读 1,100评论 0 0
  • 推荐指数: 6.0 书籍主旨关键词:特权、焦点、注意力、语言联想、情景联想 观点: 1.统计学现在叫数据分析,社会...
    Jenaral阅读 5,700评论 0 5
  • 昨天,在回家的路上,坐在车里悠哉悠哉地看着三毛的《撒哈拉沙漠的故事》,我被里面的内容深深吸引住了,尽管上学时...
    夜阑晓语阅读 3,777评论 2 9
  • 一。匹配。 判断一个字符串是否符合我们制定的规则? 二…捕获 字符串中符合我们正则表达式,规则的,内容捕获到。 三...
    时修七年阅读 973评论 2 0
  • 城空了,有树长出来 我的城死了 铸起它的人,杀死它的人 不愿因为这件事而骄傲 一座城的终结 永远因为终结这件事而显...
    于十六阅读 2,847评论 6 17