概述
Knative Serving定义了一些kubernetes的CRD对象,这些对象用于管理和定义serverless工作负载(比如函数)在集群上的行为。对象包括:
- Service:一般是我们自定义的函数(function),主要的作用是控制其他CRD对象的创建,从而保证你的Service都有一个Configuration、Route和Revison。
- Revision:每一次的部署都可以看作一次Revision,也就是说,knative会记录你每一次提交或配置的函数版本。Revision是不可变的对象,并且是会长期保留的;
- Route:作用是将流量分到一个或多个Revison上去;可以通过多种方式管理流量,包括部分流量和命名路由。。
- Configuration:维护部署时所需要的状态,遵循12因素,即代码与配置分离,修改一次Configuration就相当于创建了一个新的Revision。
其关系图如下:
流量管理
创建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-world
、hello-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/
发表评论