页面加载中...

knative-serving 流量管理

| 云原生 | 0 条评论 | 130浏览

概述

Knative Serving定义了一些kubernetes的CRD对象,这些对象用于管理和定义serverless工作负载(比如函数)在集群上的行为。对象包括:

  • Service:一般是我们自定义的函数(function),主要的作用是控制其他CRD对象的创建,从而保证你的Service都有一个Configuration、Route和Revison。
  • Revision:每一次的部署都可以看作一次Revision,也就是说,knative会记录你每一次提交或配置的函数版本。Revision是不可变的对象,并且是会长期保留的;
  • Route:作用是将流量分到一个或多个Revison上去;可以通过多种方式管理流量,包括部分流量和命名路由。。
  • Configuration:维护部署时所需要的状态,遵循12因素,即代码与配置分离,修改一次Configuration就相当于创建了一个新的Revision。

其关系图如下:

image-20220314164123568

流量管理

创建Service

先来个knative serving的hello world。创建一个Service:

k apply -f hello.yaml

(k = kubectl ,这里简写了,下同)

hello.yaml内容:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: hello #Service的名字就交hello
spec:
  template:
    metadata:
      name: hello-world # revision的名字
    spec:
      containers:
        - image: abreaking/helloworld-java
          ports:
            - containerPort: 8080
          env:
            - name: TARGET
              value: "world"

此时我们通过如下命令来查看service的内容:

$ k get ksvc
NAME    URL                                           LATESTCREATED   LATESTREADY   READY   REASON
hello   http://hello.default.10.105.32.166.sslip.io   hello-world     hello-world   True   

此时看到了一个url,直接进行调用:

$ curl http://hello.default.10.105.32.166.sslip.io
Hello world!

说明Service创建没问题。

此时再看看revision、route、Configuration等内容:

  • 查看revision:

    这里使用了kn命令,也就是Knative官方提供的客户端工具,建议先提前[安装kn](Installing kn - Knative),方便操作。

    $ kn revision list
    NAME          SERVICE   TRAFFIC   TAGS   GENERATION   AGE     CONDITIONS   READY   REASON
    hello-world   hello     100%             1            4m16s   3 OK / 4     True 
    

    可以看见,hello只有一个revision,当然流量(TRAFFIC)百分比是100%。

  • 查看configuration

    $ k get configuration
    NAME    LATESTCREATED   LATESTREADY   READY   REASON
    hello   hello-world     hello-world   True 
    

    可以看见,hello的最近的一个版本叫做hello-world

  • 查看route

    $ k get route
    NAME    URL                                           READY   REASON
    hello   http://hello.default.10.105.32.166.sslip.io   True 
    

    可以看见,当前只有一个路由,叫做hello.

流量分割

接下来为hello创建另一个revision,并指定分流的策略。

修改hello.yaml,内容如下:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: hello
spec:
  template:
    metadata:
      name: hello-abreaking #创建另一个revision
    spec:
      containers:
        - image: abreaking/helloworld-java
          imagePullPolicy: Never
          ports:
            - containerPort: 8080
          env:
            - name: TARGET
              value: "abreaking" # 修改环境变量值
  traffic:
  - latestRevision: true # 指定当前revision是最新版本
    percent: 50 # 流量百分比
  - revisionName: hello-world #指定上一个revision的流量百分比
    percent: 50              

创建新的revision:

$ k apply -f hello.yaml 
service.serving.knative.dev/hello configured

此时再查看revision:

$ kn revision list
NAME              SERVICE   TRAFFIC   TAGS   GENERATION   AGE     CONDITIONS   READY   REASON
hello-abreaking   hello     50%              2            5m24s   3 OK / 4     True    
hello-world       hello     50%              1            29m     3 OK / 4     True 

可以发现,此时hello-abreaking和之前创建的hello-world流量(TRAFFIC)都是50%。

再进行服务调用:

$ curl http://hello.default.10.105.32.166.sslip.io
Hello world!
$ curl http://hello.default.10.105.32.166.sslip.io
Hello abreaking!

