Knative: 基于流量的灰度发布和自动弹性实践

导读

作为 Severless Framework 就离不开按需分配资源的能力,Knative 提供了基于流量的自动扩缩容能力,可以根据应用的请求量在高峰时期自动扩容实例数,当请求量减少以后自动缩容实例数,做到自动化的帮助您节省成本。此外 Knative 还提供了基于流量的灰度发布能力,可以根据流量百分比进行灰度发布。本文会从以下 4 个方面展开介绍:

  • ASK Knative 中流量请求机制
  • 基于流量的灰度发布
  • 弹性自动扩缩容
  • 示例演示


在介绍Knative 灰度发布和自动弹性前,我们先来看一下 ASK Knative 中流量请求机制。

ASK Knative 流量请求机制

在 ASK Knative 中,流量首先通过SLB网关,然后根据转发规则,将请求转发到对应服务的POD上,这里转发规则是通过Knative Ingress Controlller创建,该 controller 通过 Route 中设置的规则,最终转换成 SLB 规则。

Knative: 基于流量的灰度发布和自动弹性实践

再谈 Knative 应用生命周期


Knative Service 是直接面向开发者操作的资源对象它直接负责对Route和Configuration的管控,一个Service 分别对应一个Route和一个Configuration


Service

每次 Service 变化如果需要创建新的 Workload 就更新 Configuration,然后每次 Configuration 更更新都会创建一个唯一的 Revision。Configuration 可以认为是版本控制器,负责管理多个Revision版本

Knative: 基于流量的灰度发布和自动弹性实践

Route

Route 主要负责 Knative 的流量管理,控制流量分发到不同到Revision, 并且支持按照百分比进行流量分发。这里我们可以通过在Traffic中对不同的Revison 设置不同对流量比例即可控制流量分发。

Knative: 基于流量的灰度发布和自动弹性实践

Revision

Revision. 一个Revision可以认为是一个Configuration的快照。通过Revision可以实现历史版本追踪,以及灰度发布的过程中进行回滚等功能。

Knative: 基于流量的灰度发布和自动弹性实践



基于流量的灰度发布

那么接下来我们看一下基于流量的灰度发布我们可以怎样做。

假设一开始我们创建了V1版本的Revison, 这时候如果有新的版本变更,那么我们只需要更新Service 中的Configuration, 就会创建出V2版本,然后我们可以通过Route对V1、V2设置不同对流量比例,这里v1是70%, v2是30%, 那么流量就会分别按照7:3的比例分发到这两个版本上。一旦新到V2版本验证没有问题,那么我们接下来就可以通过调整比例继续灰度,直到新版本V2 100%。在这个灰度到过程中,一旦发现新版本有异常,可以通过调整比例进行回滚操作。

除此以外,我们可以在Route到Traffic 中对Revison打Tag, 打完Tag的Revison, 我们可以直接通过Url进行单独的版本测试,对这个版本对调试不会影响正常对流量访问。

Knative: 基于流量的灰度发布和自动弹性实践

自动弹性

接下来我们聊一下自动弹性。作为 Severless Framework 就离不开按需分配资源的能力,Knative 提供了基于流量的自动扩缩容KPA能力,以及基于CPU和Memory的HPA弹性能力,除此以外,Knative 提供了弹性的扩展能力,我们可以基于不同的指标自定义弹性功能。

  • Knative Pod 自动扩缩容 (KPA)
  • Pod 水平自动扩缩容 (HPA)
  • 支持定时 + HPA的自动扩缩容策略
  • 事件网关(基于流量请求的精准弹性)
  • 扩展自定义扩缩容插件


KPA

Knative Serving 中默认使用KPA。

Knative: 基于流量的灰度发布和自动弹性实践

上图展示了 Knative Autoscaler 的工作机制,Route 负责接入流量,Autoscaler 负责做弹性伸缩。当没有业务请求的时候会缩容到零,缩容到零后 Route 进来的请求会转到 Activator 上。当第一个请求进来之后 Activator 会保持住 http 链接,然后通知 Autoscaler 去做扩容。Autoscaler 把第一个 pod 扩容完成以后 Activator 就把流量转发到 Pod ,从而做到了缩容到零也不会损失流量的目的。

当后续有流量进来之后,流量会直接Route到Pod上,这时候Autoscaler会直接采集Pod中的指标,根据指标进行1-N的扩缩容操作。


HPA

基于CPU、Memory的自动扩缩容-HPA

Knative: 基于流量的灰度发布和自动弹性实践


利用 Horizontal Pod Autoscaling,kubernetes 能够根据监测到的 CPU 、Memory利用率 通过 修改deployment 中 pod 的数量,进行扩容。在Knative 中集成了HPA的能力,通过autoscaling class可以选择HPA的能力。


定时与HPA融合

支持定时+HPA的自动扩缩容:

  • 提前规划容量进行资源预热
  • 与CPU、Memory弹性指标相结合


Knative: 基于流量的灰度发布和自动弹性实践

事件网关

