knative serving 流量管理

发布时间 2023-10-08 16:38:37作者: 小吉猫

创建客户端

# kubectl run client --image=ikubernetes/admin-box -it --rm --restart=Never --command -n knative-demo -- /bin/bash
root@client /# 

创建应用

hello-world-v1.yaml

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: helloworld-go
  namespace: knative-demo
spec:
  template:
    spec:
      containers:
        - image: ghcr.dockerproxy.com/knative/helloworld-go:latest
          env:
            - name: TARGET
              value: "Go Sample v1"

hello-world-v2.yaml

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: helloworld-go
  namespace: knative-demo
spec:
  template:
    spec:
      containers:
        - image: ghcr.dockerproxy.com/knative/helloworld-go:latest
          env:
            - name: TARGET
              value: "Go Sample v2"

hello-world-v3.yaml

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: helloworld-go
  namespace: knative-demo
spec:
  template:
    spec:
      containers:
        - image: ghcr.dockerproxy.com/knative/helloworld-go:latest
          env:
            - name: TARGET
              value: "Go Sample v3"

创建应用

# kubectl apply -f hello-word-v1.yaml 
# kubectl apply -f hello-word-v2.yaml 
# kubectl apply -f hello-word-v3.yaml 
service.serving.knative.dev/helloworld-go created
service.serving.knative.dev/helloworld-go configured
service.serving.knative.dev/helloworld-go configured

查看应用资源

# kubectl get svc,rt,vs -n knative-demo
NAME                                  TYPE           CLUSTER-IP       EXTERNAL-IP                                        PORT(S)                                              AGE
service/helloworld-go                 ExternalName   <none>           knative-local-gateway.istio-system.svc.wgs.local   80/TCP                                               14s
service/helloworld-go-00001           ClusterIP      10.100.212.167   <none>                                             80/TCP,443/TCP                                       17s
service/helloworld-go-00001-private   ClusterIP      10.100.63.173    <none>                                             80/TCP,443/TCP,9090/TCP,9091/TCP,8022/TCP,8012/TCP   17s
service/helloworld-go-00002           ClusterIP      10.100.105.107   <none>                                             80/TCP,443/TCP                                       13s
service/helloworld-go-00002-private   ClusterIP      10.100.93.61     <none>                                             80/TCP,443/TCP,9090/TCP,9091/TCP,8022/TCP,8012/TCP   13s
service/helloworld-go-00003           ClusterIP      10.100.170.32    <none>                                             80/TCP,443/TCP                                       10s
service/helloworld-go-00003-private   ClusterIP      10.100.157.99    <none>                                             80/TCP,443/TCP,9090/TCP,9091/TCP,8022/TCP,8012/TCP   10s

NAME                                      URL                                               READY   REASON
route.serving.knative.dev/helloworld-go   http://helloworld-go.knative-demo.svc.wgs.local   True    

NAME                                                               GATEWAYS                                      HOSTS                                                                                                        AGE
virtualservice.networking.istio.io/helloworld-go-ingress           ["knative-serving/knative-local-gateway"]     ["helloworld-go.knative-demo","helloworld-go.knative-demo.svc","helloworld-go.knative-demo.svc.wgs.local"]   14s
virtualservice.networking.istio.io/helloworld-go-mesh              ["mesh"]                                      ["helloworld-go.knative-demo","helloworld-go.knative-demo.svc","helloworld-go.knative-demo.svc.wgs.local"]   14s
virtualservice.networking.istio.io/helloworld-go.wgs.com-ingress   ["knative-serving/knative-ingress-gateway"]   ["helloworld-go.wgs.com"]                                                                                    22h
virtualservice.networking.istio.io/helloworld.wgs.com-ingress      ["knative-serving/knative-ingress-gateway"]   ["helloworld.wgs.com"]                                                                                       22h

查看 Revision

# kubectl get revision -n knative-demo
NAME                  CONFIG NAME     K8S SERVICE NAME   GENERATION   READY   REASON   ACTUAL REPLICAS   DESIRED REPLICAS
helloworld-go-00001   helloworld-go                      1            True             0                 0
helloworld-go-00002   helloworld-go                      2            True             0                 0
helloworld-go-00003   helloworld-go                      3            True             1                 1

查看流量规则

默认流量路由到最新的Revision。
# kn route describe  helloworld-go -n knative-demo
Name:       helloworld-go
Namespace:  knative-demo
Age:        1m
URL:        http://helloworld-go.knative-demo.svc.wgs.local
Service:    helloworld-go

Traffic Targets:  
  100%  @latest (helloworld-go-00003)

Conditions:  
  OK TYPE                      AGE REASON
  ++ Ready                      1m 
  ++ AllTrafficAssigned         1m 
  ++ CertificateProvisioned     1m TLSNotEnabled
  ++ IngressReady               1m 

访问测试

root@client /# curl helloworld-go.knative-demo.svc.wgs.local
Hello Go Sample v3!

定义流量策略

hello-world-v3.yaml

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: helloworld-go
  namespace: knative-demo
spec:
  template:
    spec:
      containers:
        - image: ghcr.dockerproxy.com/knative/helloworld-go:latest
          env:
            - name: TARGET
              value: "Go Sample v3"
  traffic:
  - percent: 0
    revisionName: helloworld-go-00001
    tag: staging
  - percent: 40
    revisionName: helloworld-go-00002
  - percent: 60
    revisionName: helloworld-go-00003

 

更新资源

# kubectl apply -f hello-word-v3.yaml 
service.serving.knative.dev/helloworld-go configured

查看流量规则