可见流量确实分到了这两个revison上去了。

指定标签

如果需要显示指定某个revision,knative支持配置tag属性。

修改hello.yaml内容:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: hello
spec:
  template:
    metadata:
      name: hello-abreaking 
    ... 同上
  traffic:
  - latestRevision: true 
    percent: 50
  - revisionName: hello-world 
    percent: 50  
    tag: worldtag # 为hello-world 的revison指定一个tag

使用tag属性后,knative会创建特定流量目标的地址。 可以通过staging-<route name>.<namespace>.<domain> 这种方式访问指定的revision。

$ k apply -f hello.yaml

此时再查看revision:

$ kn revision list
NAME              SERVICE   TRAFFIC   TAGS       GENERATION   AGE   CONDITIONS   READY   REASON
hello-abreaking   hello     50%                  2            14m   3 OK / 4     True    
hello-world       hello     50%       worldtag   1            39m   3 OK / 4     True    

可以发现,hello-world的TAGS多了一个worldtag

通过如下命令来显示调用hello-world的revision:

$ curl http://worldtag-hello.default.10.105.32.166.sslip.io
Hello world!

路由配置

前面我们通过k get route查看了Service 的路由,只有一个hello,此时我们可以根据需求创建不同的Route(路由)。

前面我们已经创建了两个revision,分别是hello-worldhello-abreaking,此时我们再为这两个revision创建一个新的Route,route.yaml内容如下:

apiVersion: serving.knative.dev/v1
kind: Route
metadata:
  name: myroute # 自定义路由的名称
  namespace: default
spec:
  traffic:
    - revisionName: hello-world 
      percent: 100 
      tag: v1
    - revisionName: hello-abreaking 
      percent: 0 
      tag: v2 

通过如下命令:

$ k apply -f route.yaml 
route.serving.knative.dev/myroute created

再查看Route:

$ k get route
NAME      URL                                             READY   REASON
hello     http://hello.default.10.105.32.166.sslip.io     True    
myroute   http://myroute.default.10.105.32.166.sslip.io   True 

此时已经新创建了一个路由myroute,再访问URL:

$ curl http://myroute.default.10.105.32.166.sslip.io
Hello world!

不管调用多少次,都是返回Hello world!,可见新的路由确实把流量全部路由到了hello-world revision上了。

同样我们可以根据指定的tag来访问对应不同的revision:

$ curl http://v1-myroute.default.10.105.32.166.sslip.io
Hello world!
$ curl http://v2-myroute.default.10.105.32.166.sslip.io
Hello abreaking!

使用knative客户端工具

上述流量分割配置都是在yaml里配置。如果需要动态变更分流策略,那么建议使用knative提供的客户端工具 kn来进行管理流量。

命令的格式一般是:

kn service update <service-name> --traffic <revision-name>=<percent>

比如修改将10%的流量分流到hello-world,90%分流到hello-abreaking:

$ kn service update hello --traffic hello-world=10 --traffic hello-abreaking=90
Updating Service 'hello' in namespace 'default':

  0.033s The Route is still working to reflect the latest desired specification.
  0.135s Ingress has not yet been reconciled.
  0.716s Waiting for load balancer to be ready
  0.861s Ready to serve.

Service 'hello' with latest revision 'hello-abreaking' (unchanged) is available at URL:
http://hello.default.10.105.32.166.sslip.io

此时再确认下修改的结果:

$ kn revision list
NAME              SERVICE   TRAFFIC   TAGS       GENERATION   AGE   CONDITIONS   READY   REASON
hello-abreaking   hello     90%                  2            40m   3 OK / 4     True    
hello-world       hello     10%       worldtag   1            65m   3 OK / 4     True 

也支持修改tag,比如为hello-abreaking打上tag :

$ kn service update hello --tag hello-abreaking=abreakingtag

参考资料

Traffic management - Knative:https://knative.dev/docs/serving/traffic-management/

发表评论

最新评论

    来第一个评论吧!