基于流量请求的精准弹性:

  • 基于请求数自动弹性
  • 支持1对1任务分发

Knative: 基于流量的灰度发布和自动弹性实践

自定义扩缩容插件

Knative 中提供了灵活的扩缩容插件机制, 开发者可以通过设置`autoscaling.knative.dev/class`来指定所使用的具体插件。自定义扩缩容插件只需要实现下面两个关键能力即可:

  • 采集指标
  • 调整Pod实例数

Knative: 基于流量的灰度发布和自动弹性实践

示例演示

这里我们分别演示一下基于流量灰度发布和自动扩缩容的功能。

灰度流量发布

我们以 helloworld 的服务为例,分别执行如下操作:

  • 创建 helloworld 服务
  • 升级服务
  • 灰度发布

创建 helloworld 服务

  1. 登录容器服务管理控制台
  2. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  3. 在集群管理页左侧导航栏中,选择应用 > Knative
  4. 服务管理页签右上角,单击创建服务
  5. 设置集群命名空间服务名称,选择所要使用的镜像和镜像版本等配置信息。这里我们创建 helloworld-go 服务。

Knative: 基于流量的灰度发布和自动弹性实践

  1. 单击创建创建完成后,您可以在服务管理页签的列表中,点击helloworld-go看到新创建的服务。


Knative: 基于流量的灰度发布和自动弹性实践

此时我们访问服务:

$ curl -H "host: helloworld-go.default.example.com" http://39.106.199.35
Hello World!

升级服务

点击【创建修订版本】,这里我们设置新版本环境变量为:TARGET=Knative

Knative: 基于流量的灰度发布和自动弹性实践

点击下一步,我们可以设置新版本的流量比例,这里我们设置新版本流量为0,点击创建。

Knative: 基于流量的灰度发布和自动弹性实践

在服务详情中,可以看到新的版本已经创建完成,如图:

Knative: 基于流量的灰度发布和自动弹性实践

由于新版本流量为0,所以当前访问helloworld-go 服务的话,还是请求到原来的版本中。

此时我们访问服务:

$ curl -H "host: helloworld-go.default.example.com" http://39.106.199.35
Hello World!

灰度发布

接下来我们开始灰度流量发布,点击【设置流量比例】,将新、旧版本各设置为50%。

Knative: 基于流量的灰度发布和自动弹性实践

在服务详情中,可以看到新、旧的版本已经创建完成,如图:

Knative: 基于流量的灰度发布和自动弹性实践

由于新、旧版本流量各为50%,所以当前访问helloworld-go 服务的话,基本是50%进行流量分配。

此时我们访问服务:

Knative: 基于流量的灰度发布和自动弹性实践

我们通过调整流量比例继续灰度,直到新版本100%,完成灰度发布。

Knative: 基于流量的灰度发布和自动弹性实践

在这个过程中,如何发现新版本有问题,可以随时通过调整流量比例的方式进行回滚操作。

基于流量的自动扩缩容

我们模拟并发场景,并发50,持续30s。使用hey工具(hey压测工具的详细介绍请参见hey

hey -z 30s -c 50   -host "helloworld-go.default.example.com"   "http://39.106.199.35"

结果如下:

$ kubectl get po
helloworld-go-g2qfr-deployment-5f557f97cc-76mjb                   2/2     Running   0          38s
helloworld-go-g2qfr-deployment-5f557f97cc-7j797                   2/2     Running   0          34s
helloworld-go-g2qfr-deployment-5f557f97cc-fh4nl                   2/2     Running   0          2m4s
helloworld-go-g2qfr-deployment-5f557f97cc-kdqjx                   2/2     Running   0          38s
helloworld-go-g2qfr-deployment-5f557f97cc-kmxsz                   2/2     Running   0          26s
helloworld-go-g2qfr-deployment-5f557f97cc-p24s8                   2/2     Running   0          2m48s
helloworld-go-g2qfr-deployment-5f557f97cc-wq89q                   2/2     Running   0          36s
helloworld-go-g2qfr-deployment-5f557f97cc-zfhf6                   2/2     Running   0          38s
helloworld-go-g2qfr-deployment-5f557f97cc-xvdf6                   2/2     Running   0          38s
helloworld-go-g2qfr-deployment-5f557f97cc-aeaf8                   2/2     Running   0          37s
helloworld-go-g2qfr-deployment-5f557f97cc-dfdsa                   2/2     Running   0          46s

当然,我们也可以在日志服务中配置查看Pod扩缩容趋势

Knative: 基于流量的灰度发布和自动弹性实践


总结

本文我们介绍了基于流量的灰度发布以及自动弹性策略,并分别进行了示例演示。欢迎有兴趣同学关注 Knative 钉钉交流群。

Knative: 基于流量的灰度发布和自动弹性实践


上一篇:赠票|ATEC倒计时12天:解密小猪短租是如何实现智能入住的?


下一篇:「镁客·请讲」天宝陈朝晖:AI 的准确译法不是人工智能,而是机器智能