# kn route describe  helloworld-go -n knative-demo
Name:       helloworld-go
Namespace:  knative-demo
Age:        30m
URL:        http://helloworld-go.knative-demo.svc.wgs.local
Service:    helloworld-go

Traffic Targets:  
    0%  helloworld-go-00001 #staging
        URL:  http://staging-helloworld-go.knative-demo.svc.wgs.local
   40%  helloworld-go-00002
   60%  helloworld-go-00003

Conditions:  
  OK TYPE                      AGE REASON
  ++ Ready                      1m 
  ++ AllTrafficAssigned        30m 
  ++ CertificateProvisioned    30m TLSNotEnabled
  ++ IngressReady               1m 

访问测试

root@client /# while true;do sleep 0.5; curl helloworld-go.knative-demo.svc.wgs.local;done
Hello Go Sample v3!
Hello Go Sample v2!
Hello Go Sample v2!
Hello Go Sample v2!
Hello Go Sample v3!
Hello Go Sample v2!
Hello Go Sample v3!
Hello Go Sample v2!
Hello Go Sample v3!
Hello Go Sample v2!
Hello Go Sample v3!
Hello Go Sample v3!
root@client /# curl staging-helloworld-go.knative-demo.svc.wgs.local
Hello Go Sample v1!

使用 Knative CLI管理路由和流量

kn service update <service-name> --traffic <revision-name>=<percent>
<service-name>   是为其配置流量路由的 Knative 服务的名称。
<revision-name>  是要配置为接收流量百分比的修订版的名称。
<percent>        是要发送到指定<revision-name>的修订版本的流量百分比。

将流量完全发送至指定的某个Revision

kn service update helloworld-go --trafic helloworld-go-00003=100 -n knative-demo

将流量切分至不同的Revision

kn service update helloworld-go --traffic helloworld-go-00003=90 --traffic helloworld-go-00002=10 -n knative-demo

将流量完全发送至最新就绪版本的Revision

kn service update helloworld-go --traffic '@latest'=100 -n knative-demo

路由标签

设置标签

kn service update helloworld-go --tag helloworld-go-00002=green --tag @latest=blue -n knative-demo
Updating Service 'helloworld-go' in namespace 'knative-demo':

  0.051s The Route is still working to reflect the latest desired specification.
  0.177s Ingress has not yet been reconciled.
  0.248s Ready to serve.

Service 'helloworld-go' with latest revision 'helloworld-go-00003' (unchanged) is available at URL:
http://helloworld-go.knative-demo.svc.wgs.local

查看标签

# kn route describe  helloworld-go -n knative-demo
Name:       helloworld-go
Namespace:  knative-demo
Age:        55m
URL:        http://helloworld-go.knative-demo.svc.wgs.local
Service:    helloworld-go

Traffic Targets:  
    0%  helloworld-go-00001 #staging
        URL:  http://staging-helloworld-go.knative-demo.svc.wgs.local
   40%  helloworld-go-00002 #green
        URL:  http://green-helloworld-go.knative-demo.svc.wgs.local
   60%  helloworld-go-00003
    0%  @latest (helloworld-go-00003) #blue
        URL:  http://blue-helloworld-go.knative-demo.svc.wgs.local

Conditions:  
  OK TYPE                      AGE REASON
  ++ Ready                      9s 
  ++ AllTrafficAssigned        55m 
  ++ CertificateProvisioned    55m TLSNotEnabled
  ++ IngressReady               9s 

删除标签

kn service update helloworld-go --untag blue

将流量按照标签切分至不同的Revision

kn service update helloworld-go --traffic blue=100 --traffic green=0 -n knative-demo
Updating Service 'helloworld-go' in namespace 'knative-demo':

  0.046s The Route is still working to reflect the latest desired specification.
  0.090s Ingress has not yet been reconciled.
  0.198s Ready to serve.

Service 'helloworld-go' with latest revision 'helloworld-go-00003' (unchanged) is available at URL:
http://helloworld-go.knative-demo.svc.wgs.local

查看流量规则

# kn route describe  helloworld-go -n knative-demo
Name:       helloworld-go
Namespace:  knative-demo
Age:        59m
URL:        http://helloworld-go.knative-demo.svc.wgs.local
Service:    helloworld-go

Traffic Targets:  
    0%  helloworld-go-00001 #staging
        URL:  http://staging-helloworld-go.knative-demo.svc.wgs.local
    0%  helloworld-go-00002 #green
        URL:  http://green-helloworld-go.knative-demo.svc.wgs.local
  100%  @latest (helloworld-go-00003) #blue
        URL:  http://blue-helloworld-go.knative-demo.svc.wgs.local

Conditions:  
  OK TYPE                      AGE REASON
  ++ Ready                      6s 
  ++ AllTrafficAssigned        59m 
  ++ CertificateProvisioned    59m TLSNotEnabled
  ++ IngressReady               6s 

流量逐步迁移

ConfigurationName也可以作为路由项中的流量目标,意味着相关的流量部分由该Configurate下最新就绪的Revision承载。在新的Revision就绪之后,Configuration Target上的所有流量会立即转移至该Revision。
这可能会使 QP 或 Activator 处的请求队列过长,并导致请求过期或被 QP 拒绝。
Knative 提供了一个rollout-duration参数,可用于将流量逐渐转移到最新的 Revision,防止请求排队或被拒绝。新的Revision上线后,它会先从Configuration Target迁出1%的流量,随后再等分迁出余下的流量部分。
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: helloworld-go
  namespace: knative-demo
  annotations:
    serving.knative.dev/rollout-duration: "380s"  # 指定流量迁移过程的时长

参考文档

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